一个经典问题:
如何在一个严格递增序列A中找出给定的数X。
二分查找的高效之处在于,每一步都可以去除当前区间中的一半元素
因此其时间复杂度是O(logn)
优秀!!!
需要注意的是:
二分查找的过程与序列的下标从0开始还是从1开始无关
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<string>
using namespace std;
int pd(int A[],int left,int right,int x)
{
int mid;
while(left<=right)
{
mid=(left+right)/2;
if(A[mid]==x)
return mid;
else if(A[mid]>x)
{
right=mid-1;
}
else
{
left=mid+1;
}
}
return -1;
}
int main()
{
const int n=10;
int A[n]={1,3,4,6,7,8,10,11,12,15};
printf("%d %d\n",pd(A,0,n-1,6),pd(A,0,n-1,9));
return 0;
}
以上代码基于A是严格递增序列
那么,如果A是递减的
只要把A[mid]>x改为A[mid]<x即可
需要注意的是
如果二分上界超过int型数据类型范围的一半
那么mid=(left+right)/2的left+right就有可能超过int而溢出
所以一般使用mid=left+(right-left)/2(避免溢出)
下一个问题:如果递增序列A中的元素可能重复,那么如何对给定的
欲查询元素X,求出序列中的第一个大于等于x的元素的位置L以及
第一个大于x的元素的位置R,这样元素x在序列中的存在区间就是[L,R)