#include<iostream>
using namespace std;
void func(int *a, int length, int find)
{
int L = 0;
int R = length;
while (L < R)
{
int middle = L + ((R - L) >> 1);
if (find < a[middle])
{
R = middle;
}
else if (find > a[middle])
{
L = middle + 1;
}
else
{
printf("%d\n", middle);
break;
}
}
if (L >= R)
{
printf("没找到\n");
}
}
int main()
{
int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
func(a, 10, 10);
return 0;
}
还有另外一种
#include<iostream>
using namespace std;
void func(int *a, int length, int find)
{
int L = 0;
int R = length - 1;
int flat = 0;
while (L <= R)
{
int middle = L + ((R - L) >> 1);
if (find < a[middle])
{
R = middle - 1;
}
else if (find > a[middle])
{
L = middle + 1;
}
else
{
printf("%d\n", middle);
flat = 1;
break;
}
}
if (flat = 0)
{
printf("没找到\n");
}
}
int main()
{
int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
func(a, 10, 10);
return 0;
}
这里我主要想警醒自己的就是边界问题,之前我从来没有感觉到扣边界是这么重要的一件事情,直到昨天下午,只是仅凭着大脑的想法去实现代码,发现越来越乱,越来越乱,我感觉是时候写一点东西类警醒自己了。
上面我写了两种方法主要就是关于边界的讨论。
第一种的边界情况是这样的,也就是说 [ )
代表的就是这样一种情况,也正是因为这样所以可以不在while循环中讨论 =
的情况,也就是在 L > middle的时候要进行L = middle +1的操作。
第一种属于边界不对称的写法。
第二种写的是边界对称的写法,
边界对称的写法的好处就是整齐,其次可能是便于记忆吧!
但是在边界对称的时候要在while循环中讨论L = R
的这种写法,其次就是L和R判断的时候要进行相同的左移或者右移一位的操作。我用了一个标记位flag来判断是否真的找到这个数字。
总之以后写代码一定要扣边界,头疼。