迴圈有序陣列的查詢筆記
阿新 • • 發佈:2019-01-01
背景:
雷達方位角的初步定位.
方法:
定義
一個迴圈有序陣列(如:3,4,5,6,7,8,9,0,1,2),不知道其最小值的位置,要查詢任一數值的位置。要求演算法時間複雜度為log2(n)。
對於迴圈有序陣列,一種簡單的定義是:
迴圈有序陣列是將一個有序陣列切成兩段,並交換位置得到引用塊內容
另一種比較嚴格的定義是:
對於一個迴圈有序陣列
a1,a2,…,an ,存在一個i,滿足1< i < n,使得a1,a2,…,ai 和ai,ai+1,…,an 同為單調不減,或單調不增陣列。且a1,a2,…,ai 中的任意一個元素恆大與等於或恆小於等於ai,ai+1 中的任意一個元素。,…,an
性質:
1.將一個迴圈有序陣列一分為二,一定得到一個有序陣列和另一個迴圈有序陣列
2.長度不超過2的迴圈有序陣列其實就是有序陣列。
解答思路:
第一步:我們要先弄清楚這個迴圈有序陣列的原陣列是單調減的還是單調增,如果
a1>an ,那麼a一定是增加型的迴圈有序陣列,如果a1<an ,那麼a一定是減少型的迴圈有序陣列。注意:
a1=an 這種情況。第二步:判斷左邊一半和右邊一半哪一個是有序的。這裡以增加型的舉例,減少型的同理。如果a[mid] >= a[start],那麼左邊一定是有序的。因為如果左邊是迴圈有序的,那麼最大值點一定出現在左側,且最大值點左側的數恆大於最大值點右側的數。這與a[mid] >= a[start]矛盾。反之同理。
第三步:確定了有序的一側後,就要判斷是不是在這一側搜尋了。這個判斷非常簡單,只要確定待搜尋的數的值是否在有序數列的兩個端點值之間即可。
第四步:最後通過迴圈,就可以類似二分法,找到待搜尋的數的位置。
程式碼
注:
#include <iostream>
using namespace std;
int getIndex(int a[],int seek,int arrayLength){
int start = 0;
int end = arrayLength;
if (a[start] >= a[end]) {//單增
while (start <= end) {
int mid = start + (end - start)/2;
int midValue = a[mid];
//說明這是一個在增加的迴圈有序陣列
if (midValue >= a[start]) {
//左側單調遞增
if (seek == a[mid]) {
return mid;
} else if (seek < a[mid] && seek >= a[start]){
//一定是在左側查詢
end = mid - 1;
}else{
//在右側查詢
start = mid + 1;
}
}
else{
//右側單調遞增,同理
if (seek == a[mid]) {
return mid;
}
else if (seek > a[mid] && seek <= a[end]){
//一定是在右側查詢
start = mid + 1;
}
else{
//在左側查詢
end = mid - 1;
}
}
}// while end
//沒找到元素
return -1;
}
else{
while (start <= end) {
int mid = start + (end - start)/2;
int midValue = a[mid];
//說明這是一個在減少的迴圈有序陣列
if (midValue >= a[start]) {
//右側單調遞減
if (seek == a[mid]) {
return mid;
}
else if (seek < a[mid] && seek >= a[end]){
//一定是在右側查詢
start = mid + 1;
}
else{
//在右側查詢
end = mid - 1;
}
}
else{
//左側單調遞減,同理
if (seek == a[mid]) {
return mid;
}
else if (seek <= a[start] && seek > a[mid]){
//一定是在左側查詢
end = mid - 1;
}
else{
//在左側查詢
start = mid + 1;
}
}
}
//沒找到元素
return -1;
}
}
int main(int argc,char * argv[]) {
// int a[] = {12,16,18,20,41,100,1,4,6,9};
int a[] = {9,6,4,1,100,41,20,18,16,12};
int seek = 20;
int arrayLength = sizeof(a)/sizeof(a[0]) - 1;
int index = getIndex(a,seek,arrayLength);
index == -1 ? cout<<"not found" : cout<<index;
return 0;
}