###1、折半查找 折半查找(Binary Search)又稱爲二分查找。 注意 折半查找方法要求查找表的數據是線性結構保存,而且還要求查找表中的數據是按關鍵字由小到大有序排列。 ####折半查找的具體過程 假設有n個元素的查找表,首先計算位於查找表中間位置元素的序號m(m=n/2),取s[m]的關鍵字與給定值key進行比較。比較結果有3種可能 (1)若s[m]=key,表示查找成功。 (2)若s[m]>key,表示關鍵字key只可能在查找表的前半部分(因查找表中的數據是按從小到大的順序排 列),則在前半部分繼續進行折半查找。 (3)若s[m]<key,表示關鍵字key只可能在查找表的後半部分,則在後半部分繼續進行折半查找。 技巧 從上面的過程可看出,折半查找是一種遞歸過程。每折半查找一次,可以使查找範圍縮小一半,當查找範 圍縮小到只剩下一個元素,而該元素仍與關鍵字不相等,則說明查找失敗。 在最壞的狀況下,折半查找所需的比較次數爲O(nlog 2 n),其查找效率比順序查找法要快不少 例如,有如下數據: 6,12,28,37,54,65,69,83,90,92 若要查找關鍵字37,則查找過程以下圖1:數組
從上圖1的查找過程可看出,經過4次比較,可找到關鍵字37所在的位置。再例如,若要查找關鍵字66,其查找過程以下圖2:測試
從上圖2的過程可看出,經過4次比較,當查找範圍縮小到只剩一個元素,仍沒有找到指定關鍵字,說明查找失敗。code
###2、折半查找實現 ####折半查找法排序
/** *折半查找法(非遞歸) * */ int BinarySearch1(int s[], int n, int key) { int low, high, mid; low = 0; high = n-1; while (low <= high) { //查找結束條件,即至少包含一個元素 mid = (low + high)/2; //計算中間位置 if (s[mid] == key) //若是中間位置與關鍵字相同 return mid; //返回序號 else if (s[mid] > key) //中間元素大於關鍵字,關鍵字在左邊 high = mid - 1; //從新定義high else //中間元素大於關鍵字,關鍵字在右邊 low = mid + 1; //從新定義low } return -1; } /** *折半查找法(遞歸) * */ int BinarySearch2(int s[], int low, int high, int key) { int mid; if (low <= high) { //查找結束條件,即至少包含一個元素 mid = (low + high)/2; //計算中間位置 if (s[mid] == key) //若是中間位置與關鍵字相同 return mid; //返回序號 else if (s[mid] > key) //中間元素大於關鍵字,關鍵字在左邊 return BinarySearch2(s, low, mid-1, key); else return BinarySearch2(s, mid+1, high, key); } else return -1; }
####折半查找法測試遞歸
#include <stdio.h> #include "BinarySearch.c" #define ARRAYLEN 10 int main() { int key, i, pos; int source[ARRAYLEN]={6, 12, 28, 37, 54, 65, 69, 83, 90, 92}; /*折半查找,非遞歸*/ printf("請輸入查找關鍵字:"); scanf("%d", &key); pos = BinarySearch1(source, ARRAYLEN, key); printf("原數據:"); for (i=0; i< ARRAYLEN; i++) printf("%d ", source[i]); printf("\n"); if (pos >= 0) printf("查找成功,關鍵字%d位於數組的第%d個位置\n", key, pos); else printf("查找失敗,關鍵字%d不在數組中\n", key); /*折半查找,遞歸*/ printf("請輸入查找關鍵字:"); scanf("%d", &key); pos = BinarySearch2(source, 0, ARRAYLEN-1, key); printf("原數據:"); for (i=0; i< ARRAYLEN; i++) printf("%d ", source[i]); printf("\n"); if (pos >= 0) printf("查找成功,關鍵字%d位於數組的第%d個位置\n", key, pos); else printf("查找失敗,關鍵字%d不在數組中\n", key); }
###3、折半查找特色 ❑優勢:查找速度快,最多查找次數爲O(nlog 2 n)圖片
❑缺點:對查找表中的數據有順序要求,在進行查找前首先進行排序。若是須要將查找不成功的關鍵字數據添加到查找表中,則須要對查找表中的已有數據進行大量的移動操做。it