一、折半查找的查找過程
1、折半查找(Binary Search)
折半查找又稱二分查找,它是一種效率較高的查找方法。
二分查找要求:線性表是有序表,即表中結點按關鍵字有序,並且要用數組向量作爲表的存儲結構,不能使用鏈表,不妨設有序表是遞增有序的。
2、二分查找的基本思想
二分查找的基本思想是:(設R[low…high]是當前的查找區間)
(1)首先確定該區間的中點位置:R[mid]
(2)然後將待查的K值與R[mid].key比較:若相等,則查找成功並返回此位置,否則須確定新的查找區間,繼續二分查找,具體方法如下:
①若R[mid].key>K,則由表的有序性可知R[mid…n].keys均大於K,因此若表中存在關鍵字等於K的結點,則該結點必定是在位置mid左邊的子表R[1…mid-1]中,故新的查找區間是左子表R[1…mid-1]。
②類似地,若R[mid].key<K,則要查找的K必在mid的右子表R[mid+1…n]中,即新的查找區間是右子表R[mid+1…n]。下一次查找是針對新的查找區間進行的。
因此,從初始的查找區間R[1…n]開始,每經過一次與當前查找區間的中點位置上的結點關鍵字的比較,就可確定查找是否成功,不成功則當前的查找區間就縮小一半。這一過程重複直至找到關鍵字爲K的結點,或者直至當前的查找區間爲空(即查找失敗)時爲止。
二、折半查找的實現
int Search_Bin(StaicTable ST, Elemtype x,int low, int high){
//本函數在遞增表ST中進行折半查找,如果查找成功,返回該元素所在位置,否則返回0
found=false;
while (low≤high && !found)
{ mid=(low+high) / 2;
if (x>ST[mid].key) low=mid+1;
else if (x<ST[mid].key) high=mid-1;
else found=true;
}
if (found ) return mid;
else
return 0;
}
三、折半查找的性能分析
在這裏我們先假定要查找的元素數目n恰好構成一棵滿二叉樹,然後爲它加上n+1個外部結點,表示查找不成功的情形。
折半查找的過程可以用下面這樣的判定樹來模擬:
該樹有m(=2n+1)個結點,高度爲 K= log(m+1)=log(n+1)+1。
最壞情形下,就是查找不成功的情形必須要查到葉子結點,查找次數爲K次,即log(n+1)+1
要求折半查找的平均情形,我們設落在每個結點的概率均爲 1/m, 則總的查找次數爲:
11/m + 2(21/m) + 3(41/m) + …… + k(2k-1*1/m)
而m=2k-1,故A(n)=((k-1)2k+1)/(2k)=(k-1)+1/2k
一般化(即非滿二叉樹),有:
四、總結
雖然二分查找的效率高,但是要將表按關鍵字排序。而排序本身是一種很費時的運算。既使採用高效率的排序方法也要花費O(nlog2n)的時間。
二分查找只適用順序存儲結構。爲保持表的有序性,在順序結構裏插入和刪除都必須移動大量的結點。因此,二分查找特別適用於那種一經建立就很少改動、而又經常需要查找的線性表。
對那些查找少而又經常需要改動的線性表,可採用鏈表作存儲結構,進行順序查找。鏈表上無法實現二分查找。