一、lower_bound
用法:int t=lower_bound(a+l,a+r,m)-a
解释:在升序排列的a数组内二分查找[l,r)区间内的值为m的元素。返回m在数组中的下标。
特殊情况:
1.如果m在区间中没有出现过,那么返回第一个比m大的数的下标。
2.如果m比所有区间内的数都大,那么返回r。这个时候会越界,小心。
3.如果区间内有多个相同的m,返回第一个m的下标。
时间复杂度:
一次查询O(log n),n为数组长度。
//first左边(不含)均<key
//first+len及右边(含)均>=key
//len=0时,跳出循环。此时first左边均<key,first及右边均>=key,因此first是第一个>=key的元素位置。
int lower_bound(int *array, int size, int key)
{
int first = 0, middle;
int half, len;
len = size;
while(len > 0) {
half = len >> 1;
middle = first + half;
if(array[middle] < key) {
first = middle + 1;
len = len-half-1; //在右边子序列中查找
}
else
len = half; //在左边子序列(包含middle)中查找
}
return first;
}
二、upper_bound
用法:int t=upper_bound(a+l,a+r,m)-a
解释:在升序排列的a数组内二分查找[l,r)区间内的值为m的元素。返回m在数组中的下标+1。
特殊情况:
1.如果m在区间中没有出现过,那么返回第一个比m大的数的下标。
2.如果m比所有区间内的数都大,那么返回r。这个时候会越界,小心。
3.如果区间内有多个相同的m,返回最后一个m的下标+1。
时间复杂度:
一次查询O(log n),n为数组长度。
//first左边(不含)均<=key
//first+len及右边(含)均>key
//len=0时,跳出循环。此时first左边均<=key,first及右边均>key,因此first是第一个>key的元素位置。
int upper_bound(int *array, int size, int key)
{
int first = 0, len = size-1;
int half, middle;
while(len > 0){
half = len >> 1;
middle = first + half;
if(array[middle] > key) //中位数大于key,在包含last的左半边序列中查找。
len = half;
else{
first = middle + 1; //中位数小于等于key,在右半边序列中查找。
len = len - half - 1;
}
}
return first;
}
部分内容转自:
http://www.cnblogs.com/cobbliu/archive/2012/05/21/2512249.html