1. 程式人生 > >迴圈有序陣列的查詢筆記

迴圈有序陣列的查詢筆記

背景:

雷達方位角的初步定位.

方法:

定義

一個迴圈有序陣列(如:3,4,5,6,7,8,9,0,1,2),不知道其最小值的位置,要查詢任一數值的位置。要求演算法時間複雜度為log2(n)。

對於迴圈有序陣列,一種簡單的定義是:

迴圈有序陣列是將一個有序陣列切成兩段,並交換位置得到引用塊內容

另一種比較嚴格的定義是:

對於一個迴圈有序陣列a1,a2,,an,存在一個i,滿足1< i < n,使得a1,a2,,aiai,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]矛盾。反之同理。

第三步:確定了有序的一側後,就要判斷是不是在這一側搜尋了。這個判斷非常簡單,只要確定待搜尋的數的值是否在有序數列的兩個端點值之間即可。

第四步:最後通過迴圈,就可以類似二分法,找到待搜尋的數的位置。

程式碼

注:a1=an這種情況沒有考慮。

#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; }