和一般的排序数组二分查找类似,下面这个链接中有详细讨论。
http://stackoverflow.com/questions/1878769/searching-a-number-in-a-rotated-sorted-array
大体思路如下:
如果arr[mid]==num,直接返回。
如果左边有序(有序与否只需检查左端点是否小于等于右端点,下同)且num在左边范围(检查是否在左右端点的数值之间,下同),则在左边找;
如果右边有序且num在右边范围,则在左边找;
如果左边无序,则在左边找;(分析:左右两边肯定至少有一边是有序的,这时左边无序,则右边肯定有序,而且前面的判断(第二个)说明不在右边,所以肯定在左边)
如果右边无序,则在右边找;
代码如下:
#include <iostream>
using namespace std;
int cbs(int arr[], int beg, int end, int num)
{
if(end - beg == 1)
{
if(arr[beg] == num)
return beg;
if(arr[end] == num)
return end;
return -1;
}
int mid = (beg + end) / 2;
if(arr[mid] == num)
return mid;
if(arr[beg] <= arr[mid - 1] && num >= arr[beg] && num <= arr[mid - 1]) //left
{
return cbs(arr, beg, mid - 1, num);
}
if(arr[mid + 1] <= arr[end] && num >= arr[mid + 1] && num <= arr[end])
{
return cbs(arr, mid + 1, end, num);
}
if(arr[beg] > arr[mid - 1])
return cbs(arr, beg, mid - 1, num);
if(arr[mid + 1] > arr[end])
return cbs(arr, mid + 1, end, num);
}
int circularbinarysearch(int arr[], int len, int num)
{
return cbs(arr, 0, len - 1, num);
}
int main()
{
int arr[] = {13,14,15,16,17,1,2,3,4,5,6,7,8,9,10,11,12};//1: 5
int len = sizeof(arr) / sizeof(arr[0]);
cout<<circularbinarysearch(arr, len, 13)<<endl;
cout<<circularbinarysearch(arr, len, 17)<<endl;
cout<<circularbinarysearch(arr, len, 1)<<endl;
cout<<circularbinarysearch(arr, len, 12)<<endl;
return 0;
}