之前总是对二分的边界问题把握的不是很好,以致于出现死循环等问题。所以用这篇博文进行总结。
首先,本文所用算法均为左闭右闭的算法,且数组是以非递减顺序排列的。
1、查找是否存在关键值,如有相等的,则返回最左边的那个值的位置。否则,返回-1.
int binary_search_1(int a[], int n, int key)
{
int m, l = 0, r = n - 1;//闭区间[0, n - 1]
while (l < r)
{
m = l + ((r - l) / 2);//向下取整
if (a[m] < key)
l = m + 1;
else
r = m;
}
if (a[r] == key) return r;
return -1;
}
int binary_search_2(int a[], int n, int key)
{
int m, l = 0, r = n - 1;//闭区间[0, n - 1]
while (l < r)
{
m = l + ((r - l + 1) / 2);//向上取整
if (a[m] <= key)
l = m;
else
r = m - 1;
}
if (a[l] == key) return l;
return -1;
}
int binary_search_3(int a[], int n, int key)
{
int m, l = 0, r = n - 1;//闭区间[0, n - 1]
while (l < r)
{
m = l + ((r - l) / 2);//向下取整
if (a[m] <= key)
l = m + 1;
else
r = m;
}
if (a[r] > key) return r;
return -1;
}
int binary_search_4(int a[], int n, int key)
{
int m, l = 0, r = n - 1;//闭区间[0, n - 1]
while (l < r)
{
m = l + ((r - l + 1) / 2);//向上取整
if (a[m] < key)
l = m;
else
r = m - 1;
}
if (a[l] < key) return l;
return -1;
}
int binary_search_5(int a[], int n, int key)
{
int m, l = 0, r = n - 1;//闭区间[0, n - 1]
while (l < r)
{
m = l + ((r - l) / 2);//向下取整
if (a[m] <= key)
l = m + 1;
else
r = m;
}
if (a[r] >= key) return r;
return -1;
}
int binary_search_6(int a[], int n, int key)
{
int m, l = 0, r = n - 1;//闭区间[0, n - 1]
while (l < r)
{
m = l + ((r - l + 1) / 2);//向上取整
if (a[m] < key)
l = m;
else
r = m - 1;
}
if (a[l] <= key) return l;
return -1;
}
另外:
1、找最小(左)的就向下取整。找最大(右)的就向上取整。
2、如果向下取整了,l+1.如果向上取整了,r-1.
3、对于带等号的情况来说。寻找最小(左)的就是key <= a[m]。寻找最大(右)的就是key >= a[m].
4、对于不带等号的两种情况,把以上括号减掉。
5、最后判断条件根据情况而定。但是如果是最小(左)的是a[r],最大(右)的是a[l]