二进制搜索

时间:2009-10-17 21:07:01

标签: algorithm search binary-search preconditions

所以,我想更多地了解二进制搜索,因为我真的不明白。二进制搜索需要一个数组排序的前提条件。我做对了吗?看起来一个方法应该检查这个前提条件并在不满足时抛出异常。但是,为什么检查前提条件是个坏主意?

6 个答案:

答案 0 :(得分:8)

这是一个坏主意,因为检查数据的排序需要n个步骤。整个搜索大约是log(n)个步骤 如果您要检查,您也可以进行线性搜索。

答案 1 :(得分:7)

二进制搜索的重点在于,由于数据已经排序,您可以快速找到所需的信息。

拿电话簿,按姓氏排序。

您如何在电话簿中找到某人?您将其打开到一个您认为接近您想要的页面,然后开始翻页。

但是你不是每次都翻页,如果你错过了很多,你翻了一堆页,然后终于开始一次翻页,直到最后你开始看一页。

这是二进制搜索的功能。由于数据是经过排序的,因此它知道它可以跳过很多并进行另一次查看,并且它将专注于您想要的信息。

二进制搜索对每两倍的项目进行1次比较。因此,1024元素集合最多需要大约10次比较来查找您的信息,或者至少知道它不存在。

如果您在运行实际二进制搜索之前执行了完整的运行以检查数据是否已排序,那么您也可以只扫描信息。完全运行+二进制搜索将需要N + log2 N个操作,因此对于1024个元素,它将需要大约1034个比较,而对信息的简单扫描平均需要一半,即512。

因此,如果您无法保证数据已排序,则不应使用二进制搜索,因为它将通过简单扫描表现出色。


编辑:我会这样说,你可以添加一个仅调试的代码步骤来验证这一点,以捕获应该为二进制搜索准备数据的代码中的错误,但是知道由于我上面所写的,这将使总运行时间更长,因此根据您对此检查的要求,您可能会或可能不想添加它。但它不应出现在发布代码中。

答案 2 :(得分:3)

是的,二进制搜索涉及0(log n)步骤并且验证整个序列被排序涉及0(n)步骤。从我的观点来看,最好在DEBUG模式下验证它,而不是在RELEASE期间验证它。

答案 3 :(得分:1)

Binary search假设输入数据已排序。所以在这里你是对的。

现在通常检查数据是否在某个时间排序。因此,在每次搜索之前执行此操作会使搜索效率低下。

更多细节。

假设'n'是您的数据量。

在最坏的情况下,

Binary searching需要O(log(n))操作来查找元素。确保对数据进行排序需要O(n)次操作。

因此,如果我们每次检查前提条件非常大n,我们将开始花大部分时间检查前提条件,而不是进行实际搜索。

当你看到这样的效果时,并不难说。我只计算了你在预先检查和实际搜索上花费的时间

  • 对于1个元素,您不会花时间搜索。
  • 对于2个元素,您将50%用于搜索。
  • 对于5个元素,您在搜索上花费了46%
  • 对于20个元素,你花22%的时间进行搜索。
  • 对于100个元素,您将花费7%进行搜索。

等等。在每种情况下,准时休息是花在预处理检查上。

答案 4 :(得分:0)

除了其他人所说的关于运行时间的内容(O(n)检查所有项目,而O(log(n))运行二进制搜索。)

我认为你误解了前提条件的想法。前提条件和后置条件是合同。如果您的前提条件为真,并且您运行算法,那么您的后置条件将为真。如果你的先决条件是假的,那么你就不能保证发布条件。

基本上,二进制搜索说:如果您给我的数据已经排序,那么我可以通过执行大约log(n)检查来告诉您特定数据的位置,或者它是否存在。如果数据没有排序,我不保证我的答案。

如果您的算法,将您从前置条件带到后置条件的工作。在这种情况下,二进制搜索。

答案 5 :(得分:0)

原始问题预先假定您正在对数据集合使用二进制搜索。情况并非总是如此。很多时候你只是想在某个时间间隔内计算一个数字。

假设您正在尝试计算风扇的最佳速度设置。由于某种原因,您无法找到封闭的表格表达式,因此您可以在不同的速度设置下模拟气流。

假设风扇可以以0RPM到5000RPM的任何速度运行,您实际上不必生成可能的速度列表。您只需在二分查找的每一步找到先前最小值和最大值的平均值。