二分查找法又名折半查找法,应用很广泛,因为
1、其原理简单
2、并且效率很高,属于基于比较的查找法中时间复杂度最低的,时间复杂度为O(log n)
缺点是是查找的对像必须是有序的。
二分查找法描述如下:
A为一个含有n个数的数组,按由小到大排列,欲将m插入该数组中,查找该位置。
int BiSearch(int* Array, int n, int m)
{
int pos1=0;
int pos2=n;
while(pos2 > pos1)
{
if(Array[(pos1+pos2)/2] > m)
{
pos2 = (pos1 + pos2)/2;
}
else
{
pos1 = (pos1 + pos2)/2 + 1;
}
}
return pos1;
}
返回值即m插入的位置。
时间复杂度:
理想情况,最坏情况,平均情况下其时间复杂度均为 O(log n),证明如下
设长度为n的数组共需查找S(n)次,同时令2^(k-1) < n <= 2^k 则有
S(n) = S(2^k)
显然,;S(2^k)只需比S(2^(k-1))多比较一次即可,于是
S(n)=1+S(2^(k-1))
=1+1+S(2^(k-2))
=...
=k
k = ln(n) / ln(2) ~ ln(n) ~ log(n),简记为log n
上面的查找法还可以这么实现
int BiSearch(int* Array, int n, int m)
{
int pos1=0;
int pos2=n;
while(pos2 > pos1)
{
if(Array[(pos1+pos2)/2] == m)
{
pos1 = pos2 = (pos1+pos2)/2;
}
else if(Array[(pos1+pos2)/2] > m)
{
pos2 = (pos1 + pos2)/2;
}
else
{
pos1 = (pos1 + pos2)/2 + 1;
}
}
return pos1;
}
这种方法的时间复杂度是不定的,最理想情况下为O(1),最坏情况和平均情况下为O(log n)