標籤:style blog http color io ar strong 2014 sp
轉自:http://student.zjzk.cn/course_ware/data_structure/web/chazhao/chazhao9.2.2.1.htm
二分尋找
1、二分尋找(Binary Search)
二分尋找又稱折半尋找,它是一種效率較高的尋找方法。
二分尋找要求:線性表是有序表,即表中結點按關鍵字有序,並且要用向量作為表的儲存結構。不妨設有序表是遞增有序的。
2、二分尋找的基本思想
二分尋找的基本思想是:(設R[low..high]是當前的尋找區間)
(1)首先確定該區間的中點位置:
(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的結點,或者直至當前的尋找區間為空白(即尋找失敗)時為止。
3、二分尋找演算法
int BinSearch(SeqList R,KeyType K)
{ //在有序表R[1..n]中進行二分尋找,成功時返回結點的位置,失敗時返回零
int low=1,high=n,mid; //置當前尋找區間上、下界的初值
while(low<=high){ //當前尋找區間R[low..high]非空
mid=(low+high)/2;
if(R[mid].key==K) return mid; //尋找成功返回
if(R[mid].kdy>K)
high=mid-1; //繼續在R[low..mid-1]中尋找
else
low=mid+1; //繼續在R[mid+1..high]中尋找
}
return 0; //當low>high時表示尋找區間為空白,尋找失敗
} //BinSeareh
二分尋找演算法亦很容易給出其遞迴程式【參見練習】
4、二分尋找演算法的執行過程
設演算法的輸入執行個體中有序的關鍵字序列為
(05,13,19,21,37,56,64,75,80,88,92)
要尋找的關鍵字K分別是21和85。具體尋找過程【參見動畫示範】
5、二分尋找判定樹
二分尋找過程可用二叉樹來描述:把當前尋找區間的中間位置上的結點作為根,左子表和右子表中的結點分別作為根的左子樹和右子樹。由此得到的二叉樹,稱為描述二分尋找的判定樹(Decision Tree)或比較樹(Comparison Tree)。
注意:
判定樹的形態只與表結點個數n相關,而與輸入執行個體中R[1..n].keys的取值無關。
【例】具有11個結點的有序表可用所示的判定樹來表示。
(1)二分尋找判定樹的組成
①圓結點即樹中的內部結點。樹中圓結點內的數字表示該結點在有序表中的位置。
②外部結點:圓結點中的所有null 指標均用一個虛擬方形結點來取代,即外部結點。
③樹中某結點i與其左(右)孩子串連的左(右)分支上的標記"<"、"("、">"、")"表示:當待查關鍵字K<R[i].key(K>R[i].key)時,應走左(右)分支到達i的左(右)孩子,將該孩子的關鍵字進一步和K比較。若相等,則尋找過程結束返回,否則繼續將K與樹中更下一層的結點比較。
(2)二分尋找判定樹的尋找
二分尋找就是將給定值K與二分尋找判定樹的根結點的關鍵字進行比較。若相等,成功。否則若小於根結點的關鍵字,到左子樹中尋找。若大於根結點的關鍵字,則到右子樹中尋找。
【例】對於有11個結點的表,若尋找的結點是表中第6個結點,則只需進行一次比較;若尋找的結點是表中第3或第9個結點,則需進行二次比較;找第1,4,7,10個結點需要比較三次;找到第2,5,8,11個結點需要比較四次。
由此可見,成功的二分尋找過程恰好是走了一條從判定樹的根到被查結點的路徑,經曆比較的關鍵字次數恰為該結點在樹中的層數。若尋找失敗,則其比較過程是經曆了一條從判定樹根到某個外部結點的路徑,所需的關鍵字比較次數是該路徑上內部結點的總數。
【例】待查表的關鍵字序列為:(05,13,19,21,37,56,64,75,80,88,92),若要尋找K=85的記錄,所經過的內部結點為6、9、10,最後到達方形結點"9-10",其比較次數為3。
實際上方形結點中"i-i+1"的含意為被尋找值K是介於R[i].key和R[i+1].key之間的,即R[i].key<K<R[i+1].key。
(3)二分尋找的平均尋找長度
設內部結點的總數為n=2h-1,則判定樹是深度為h=lg(n+1)的滿二叉樹(深度h不計外部結點)。樹中第k層上的結點個數為2k-1,尋找它們所需的比較次數是k。因此在等機率假設下,二分尋找成功時的平均尋找長度為:
ASLbn≈lg(n+1)-1
二分尋找在尋找失敗時所需比較的關鍵字個數不超過判定樹的深度,在最壞情況下尋找成功的比較次數也不超過判定樹的深度。即為:
二分尋找的最壞效能和平均效能相當接近。
6、二分尋找的優點和缺點
雖然二分尋找的效率高,但是要將表按關鍵字排序。而排序本身是一種很費時的運算。既使採用高效率的排序方法也要花費O(nlgn)的時間。
二分尋找只適用順序儲存結構。為保持表的有序性,在順序結構裡插入和刪除都必須移動大量的結點。因此,二分尋找特別適用於那種一經建立就很少改動、而又經常需要尋找的線性表。
對那些尋找少而又經常需要改動的線性表,可採用鏈表作儲存結構,進行順序尋找。鏈表上無法實現二分尋找。
轉:線性表的尋找-二分尋找