折半查找,也稱二分查找,是一種效率較高的查找方法。
要求線性表必須采用 順序結構,表中元素按關鍵字 有序排列。
int Search_Bin (SSTable ST, KeyType key) {
int low = 1, high = ST.length;
while (low <= high) { // 注意不是low<high,因為low=high時,查找區間還有最后一個結點,還要進一步比較
int mid = (low + high) / 2;
if (ST[mid].key == key) return mid;
else if (ST[mid].key > key) high = mid - 1;
else (ST[mid].key < key) low = mid + 1;
}
return 0;
}
注:該算法可改為遞歸實現
算法分析:
折半查找過程可用二叉樹來描述,結點值不是記錄的關鍵字,二是記錄在表中的位置序號。
把當前查找區間的中間位置作為根,左子表和右子表分別作為根的左子樹和右子樹,由此得到的二叉樹稱為折半查找的 判定樹 。

借助判定樹,易得折半查找的平均查找長度。
假設有序表的長度\(n=2^h - 1\),則判定表的深度\(h=log_2(n+1)\)的滿二叉樹。
樹中層次為\(1\)的結點有\(1\)個,層次為\(2\)的結點有\(2\)個,...,層次為\(h\)的結點有\(2^{h-1}\)個。
平均查找長度
\[ASL=\sum_{i=1}^{n}{P_iC_i} = \frac{i}{n}\sum_{j=1}^{h}{j·2^{j-1}} = \frac{n+1}{n}log_2(n+1)-1 \]
當n較大時,可有下列近似結果\(ASL=log_2(n+1)-1\)
優點:比較次數少,查找效率高
缺點:對表結構要求高,只能用於順序存儲的有序表。查找前需要排序,排序本身也會消耗時間。為保持有序性,插入和刪除時,也需耗時運算。
因此, 折半查找不適用於數據元素經常變動的線性表。
