题目描述:
升序数组a经过循环右移后,二分查找给定元素x。
如a={1,2,3,4,5,6,7},循环移动后a={5,6,7,1,2,3,4}。
思路:
(1)类似正常的二分查找,都是不断移动左右边界,不过判断条件更加复杂一点。
(2)每次计算中间那个元素mid,和左边界的元素left比较,总能确定有一边的区间是升序的;
(3)然后对升序那边进行分析,若这个区间不可能包含x,则不再考虑这个区间;若可能包含x,则将查找范围限制在这个区间。即每次都可以排除一半区间。
//a有n个元素,查找a是否包含x,存在的话输出任意一个值为x的元素在a的下标,不存在的话输出-1
int find(int a[], int n, int x)
{
int left = 0;
int right = n-1;
while(left <= right)
{
int mid = left + (right - left)/2;
if(a[mid] == x)
return mid;
if(a[mid] >= a[left]) //左边升序
{
if(a[left] > x)
left = mid + 1;
else if(a[mid] < x)
left = mid + 1;
else
right = mid - 1;
}
else //右边升序
{
if(a[right] < x)
right = mid - 1;
else if(a[mid] > x)
right = mid - 1;
else
left = mid + 1;
}
}
return -1;
}
int main(void)
{
int a[] = {5,6,7,1,2,3,4};
cout<<find(a,7,3)<<endl;
}