我听别人说,由于二分搜索将搜索所需的输入减半,因此它是O(log n)算法。由于我不是数学背景,我无法理解它。有人能详细解释一下吗?这与对数级数有关吗?
我听别人说,由于二分搜索将搜索所需的输入减半,因此它是O(log n)算法。由于我不是数学背景,我无法理解它。有人能详细解释一下吗?这与对数级数有关吗?
这里有一种更数学的方式来理解,虽然并不复杂。在我看来比非正式的方式更清晰:
问题是,你可以将N除以2多少次直到得到1?这基本上意味着进行二进制搜索(减半),直到找到为止。用公式表示如下:
1 = N / 2x
乘以2x:
2x = N
现在做log2:
log2(2x) = log2 N
x * log2(2) = log2 N
x * 1 = log2 N
这意味着你可以将log N个数字分割成若干段,直到将所有数字都分割开为止。这意味着您必须对log N进行“二进制搜索步骤”,直到找到您的元素。
T(n)=T(n/2)+1
T(n/2)= T(n/4)+1+1
将T(n/2)的值代入上式,得到T(n)=T(n/4)+1+1......+1+1
=T(2^k/2^k)+1+1....+1(一直加到k次)
=T(1)+k
由于我们取了2^k=n,因此k=log n
因此,时间复杂度为O(log n)
它不仅减少搜索时间,而且减少的是对数。请想一想:如果你在一个有128个条目的表中进行线性搜索,并且需要寻找你的值,平均需要搜索大约64个条目,这就是n/2或线性时间。采用二分搜索法,每次迭代可以消除1/2的可能条目,最多只需要7次比较就可以找到你的值(以2为底的128的对数是7,即2的7次方等于128)。这就是二分搜索的威力。
假设二分查找的迭代在经过k次后终止。 每次迭代,数组都会被对半分割。因此,任何一次迭代时数组的长度是n。 在第一次迭代中,
Length of array = n
Length of array = n⁄2
在第3次迭代中,
Length of array = (n⁄2)⁄2 = n⁄22
Length of array = n⁄2k
Length of array = n⁄2k = 1
=> n = 2k
对两侧应用对数函数:
=> log2 (n) = log2 (2k)
=> log2 (n) = k log2 (2)
As (loga (a) = 1)
As (loga (a) = 1)
k = log2 (n)
log2 (n)
k
后,数组长度 = n⁄2^(k-1)
。 - volperossa这里是维基百科的条目。
如果你看简单的迭代方法,你只需要消除一半的要搜索的元素,直到找到所需的元素。
我们来解释一下如何得出公式。
假设最初有N个元素,然后你先试着用⌊N/2⌋进行搜索。其中N是下限和上限的总和。第一次N的值将等于(L + H),其中L是要搜索的列表的第一个索引(0),而H是最后一个索引。如果你很幸运,在中间找到了要查找的元素[例如,你在列表{16, 17, 18, 19, 20}中搜索18,那么你计算⌊(0+4)/2⌋ = 2,其中0是下限(数组的第一个元素的索引L),4是上限(数组的最后一个元素的索引H)。在上面的例子中,L=0,H=4。现在2就是你要查找的元素18的索引。太棒了!你找到它了。
如果情况是不同的数组{15,16,17,18,19},但你仍在搜索18,那么你就没那么幸运了。你会执行第一个N/2(即⌊(0+4)/2⌋=2),然后意识到索引2处的元素17不是你要查找的那个数。现在你知道在下一次迭代搜索中,你至少不必再寻找数组的一半。你的搜索工作减少了一半。因此,每次尝试查找以前未能找到的元素时,你都不会再搜索之前搜索过的一半元素列表。
所以最坏的情况是
[N]/2 + [(N/2)]/2 + [((N/2)/2)]/2.....
即:
N/21 + N/22 + N/23 +..... + N/2x …..
直到...你完成搜索,在那里你要查找的元素位于列表的末尾。
这表明最坏的情况是当你达到N/2x时,其中x是2x=N的值。
在其他情况下,N/2x,其中x是2x<N的值。x的最小值可以是1,这是最好的情况。
现在,最坏的情况是数值为2x=N:
=> log2(2x) = log2(N)
=> x * log2(2) = log2(N)
=> x * 1 = log2(N)
=> 更正式地说,⌊log2(N)+1⌋
在二分查找中,需要进行的最大比较次数是⌊log₂(n) + 1⌋。平均情况下,需要进行约log₂(n) - 1次比较。以下链接提供更多信息:
T(N) = T(N/2) + 1
意思是:T(N)等于T(N/2)加1。T(N) = T(N/2) + 1 = (T(N/4) + 1)+ 1
意思是:T(N)等于T(N/2)加1,而T(N/2)又等于T(N/4)加1,所以T(N)等于T(N/4)加2。...
T(N) = T(N/N) + (1 + 1 + 1 +... + 1) = 1 + logN (以2为底的对数) = 1 + logN
因此,二分查找的时间复杂度为O(logN)