有序表的查找——折半查找分析

一、折半查找的查找過程

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)的時間。

二分查找只適用順序存儲結構。爲保持表的有序性,在順序結構裏插入和刪除都必須移動大量的結點。因此,二分查找特別適用於那種一經建立就很少改動、而又經常需要查找的線性表。

對那些查找少而又經常需要改動的線性表,可採用鏈表作存儲結構,進行順序查找。鏈表上無法實現二分查找。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章