(一)思考思路
1:二分查找其实是给定一组具有单调函数的数,在其中查找你想要的元素
2:实际上把具有这样规律的数放在一个数组里,定义数组元素的下表为 i j
给定一个数组,元素个数为n 需要查询的数为a
int arr[n];
int left=0,right=sizeof(arr)/sizeof(arr[0])-1;
每次查询,取中间元素,下标为int x=(i+j)/2
当arr[x]>a 说明a在arr[x]的左边,即下标是小于x的 那么right=x-1;
当arr[x]<a 说明a在arr[x]的右边,即下标是大于x的 那么left=x+1;
3:因为具体不知道该进行几次,那么建议用while循环,至于循环条件,我们这样分析
①:在2中,我们不停的缩小范围,当left right交互或者相等时,说明把所有的数都查询过,那么会出现两个结果:查得到 查不到
②:由①可知 循环条件为 left <= right,我们就不停的查找
4:由于这个查找的功能太复杂,建议使用函数调用的方法来实现,那么有个问题,把数组传递形参时right=sizeof(arr)/sizeof(arr[0])-1,我们可以在定义的函数内求吗?
很多人这样写(省略其他部分:参数定义等等)
int scend_found( int adm[ ] , x);
;
int scend_found( int adm[ ] , x)
{
int ;
...........
}
实际上这样是错误的! 因为当实参为数组传递给形式参数时,
int set = int scend_found(arr, a) 中实际是数组arr中一个元素的地址,当我们计算right=sizeof(arr)/sizeof(arr[0])-1 时,实际上进行的操作同等于right=sizeof(arr[0])/sizeof(arr[0])-1 , 那么就错啦,既然在定义函数体内,我们不能运算,那么在传参的时候,我们可以在主函数中将数组大小算出来,然后作为一个实参传递给定义函数
(二)代码实现
#include<stdio.h>
int scend_found(int arr[],int key,int left,int right)
{
while(left<=right)
{
int sum=(right+left)/2;
if(arr[sum]<key)
{
left=sum+1;
}
else
if(arr[sum]>key)
{
right=sum-1;
}
else
return sum;
}
return -1;
}
int main()
{
int arr[10]={1,2,3,4,5,6,7,8,9,10};
int key=5;
int left=0,right=sizeof(arr)/sizeof(arr[0])-1;
int set=scend_found(arr,5,0, right);
// 二分查找只能适用于有规律的数组
if(set==-1)
printf("查找不到key\n");
else
{
printf("查找到key\n");
printf("%d %d\n",key,set);
}
system("pause");
return 0;
}