想用二分法查找数据,搜了半天,发现非递归的大概两种。(我不喜欢递归的,担心堆栈问题)
如下:
https://yq.aliyun.com/ziliao/12066
/*第一种方法,判断都在循环内*/
int binSearch(int x, int a[], int n)
{
int low, high, mid;
low = 0;
high = n-1;
//注意,这里必须用<=, 用<不对,一直返回-1
while(low <= high)
{
mid = (low + high) / 2;
if(x < a[mid])
high = mid - 1;
else if(x > a[mid])
low = mid + 1;
else
return mid;
}
return -1;
}
/*在循环内执行一次测试的方法*/
/*int binSearch(int x, int a[], int n)
{
int low, high, mid;
low = 0;
high = n-1;
mid = (low + high) / 2;
while((low <= high)&&(a[mid]!=x))
{
if(x < a[mid])
high = mid -1;
else
low = mid + 1;
mid = (low + high) / 2;
}
if(a[mid] == x)
return mid;
else
return -1;
}
*/
在百度百科https://baike.baidu.com/item/%E4%BA%8C%E5%88%86%E6%B3%95%E6%9F%A5%E6%89%BE/9751511
有:
//非递归算法
int
binary(
int
*a,
int
key,
int
n )
{
int
left = 0, right = n - 1, mid = 0;
mid = ( left + right ) / 2;
while
( left < right && a[mid] != key )
{
if
( a[mid] < key ) {
left = mid + 1;
}
else
if
( a[mid] > key ) {
right = mid - 1;
}
mid = ( left + right ) / 2;
}
if
( a[mid] == key )
return
mid;
return
-1;
}
int
main()
{
int
a[] = {1,2,3,4,5,6,7,8,9,12,13,45,67,89,99,101,111,123,134,565,677};
int
b[] = {677,1,7,11,67};
int
i;
for
( i=0; i<
sizeof
(b)/
sizeof
(b[0]); i++ )
{
//printf( "%d\n", recurbinary(a, b[i],0,sizeof(a)/sizeof(a[0])-1) );
printf
(
"%d\n"
, binary( a, b[i],
sizeof
(a)/
sizeof
(a[0])));
}
return
0;
}
看出来了吧,可能有个错误的。懒得查哪个错了。
于是就用第一个链接的第一种方法了。
int binSearch(int x, int a[], int n)
{
int low, high, mid;
low = 0;
high = n-1;
//注意,这里必须用<=, 用<不对,一直返回-1
while(low <= high)
{
mid = (low + high) / 2;
if(x < a[mid])
high = mid - 1;
else if(x > a[mid])
low = mid + 1;
else
return mid;
}
return -1;
}
网上也有这么写的
int search(int aim,int data[],int size){
int det = -1;
int left = 0;
int right = size-1;
while(left<=right){
int mid = (left+right)/2;
if(data[mid]<aim){
left = mid+1;
}else if(data[mid]>aim){
right = mid-1;
}else{
det = mid;
break;
}
}
return det;
}
这个实现是绝对没有问题的,网上也有好多地方就是这么写的。
我不喜欢用int,涉及到负数的东西比较不容易理解。于是将int 改成uint16_t 就是 无符号的16bit的。
结果运行出错,如果想查找的aim在 数组data中不存在,就直接进入了hartdefault里面了。就是说可能指令出问题或内存溢出之类的。
很奇怪!必须找到根源!
跟踪了一下,发现当mid=0的时候,right=mid-1就是0xFFFFFFFF,于是下一把进入循环0<0xFFFFFFFF就为真,那么就是data[0XFFFFFFFF]
就是指针溢出,直接不给机会,飞到了九霄云外了!
如果用int类型,那么0<0XFFFFFFFF就不成立,就直接进入return det了。
所以原因找到。
看样以后写代码不能直接把int改成别的了。还好,我有个好习惯,只要是别人的东西,我改了的话,都要验证一下。
根源还是c语言还是很容易出问题的。
真是个危险的函数!!!