STL 源码剖析 算法 stl_algo.h -- upper_bound
2014-07-19 19:43
435 查看
本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie
upper_bound(应用于有序区间)
-------------------------------------------------------------------------------------------------------------------------------------------------
描述:受STL区间前闭后开习惯的影响,upper_bound成功找到某个值时,
返回一个迭代器指向每一个"不大于 value "的元素的下一个位置,而不是指向 value 的迭代器,
或找不到,返回value 应该存在的位置
思路:
1.循环直到区间长度为 0
2.如果 value < *middle,在前半段继续查找
3.如果 value >= *middle,在后半段继续查找 (等于的时候也会继续在后半段查找,所以能保证找到的是 upper bound)
源码:
template <class ForwardIterator, class T>
inline ForwardIterator upper_bound(ForwardIterator first, ForwardIterator last,
const T& value) {
return __upper_bound(first, last, value, distance_type(first),
iterator_category(first));
}
// forward_iterator_tag 版本
template <class ForwardIterator, class T, class Distance>
ForwardIterator __upper_bound(ForwardIterator first, ForwardIterator last,
const T& value, Distance*,
forward_iterator_tag) {
Distance len = 0;
distance(first, last, len);
Distance half;
ForwardIterator middle;
while (len > 0) {
half = len >> 1;
middle = first;
advance(middle, half);
if (value < *middle)
len = half;
else {
first = middle;
++first;
len = len - half - 1;
}
}
return first;
}
// random_access_iterator_tag 版本
template <class RandomAccessIterator, class T, class Distance>
RandomAccessIterator __upper_bound(RandomAccessIterator first,
RandomAccessIterator last, const T& value,
Distance*, random_access_iterator_tag) {
Distance len = last - first;
Distance half;
RandomAccessIterator middle;
while (len > 0) {
half = len >> 1;
middle = first + half;
if (value < *middle)
len = half;
else { //因为大于等都是在后半段区间查找,所以最后找到的一定是 upper bound,而且存在 value 的话, first 最后指示的就是 value 的下一个位置
first = middle + 1;
len = len - half - 1;
}
}
return first;
}
示例:
upper_bound(应用于有序区间)
-------------------------------------------------------------------------------------------------------------------------------------------------
描述:受STL区间前闭后开习惯的影响,upper_bound成功找到某个值时,
返回一个迭代器指向每一个"不大于 value "的元素的下一个位置,而不是指向 value 的迭代器,
或找不到,返回value 应该存在的位置
思路:
1.循环直到区间长度为 0
2.如果 value < *middle,在前半段继续查找
3.如果 value >= *middle,在后半段继续查找 (等于的时候也会继续在后半段查找,所以能保证找到的是 upper bound)
源码:
template <class ForwardIterator, class T>
inline ForwardIterator upper_bound(ForwardIterator first, ForwardIterator last,
const T& value) {
return __upper_bound(first, last, value, distance_type(first),
iterator_category(first));
}
// forward_iterator_tag 版本
template <class ForwardIterator, class T, class Distance>
ForwardIterator __upper_bound(ForwardIterator first, ForwardIterator last,
const T& value, Distance*,
forward_iterator_tag) {
Distance len = 0;
distance(first, last, len);
Distance half;
ForwardIterator middle;
while (len > 0) {
half = len >> 1;
middle = first;
advance(middle, half);
if (value < *middle)
len = half;
else {
first = middle;
++first;
len = len - half - 1;
}
}
return first;
}
// random_access_iterator_tag 版本
template <class RandomAccessIterator, class T, class Distance>
RandomAccessIterator __upper_bound(RandomAccessIterator first,
RandomAccessIterator last, const T& value,
Distance*, random_access_iterator_tag) {
Distance len = last - first;
Distance half;
RandomAccessIterator middle;
while (len > 0) {
half = len >> 1;
middle = first + half;
if (value < *middle)
len = half;
else { //因为大于等都是在后半段区间查找,所以最后找到的一定是 upper bound,而且存在 value 的话, first 最后指示的就是 value 的下一个位置
first = middle + 1;
len = len - half - 1;
}
}
return first;
}
示例:
int main() { int A[] = { 1, 2, 3, 3, 3, 5, 8 }; const int N = sizeof(A) / sizeof(int); for (int i = 1; i <= 10; ++i) { int* p = upper_bound(A, A + N, i); cout << "Searching for " << i << ". "; cout << "Result: index = " << p - A << ", "; if (p != A + N) cout << "A[" << p - A << "] == " << *p << endl; else cout << "which is off-the-end." << endl; } } /* The output is: Searching for 1. Result: index = 1, A[1] == 2 Searching for 2. Result: index = 2, A[2] == 3 Searching for 3. Result: index = 5, A[5] == 5 Searching for 4. Result: index = 5, A[5] == 5 Searching for 5. Result: index = 6, A[6] == 8 Searching for 6. Result: index = 6, A[6] == 8 Searching for 7. Result: index = 6, A[6] == 8 Searching for 8. Result: index = 7, which is off-the-end. Searching for 9. Result: index = 7, which is off-the-end. Searching for 10. Result: index = 7, which is off-the-end. */
相关文章推荐
- STL 源码剖析 算法 stl_algo.h -- lower_bound
- STL 源码剖析 算法 stl_algobase.h
- STL 源码剖析 算法 stl_algo.h -- search_n
- STL 源码剖析 算法 stl_algo.h -- partition
- STL 源码剖析 算法 stl_algo.h -- equal_range
- STL 源码剖析 算法 stl_algo.h -- binary_search
- STL 源码剖析 算法 stl_algo.h -- search
- STL 源码剖析 算法 stl_algo.h -- rotate
- STL 源码剖析 算法 stl_algo.h -- merge sort
- STL 源码剖析 算法 stl_algo.h -- nth_element
- STL 源码剖析 算法 stl_algo.h -- random_shuffle
- STL 源码剖析 算法 stl_algo.h -- next_permutation
- STL 源码剖析 算法 stl_algo.h -- includes
- STL 源码剖析 算法 stl_algo.h -- merge
- STL 源码剖析 算法 stl_algo.h -- inplace_merge
- STL 源代码剖析 算法 stl_algo.h -- lower_bound
- STL 源码剖析 算法 stl_algo.h -- partial_sort / partial_sort_copy
- STL 源码剖析 算法 stl_algo.h -- pre_permutation
- STL源码学习----lower_bound和upper_bound算法
- STL 源码分析《5》---- lower_bound and upper_bound 详解