您的位置:首页 > 其它

在旋转后的有序数组中查找元素,要求O(logn)的时间复杂度

2010-09-29 22:04 423 查看
题:比如说在A[] = {7, 8, 1, 2, 3, 4, 5, 6};查找元素。A是由{1, 2, 3, 4, 5, 6, 7, 8}左旋6位得到。

假定数组旋转前是有序递增的,且没有重复的元素。



方法:二分查找,再分情况讨论。在确定l, m, r后,旋转后的数组有图1所示的四种情况,且对应的元素有图2所示的关系。

由图中可以看出,根据A[l]与A[r]的大小关系可以区分出第4种情况。然后根据A[l]与A[m]的关系可以区分出第1中情况。

第2和第3中情况难以区分,但是如果

(1)m == r,肯定是第2种情况(或第4种情况,当然第4种情况右侧元素个数为0的话也退化成第2种情况)

(2)否则m < r,m+1在检查的范围之内,是有意义的

1)如果A[m] > A[m + 1]则是第2种情况

2)否则A[m] < A[m + 1]是第3种情况

对于第4和第2种情况,简单的调用通用的二分查找函数即可。

对于第1种情况,如果确定要查找的值在A[m+1:r]的范围内,可以调用简单的二分查找函数,否则对A[l:m+1]继续上面的情况分类。

对于第3种情况,讨论与第1种情况类似。

程序如下

]#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <ctime>
using namespace std;
static void left_rotate_1(int A[], const int N)
{
int tmp = A[0];
for (int i = 0; i < N - 1; i++){
A[i] = A[i + 1];
}
A[N - 1] = tmp;
}
static int binary_search(const int A[], int l, int r, const int val)
{
int m;
while (l <= r){
m = (l + r) >> 1;
if (val == A[m])
return m;
else if (val < A[m])
r = m - 1;
else
l = m + 1;
}
return -1;
}
static int rotated_search(const int A[], const int N,
const int val)
{
int l, r, m;
l = 0;
r = N - 1;
cout << "searching " << val << endl;
while (l <= r){
m = (l + r) >> 1;
if (A[l] < A[r]){
/*case 4*/
return binary_search(A, l, r, val);
}
if (val == A[m])
return m;
else if (A[l] > A[m]){
/*case 1*/
if (val > A[m] && val <= A[r])
return binary_search(A, m + 1, r, val);
else
r = m - 1;
}else{
/*case 2 and 3*/
if (m == r || A[m] > A[m + 1]){
/*case 2*/
l = binary_search(A, l, m - 1, val);
if (-1 != l)
return l;
return binary_search(A, m + 1, r, val);
}else{
/*case 3*/
if (val >= A[l] && val < A[m]){
return binary_search(A, l, m - 1, val);
}else{
l = m + 1;
}
}
}
}
return -1;
}
static inline void case_test(const int val)
{
cout << "get" << setw(5) << val << endl;
}
static void print_array(const int A[], const int N)
{
cout << "index:";
for (int i = 0; i < N; i++){
cout << setw(5) << i;
}
cout << endl;
cout << "array:";
for (int i = 0; i < N; i++){
cout << setw(5) << A[i];
}
cout << endl;
}
static int int_compare(const void *p1, const void *p2)
{
return (*(const int *)p1 - *(const int *)p2);
}
int main()
{
const int N = 8;
int A
= {4, 4, 5, 6, 7, 2, 3, 4};/* = {6, 1, 5, 5, 5, 3, 6, 4};*/

srandom((unsigned int)time(NULL));
print_array(A, N);
case_test(rotated_search(A, N, 5));
for (int i = 0; i < N; i++)
A[i] = random() % N;
qsort(A, N, sizeof(int), int_compare);

print_array(A, N);
case_test(rotated_search(A, N, 3));
case_test(rotated_search(A, N, random() % N));
case_test(rotated_search(A, N, random() % N));
case_test(rotated_search(A, N, random() % N));
left_rotate_1(A, N);
print_array(A, N);
case_test(rotated_search(A, N, random() % N));
case_test(rotated_search(A, N, random() % N));
case_test(rotated_search(A, N, random() % N));
case_test(rotated_search(A, N, random() % N));
left_rotate_1(A, N);
left_rotate_1(A, N);
print_array(A, N);
case_test(rotated_search(A, N, random() % N));
case_test(rotated_search(A, N, random() % N));
case_test(rotated_search(A, N, random() % N));
case_test(rotated_search(A, N, random() % N));
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐