1. 程式人生 > >12、【演算法】查詢演算法總結

12、【演算法】查詢演算法總結

一、順序查詢

1、定義

    順序查詢屬於無序查詢,從資料結構的一端開始,順序掃描,依次將掃描到的節點關鍵字與給定值K相比,若相等,則表示查詢成功,若掃描結束,仍未找到關鍵字與給定值K相等,則表示查詢失敗。

時間複雜度分析
    查詢成功時:平均查詢長度為(N+1)/2
    查詢失敗時:需要比較N+1次
    因此,順序查詢的時間複雜度為O(N)

2、 實現(C++)
int search(int *arr, int K)
{
     int len = sizeof(arr)/sizeof(arr[0]);//計算陣列大小
     for(int i = 0
; i < len; i++) { if(k == arr[i]) return i; } return 0; }

二、二分查詢

1、定義

    也稱折半查詢,元素必須是有序的,如果是無序的,則要先進性排序操作。

時間複雜度分析
    最壞的情況,關鍵字比較次數為:log2(N+1),且期望事件複雜度為O(log2N)

2、實現

(C++ 非遞迴)

int binarySearch(int *arr, int value)
{
     int left, high, mid;
     int
len; len = sizeof(arr)/sizeof(arr[0]);//獲取陣列長度 left = 0; high = len - 1; while(left <= high) { mid = (left + high)/2; if(arr[mid] == value) return mid; if(arr[mid] < value) left = mid + 1; if(arr[mid] > value)
high = mid - 1; } return -1; }

(C++ 遞迴)

int binarySearch(int *arr, int value, int low, int high)
{
     int mid = (low + high)/2;
     if(arr[mid] == value)
         return mid;
     if(arr[mid] > value)
         return binarySearch(arr, value, low, mid - 1);
      if(arr[mid] < value)
         return binarySearch(arr, value, mid+1, high);
}

三、插值查詢

1、定義

    插值查詢是對摺半查詢的優化,本質上是對查詢點進行改進:mid = low + ((Key - arr[low])/(arr[high] - arr[low]))*(high - low);
    也就是將比例引數1/2改進為自適應的。
    適用於表長較大,而關鍵字分佈又比較均勻的查詢表。反之,如果表中分佈非常不均勻,那麼插值查詢未必是很合適的選擇。

時間複雜度分析
    查詢成功或者失敗的時間複雜度均為O(log2(log2N))

2、實現(C++ 遞迴)
int insertionSearch(int *arr, int value, int low, int high)
{
     int mid = low + ((value - arr[low])/(arr[high] - arr[low]))*(high - low);
    
     if(arr[mid] == value)
         return mid;
     if(arr[mid] > value)
         insertionSearch(arr, value, low, mid-1);
     if(arr[mid] < value)
         insertionSearch(arr, value, mid+1, high);
}

4、斐波那契查詢

1、定義

    黃金分割比的值約1:0.618或者1.618:1
    斐波那契數列:1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89…….,其前後兩個值的比值越來越接近0.618,利用這個特性,就可以將黃金分割比運用到查詢技術中。
    斐波那契查詢演算法同樣是二分查詢的一種改進。通過運用環境分割比的概念在數列中選擇查詢點進行查詢,提高查詢效率。斐波那契查詢也屬於一種有序查詢演算法。

時間複雜度分析
最壞的情況下:時間複雜度為O(log2N),且期望複雜度也為O(log2N)

2、實現(C++)
#define MAX 100
//構造斐波那契數列
void fibonacci(int *F)
{
     F[0] = 0;
     F[1] = 1;
     for(int i = 2; i < MAX; i++)
     {
         F[i] = F[i-1] + F[i-2];
     }
}
//斐波那契查詢
int fibonacciSearch(int *arr, int value)
{
     int len = sizeof(arr)/sizeof(arr[0]);

     int low = 0;
     int high = len - 1;//構造一個斐波那契數列
    
     int F[MAX];
     fibonacci(F);

     int k = 0;
     while(len > F[k] - 1);//計算len在斐波那契數列中的位置
         k++;
    
     int *temp;//將陣列arr擴充套件到F[k]-1長度

     temp = new int [F[k] -1];
     memcpy(temp, arr, len*sizeof(int));

     for(int i = len; i < F[k]-1; i++)
         temp[i] = arr[len-1];

     while(low < high)
     {
         int mid = low + F[k-1] -1;
         if(value < temp[mid])
         {
              high = mid - 1;
              k -= 1;
         }
         else if(value > temp[mid])
         {
              low = mid + 1;
              k -= 2;
         }
         else
         {
              if(mid < len)
                   return mid;
              else
                   return len-1;
         }
     }
     delete[] temp;
     return -1;
}