//二分查找,在一个有序数组(升序)里找到目标值所在的位置,最后返回值是下标.
#include<stdio.h>
#include<windows.h>
#define NO -1
int BinSearch(int num,int X,int arr[])
{
int start = 0;
int end = num - 1;
while (start<=end){
int middle = (end + start) / 2;
if (arr[middle]>X){
end = middle - 1;
}
else if (arr[middle] < X){
start = middle + 1;
}
else {
return middle;
}
}
return NO ;
}
int main(){
int arr[] = { 11, 22, 33, 44, 55, 66, 77, 88, 99 };
int num = sizeof (arr) / sizeof(arr[0]);
int X = 88;
int result = BinSearch(num, X,arr);
printf("result=%d", result);
system("pause");
return 0;
}
二分查找的优点:从时间和空间上优化查找工作,比遍历效率高很多.
细节点记录:
1.在做二分查找的时候,返回值不能是负数,所以一般设定的返回值是数组的下标。而且通常把没有找到的返回值设成-1,因为-1与数组的下标没有冲突。
2.循环的条件不能忘记是start>=end,如果漏掉等号,当最终start与end指向同一个值时,这个值没有被判定.
3.在写这个代码时了解到,设定一个函数参数时如果参数中包含数组,写"int arr[]",主函数在调用的时候,写"arr".
4.计算数组元素个数时,num=sizeof(arr)/sizeof(arr[0]);
5.int middle = (end + start) / 2; 这行代码考虑溢出问题就应该改个写法,加法改成减法,溢出概率减小很多,如何改呢举个例子,两个数求平均值:
eg.求4与8平均值
方法一: (4+8)/2 这个方式为先加后除,如果用这种方法发求middle,有溢出问题 .
方法二: 4+{(8-4)/2 } 这个方式改加为减,大大降低了溢出可能性.
方法三: 目前在这里先只提一下,除法本身可以用右移取代.