今天训练做题讲了二分查找,我虽然学过数据结构,但是做的并不好,因为都忘得差不多了。
今天再复习一下。
- 折半查找的缺点
只适用于有序表,且限于顺序存储结构。(对线性链表无法进行查找) - 代码 (左闭右开)
int binary_search(int *p, int left,int right,int key)
{
int low ,high,mid;
low = left;
high = right+1;
while(low<high)
{
mid = (low+high)/2;
if(p[mid] == key)
{
return mid ; //返回所在下标
}
else if(p[mid] < key)
{
low= mid+1;
}
else if(p[mid] >key)
{
high= mid; //因为是左闭右开区间
}
}
return -1;
}
一是区间边界问题。
注意保持区间的稳定性,如果开始是左开右必就要一直保持这种状态,否则可能会发生遗漏。
二是注意mid 溢出问题
mid = (left+right)/2;
mid = (left- right)/2 + right ;
当两个数都非常大且互相接近时,两个大数的相加可能会导致溢出,变成一个负数。
这时后面这种写法就可以避免溢出。
三是常数步前进问题
假设 s = [1,2];
key =0;
当 left = 0 right =1 时 => mid= (high+low)/2 = 0
如果此时 high= mid; low = mid ; 则会陷入一直为0 的死循环
如果此时 high = mid;low = mid+1; 则 high= 0 ;跳出循环
如果此时 high= mid-1;low = mid; 则 high =-1 ;跳出循环
由此可知 ,只要有常数步前进就不会陷入死循环。
四是判断 while 循环的终止条件
如果左闭右开区间 ,循环终止条件为 low < high
如果左开右闭区间 , 循环终止条件为 low