版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u014281392/article/details/80992093
按条件查找:
查找序列中第一个大于等于x元素的位置
- 如果A[mid] >= x, 即 x 可能在 mid 或 mid的左侧, right = mid;
- 如果A[mid] < x, left = mid - 1;
按条件的二分查找与直接二分查找有几点不同:
1.循环条件,left < right, 不是 left <= right, 因为寻找第一个大于等于 x的元素,不需要必须判读x是否存在,就算 x 在序列中并不存在,返回的结果应是"假设 x 存在,它在序列中的位置".
2.由于当 left == right,循环结束,返回的结果可能是left或right.
3.二分查找的上界,n, 因为可能出现,x,比有序序列中的所有元素都大,所以返回结果应该是n,(假设 x存在,x 应该排列的位置).
#include <iostream>
using namespace std;
int lower_bound(int a[], int x, int left, int right) {
int mid;
while(left < right) { //left = right,退出循环,找到x
mid = (left + right)/2;
if (a[mid] >= x)
right = mid;
else
left = mid + 1;
}
return left;
}
int main() {
int A[10] = {1, 2, 3, 4, 4, 4, 5, 6, 7, 8};
int x;
cin >>x;
cout<<lower_bound(A, x, 0, 10);
return 0;
}
查找一个序列中第一个大于x元素的位置
#include <iostream>
using namespace std;
int upper_bound(int a[], int x, int left, int right) {
int mid;
while(left < right) {
mid = (left + right)/2;
if (a[mid] > x)
right = mid;
else
left = mid + 1;
}
return left;
}
int main() {
int A[10] = {1, 2, 3, 4, 4, 4, 5, 6, 7, 8};
int x;
cin >>x;
cout<<upper_bound(A, x, 0, 10);
return 0;
}
左开右闭写法
(left, right],循环条件while(left + 1 < right), 对于下标为0的序列,left = -1, right = n;
#include <iostream>
using namespace std;
int upper_bound(int a[], int x, int left, int right) {
int mid;
while(left+1 < right) {
mid = (left + right)/2;
if (a[mid] > x)
right = mid;
else
left = mid;
}
return right;
}
int main() {
int A[10] = {1, 2, 3, 4, 4, 4, 5, 6, 7, 8};
int x;
cin >>x;
cout<<upper_bound(A, x, -1, 10);
return 0;
}
假设有序序列中有一些重复元素x,查找 x的区间
举个例子:A = {1, 3, 3, 3, 6};, 返回 [1, 4];
#include <iostream>
using namespace std;
int lower_bound(int a[], int x, int left, int right) {
int mid;
while(left < right) {
mid = (left + right)/2;
if (a[mid] >= x)
right = mid;
else
left = mid + 1;
}
return left;
}
int upper_bound(int a[], int x, int left, int right) {
int mid;
while(left < right) {
mid = (left + right)/2;
if (a[mid] > x)
right = mid;
else
left = mid + 1;
}
return left;
}
int main() {
int A[10] = {1, 2, 3, 4, 4, 4, 5, 6, 7, 8};
int x;
cin >>x;
int l = lower_bound(A, x, 0, 10);
int r = upper_bound(A, x, 0, 10);
cout<<'['<<l<<','<<r<<']'<<endl;
return 0;
}
4
[3,6]
algorithm 中已经集成了这些函数
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
int A[10] = {1, 2, 3, 4, 4, 4, 5, 6, 7, 8};
int x;
cin >>x;
int * l = lower_bound(A, A+10, x);
int * r = upper_bound(A, A+10, x);
cout<<'['<<l - A<<','<<r - A<<']'<<endl;
return 0;
}
4
[3,6]