二分算法——有序序列
二分法可以作为某几类问题的通用解法:
- 有序序列中是否存在满足某条件的元素;
- 有序序列中第一个满足某条件的元素的位置;
- 有序序列中最后一个满足某条件的元素的位置。
1. 有序序列中是否存在满足某条件的元素:
eg. 查找一个严格递增序列中是否存在给定的数 x,存在返回下标序号,不存在返回 -1
/*left为数组最低位,right为数组最高位*/
int BinarySearch(int A[], int left, int right, int x)
{
int mid;
while(left <= right) // 当查找存在与否时,需要考虑left=right情况
{
// mid = (left + right) / 2; // 存在整型数溢出的危险
mid = left + (right - left) / 2;
if(x == A[mid])
{
return mid;
}
else if(x < A[mid])
{
right = mid - 1;
}
else
{
left = mid + 1;
}
}
return -1;
}
2. 有序序列中第一个满足某条件的元素的位置:
求出序列中第一个大于等于x的元素位置L,以及第一个大于x的元素位置R,x在序列中的存在区间就是 [L,R)。
eg1. 查找一个非严格递增序列中,第一个大于等于x的元素位置
/*left为数组最低位,right为数组最高位n+1*/
int lower_bound(int A[], int left, int right, int x)
{
int mid;
while(left < right) // 必定有返回值,则left==right时,夹出来的即为结果
{
mid = left