二分查找很简单,二分查找的变形需要注意一些细节。
1、当找大于等于key的第一个元素,或者查找小于等于key的最后一个元素时,
循环条件是 low < high,这和基本的二分查找不同,
但需要在循环退出的时候,判断是否满足条件;
2、如果是找最后一个满足条件的情况,
下限移动时不能用 low=mid+1;而应该用 low=mid;
此时,mid计算时应该用 mid=(low+high+1)/2,
保证 最后low、high相差1时不会陷入死循环,
循环退出后,下限可能是结果;
3、如果是找第一个满足条件的情况,
移动时不能用 high=mid-1;而应该用 high=mid;
此时,mid计算时还是用 mid=(low+high)/2,想想为什么?
循环退出后,上限可能是结果;
#include <iostream>
using namespace std;
#define N 8
int binary_search(int a[], int low, int high, int key) {
while (low <= high) {
int mid = (low + high)/2;
if (a[mid] == key) {
return mid;
} else if (a[mid] > key) {
high = mid - 1;
} else { //a[mid] < key
low = mid + 1;
}
}
return -1;
}
//和stl源码剖析中6.7.3 upper_bound对应,
//不过有所不同,返回的是小于等于的最后一个值的位置
int binary_up_bound(int a[], int low, int high, int key) {
while (low < high) {
int mid = (low + high + 1)/2;
if (a[mid] > key) {
high = mid -1;
} else { //a[mid] <= key
low = mid;
}
}
if (a[low] <= key) {
return low;
} else {
return -1;
}
}
//和stl源码剖析中6.7.2 lower_bound 对应
int binary_low_bound(int a[], int low, int high, int key) {
while (low < high) {
int mid = (low + high)/2;
if (a[mid] < key) {
low = mid +1;
} else { //a[mid] >= key
high = mid;
}
}
if (a[high] >= key) {
return high;
} else {
return -1;
}
}
int main () {
int a[] = {
1,2,3,4,6,6,7,8
};
int pos = -1;
int key = 0;
cout << "intput key:";
cin >> key;
//pos = binary_search(a, 0, N-1, key);
//pos = binary_down_bound(a, 0, N-1, key);
pos = binary_up_bound(a, 0, N-1, key);
cout << "binary search result:" << pos << endl;
}
转载于:https://blog.51cto.com/tianyanshentong/1560237