首页 > 代码库 > STL 源码剖析 算法 stl_algo.h -- lower_bound
STL 源码剖析 算法 stl_algo.h -- lower_bound
本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie
lower_bound(应用于有序区间)
--------------------------------------------------------------------------------------------------------------------------
描述:二分查找,返回一个迭代器指向每一个"不小于 value "的元素,
或 value 应该存在的位置
思路:
1.循环直到区间长度为 0
2.如果 *middle < value,在后半段继续查找
3.如果 *middle >= value,在前半段继续查找 (等于的时候也会继续在前半段查找,所以能保证找到的是 lower bound)
源码:
template <class ForwardIterator, class T> inline ForwardIterator lower_bound(ForwardIterator first, ForwardIterator last, const T& value) { return __lower_bound(first, last, value, distance_type(first), iterator_category(first)); } // forward_iterator_tag 版本 template <class ForwardIterator, class T, class Distance> ForwardIterator __lower_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); // 因为只是 ForwardIterator,不能采用 middle = middle + half 的方式 if (*middle < value) { first = middle; ++first; len = len - half - 1; } // 因为 *middle >= value 时,会在前半段继续查找,所以最终找到的是 lower bound else len = half; } return first; } // random_access_iterator_tag 版本 template <class RandomAccessIterator, class T, class Distance> RandomAccessIterator __lower_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; //除以2 middle = first + half; if (*middle < value) { first = middle + 1; len = len - half - 1; // -half-1 是因为前面那段有first指向的元素和half指向的区间 } else //为什么这样的代码能保证找到的是 lower bound ?--> 因为小于等于都是到前面一段区间查找,所以最后找到的一定是 lower bound len = half; } 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 = lower_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 = 0, A[0] == 1 Searching for 2. Result: index = 1, A[1] == 2 Searching for 3. Result: index = 2, A[2] == 3 Searching for 4. Result: index = 5, A[5] == 5 Searching for 5. Result: index = 5, A[5] == 5 Searching for 6. Result: index = 6, A[6] == 8 Searching for 7. Result: index = 6, A[6] == 8 Searching for 8. Result: index = 6, A[6] == 8 Searching for 9. Result: index = 7, which is off-the-end. Searching for 10. Result: index = 7, which is off-the-end. */
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。