STL中的每个算法都非常精妙,

  ForwardIter lower_bound(ForwardIter first, ForwardIter last,const _Tp& val)算法返回一个非递减序列[first, last)中的第一个大于等于值val的位置。

     ForwardIter upper_bound(ForwardIter first, ForwardIter last, const _Tp& val)算法返回一个非递减序列[first, last)中第一个大于val的位置。

     lower_bound和upper_bound如下图所示:

 

[STL] lower_bound和upper_bound_二分查找

 

调用时注意,传入的firest 是第一元素的索引,传入的last是最后一个元素下一个元素的索引。

返回时,若所有元素都比targe 小,则返回last

 STL 的equal_range是基于lower_bound 和upper_bound实现的

 

1, lower_bound

  这个序列中可能会有很多重复的元素,也可能所有的元素都相同,为了充分考虑这种边界条件,STL中的lower_bound算法总体上是才用了二分查找的方法,但是由于是查找序列中的第一个出现的值大于等于val的位置,所以算法要在二分查找的基础上做一些细微的改动。

     

 1 int lower_bound(int* array, int low, int high, int key )
 2 {
 3      4      5     int mid = 0;
 6     while(low < high)
 7     {   
 8         mid =  (low + high)/2;
 9         if(array[mid] >= key)
10             //若中位数的值大于等于key,我们要在左边子序列查找,但有可能middle处就是最终位置,所以我们要包含mid,让high保持不动, 让low不断逼近high。
11             high = mid;// 注意,包含mid,high=mid,不是high = mid+1;
12         else
13             low = mid+1; //若中位数的值小于key的值,我们要在右边子序列中查找, 不包含mid
14 
15     }   
16     return high;
17 
18 }

 

2, upper_bound

upper_bound返回的是最后一个大于等于val的位置,也是有一个新元素val进来时的插入位置

 

 1 int upper_bound(int* array, int low, int high, int key )
 2 {
 3      4      5     int mid = 0;
 6     while(low < high)
 7     {   
 8         mid =  (low + high)/2;
 9         if(array[mid] > key)
10             //若中位数的值大于等于key,我们要在左边子序列查找,但有可能middle处就是最终位置,所以我们要包含mid,让high保持不动, 让low不断逼近high。
11             high = mid;// 注意,包含mid,high=mid,不是high = mid+1;
12         else
13             low = mid+1; //若中位数的值小于key的值,我们要在右边子序列中查找, 不包含mid
14 
15     }   
16     return high;
17 
18 }

 

 

另外,也可以用一个变量来记录当前的位置,写起来也很简单。。在传统二分基础上加两个判断

 1 #if 1
 2 int my_lower_bound(int *array, int low, int high, int key) 
 3 {
 4     int mid, pos= high;       
 5     high --;
 6 
 7     while(low <= high)
 8     {
 9         mid = (low + high)/2;
10         if(array[mid] >=  key){      
11             if(mid < pos)
12                 pos = mid;
13             high = mid- 1;  
14         }
15         else{
16            low = mid + 1; 
17         }
18     }
19     return pos;
20 }
21 int my_upper_bound(int *array, int low, int high, int key)
22 {
23     int mid, pos= high;       
24     high --;
25 
26     while(low <= high)
27     {
28         mid = (low + high)/2;
29         if(array[mid] >  key){      
30             if(mid < pos)
31                 pos = mid;
32             high = mid- 1;  
33         }
34         else{
35            low = mid + 1; 
36         }
37     }
38     return pos;
39 }
40 #endif