二分查找算法

簡介

二分查找又稱折半查找,用於在順序存儲結構(邏輯上相連的節點在物理存儲上也相連,如數組)的而且關鍵字有序的線性表中查找關鍵字,是一種效率比較高的查找算法。ios

基本邏輯

假如須要查找的序列是一個非遞減序列,首先把序列從中間分紅兩半。c++

1.若是查找的關鍵字跟序列中間關鍵字相同,說明查找到了,中止查找並返回位置。算法

2.若是要查找的關鍵字比序列中間關鍵字要小,說明須要查找的關鍵字在序列的前半部分,查找的序列的範圍就變成前半部分;數組

3.若是要查找的關鍵字比序列中間關鍵字要大,說明須要查找的關鍵字在序列的後半部分,查找的序列的範圍就變成後半部分;測試

4.再從新把上面的序列從中間分紅兩半,重複步驟1。直到要查找的序列的長度爲0表示查找失敗。spa

例子

待查找序列爲0, 1, 7, 9, 11, 13, 18, 19code

須要查找的關鍵字爲18blog

首先把序列分紅兩半,前半部分爲0, 1, 7, 9;後半部分爲9, 11, 13, 18, 19。遞歸

1.因爲待查找關鍵字18比中間的關鍵字9要大,說明查找的關鍵字在後半部分,即11, 13, 18, 19。io

2.從新把序列分紅兩半,前半部分爲11,13,後半部分爲13, 18, 19。

3.因爲待查找關鍵字18比中間的關鍵字13要大,說明查找的關鍵字在後半部分,即 18, 19。

4.從新把序列分紅兩半,前半部分爲18,後半部分爲18, 19。

5.因爲待查找關鍵字18跟中間的關鍵字18相同,說明找到了,中止查找並返回位置6。

 

c/c++示例代碼(遞歸和非遞歸實現)

  1 #include <iostream>
  2 using namespace std;
  3 
  4 /************************************************************************/
  5 /* @brief 二分查找非遞歸實現
  6 /* @param arr非遞減數組
  7 /* @param start數組查找範圍起始下標
  8 /* @param end數組查找範圍結束下標
  9 /* @param key須要查找的值
 10 /* @return key在數組中的下標 -1表示沒有查找到
 11 /************************************************************************/
 12 int binarySearch(const int* arr, int start, int end, const int key)
 13 {
 14     int index = -1;
 15     //如何傳入的參數有問題,直接返回-1,查找失敗
 16     if (arr == nullptr || start < 0 || end < start)
 17     {
 18         return index;
 19     }
 20 
 21     while (end >= start)
 22     {
 23         int middle = (end - start) / 2 + start;
 24         //查找到
 25         if (arr[middle] == key)
 26         {
 27             index = middle;
 28             break;
 29         }
 30         //查找的值比中間的值小,說明在前半部分
 31         else if (arr[middle]  > key)
 32         {
 33             end = middle - 1;
 34         }
 35         //查找的值比中間的值大,說明在後半部分
 36         else
 37         {
 38             start = middle + 1;
 39         }
 40     }
 41     return index;
 42 }
 43 
 44 /************************************************************************/
 45 /* @brief 二分查找遞歸實現
 46 /* @param arr非遞減數組
 47 /* @param start數組查找範圍起始下標
 48 /* @param end數組查找範圍結束下標
 49 /* @param key須要查找的值
 50 /* @return key在數組中的下標 -1表示沒有查找到
 51 /************************************************************************/
 52 int binarySearchR(const int* arr, int start, int end, const int key)
 53 {
 54     int index = -1;
 55     //如何傳入的參數有問題,直接返回-1,查找失敗
 56     if (arr == nullptr || start < 0 || end < start)
 57     {
 58         return index;
 59     }
 60 
 61     int middle = (end-start) / 2 + start;
 62     //查找到
 63     if (arr[middle] == key)
 64     {
 65         index = middle;
 66     }
 67     //查找的值比中間的值小,說明在前半部分
 68     else if (arr[middle] > key)
 69     {
 70         return binarySearchR(arr, start, middle - 1, key);
 71     }
 72     //查找的值比中間的值大,說明在後半部分
 73     else
 74     {
 75         return binarySearchR(arr, middle + 1, end, key);
 76     }
 77 
 78     return index;
 79 }
 80 
 81 int main()
 82 {
 83     int arr[8] = { 0, 1, 7, 9, 11, 13, 18, 19 };
 84 
 85     cout << "原始數據:" << endl;
 86 
 87     for (int i = 0; i < sizeof(arr) / sizeof(int); ++i)
 88     {
 89         cout << arr[i] << "  ";
 90     }
 91 
 92     int key = 18;
 93 
 94     cout << endl << "查詢結果:" << endl;
 95 
 96     int index = binarySearch(arr, 0, 7, key);
 97 
 98     cout << "非遞歸查找" << key << ":" << index << endl;
 99 
100     index = binarySearchR(arr, 0, 7, key);
101 
102     cout << "遞歸查找" << key << ":" << index << endl;
103 
104     return 0;
105 }

 

測試結果

相關文章
相關標籤/搜索