二分查找求上界和下界
2016-05-30 12:21
836 查看
二分查找求上界和下界
假设序列有序,其区间为[left,right),设middle为区间中间值,现在需要获得首个出现元素v的位置,如果不存在,返回一个位置,在此插入v,序列仍然有序,则可以通过以下方式求出:if middle位置的值 = v:至少已经找到一个,左边可能还有,则区间变为[left,middle]。
if middle位置的值 > v:所求位置不可能在后面,但可能是middle,则区间变为[left,middle]。
if middle位置的值 < v:middle和前面都不可行,则区间变为[middle+1,right]。
求下界算法实现
// 二分查找求下界 int lowerBound(int *a, int lef, int righ, int v) { int middle; while(lef < righ) { // 取中值 middle = lef + (righ - lef) / 2; if(v <= a[middle]) { righ = middle; } else { lef = middle + 1; } } return lef; }
同理也可以求出上界,因为[x,y)左闭右开,返回的将是它出现的最后一个位置的下一个位置,不存在的情况和下界一样。
求上界算法实现
// 二分查找求上界 int upperBound(int *a, int lef, int righ, int v) { int middle; while(lef < righ) { // 取中值 middle = lef + (righ - lef) / 2; if(v >= a[middle]) { lef = middle + 1; } else { righ = middle; } } return lef; }
测试主程序
#include <iostream>
using namespace std;
// 二分查找求下界 int lowerBound(int *a, int lef, int righ, int v) { int middle; while(lef < righ) { // 取中值 middle = lef + (righ - lef) / 2; if(v <= a[middle]) { righ = middle; } else { lef = middle + 1; } } return lef; }
// 二分查找求上界 int upperBound(int *a, int lef, int righ, int v) { int middle; while(lef < righ) { // 取中值 middle = lef + (righ - lef) / 2; if(v >= a[middle]) { lef = middle + 1; } else { righ = middle; } } return lef; }
int main() {
int a[] = {-10, -5, 0, 0, 1, 3, 3, 3, 5, 10};
int n = 10;
int v = -100;
cout << "元素" << v << "在a中的下界位置是:" << lowerBound(a, 0, n, v) << endl;
v = -10;
cout << "元素" << v << "在a中的下界位置是:" << lowerBound(a, 0, n, v) << endl;
v = 0;
cout << "元素" << v << "在a中的下界位置是:" << lowerBound(a, 0, n, v) << endl;
v = 3;
cout << "元素" << v << "在a中的下界位置是:" << lowerBound(a, 0, n, v) << endl;
v = 10;
cout << "元素" << v << "在a中的下界位置是:" << lowerBound(a, 0, n, v) << endl;
v = 100;
cout << "元素" << v << "在a中的下界位置是:" << lowerBound(a, 0, n, v) << endl;
cout << endl << endl;
v = -100;
cout << "元素" << v << "在a中的上界位置是:" << upperBound(a, 0, n, v) << endl;
v = -10;
cout << "元素" << v << "在a中的上界位置是:" << upperBound(a, 0, n, v) << endl;
v = 0;
cout << "元素" << v << "在a中的上界位置是:" << upperBound(a, 0, n, v) << endl;
v = 3;
cout << "元素" << v << "在a中的上界位置是:" << upperBound(a, 0, n, v) << endl;
v = 10;
cout << "元素" << v << "在a中的上界位置是:" << upperBound(a, 0, n, v) << endl;
v = 100;
cout << "元素" << v << "在a中的上界位置是:" << upperBound(a, 0, n, v) << endl;
return 0;
}
输出数据
元素-100在a中的下界位置是:0 元素-10在a中的下界位置是:0 元素0在a中的下界位置是:2 元素3在a中的下界位置是:5 元素10在a中的下界位置是:9 元素100在a中的下界位置是:10 元素-100在a中的上界位置是:0 元素-10在a中的上界位置是:1 元素0在a中的上界位置是:4 元素3在a中的上界位置是:8 元素10在a中的上界位置是:10 元素100在a中的上界位置是:10 Process returned 0 (0x0) execution time : 1.609 s Press any key to continue.
相关文章推荐
- 书评:《算法之美( Algorithms to Live By )》
- 动易2006序列号破解算法公布
- Ruby实现的矩阵连乘算法
- C#插入法排序算法实例分析
- 超大数据量存储常用数据库分表分库算法总结
- C#数据结构与算法揭秘二
- C#冒泡法排序算法实例分析
- 算法练习之从String.indexOf的模拟实现开始
- C#算法之关于大牛生小牛的问题
- C#实现的算24点游戏算法实例分析
- c语言实现的带通配符匹配算法
- 浅析STL中的常用算法
- C++二分查找在搜索引擎多文档求交的应用分析
- 算法之排列算法与组合算法详解
- C++实现一维向量旋转算法
- Ruby实现的合并排序算法
- C#折半插入排序算法实现方法
- 基于C++实现的各种内部排序算法汇总
- C++线性时间的排序算法分析
- C++实现汉诺塔算法经典实例