二分查詢binarySearch

2021-08-10 17:32:02 字數 2380 閱讀 2186

二分查詢又稱折半查詢,它是一種效率較高的查詢方法。

二分查詢要求:線性表是有序表,即表中結點按關鍵字有序,並且要用向量作為表的儲存結構。不妨設有序表是遞增有序的。

二分查詢的基本思想是:

設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

因此,從初始的查詢區間r[1..n]開始,每經過一次與當前查詢區間的中點位置上的結點關鍵字的比較,就可確定查詢是否成功,不成功則當前的查詢區間就縮小一半。這一過程重複直至找到關鍵字為k的結點,或者直至當前的查詢區間為空(即查詢失敗)時為止。

二分查詢只適用順序儲存結構。

int binary_search(int a*,int n,int key)

return 0;}

也可以如下構造引數:

return 0;

//當low>high時表示查詢區間為空,查詢失敗}

①  執行過程 

設演算法的輸入例項中有序的關鍵字序列為

拓展:

二分查詢判定樹

二分查詢過程可用二叉樹來描述:把當前查詢區間的中間位置上的結點作為根,左子表和右子表中的結點分別作為根的左子樹和右子樹。由此得到的二叉樹,稱為描述二分查詢的判定樹(decision tree)或比較樹(comparison tree)。

注意:判定樹的形態只與表結點個數n相關,而與輸入例項中r[1..n].keys的取值無關。

(1)二分查詢判定樹的組成

①圓結點即樹中的內部結點。樹中圓結點內的數字表示該結點在有序表中的位置。

②外部結點:圓結點中的所有空指標均用乙個虛擬的方形結點來取代,即外部結點。

③樹中某結點i與其左(右)孩子連線的左(右)分支上的標記""、")"表示:當待查關鍵字kr[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

② 二分查詢的平均查詢長度

設內部結點的總數為n=2h-1,則判定樹是深度為h=lg(n+1)的滿二叉樹(深度h不計外部結點)。樹中第k層上的結點個數為2k-1,查詢它們所需的比較次數是k。因此在等概率假設下,二分查詢成功時的平均查詢長度為:

aslbn≈lg(n+1)-1

二分查詢在查詢失敗時所需比較的關鍵字個數不超過判定樹的深度,在最壞情況下查詢成功的比較次數也不超過判定樹的深度。即為:

二分查詢的最壞效能和平均效能相當接近。

③二分查詢的優點

折半查詢的時間複雜度為o(logn),遠遠好於順序查詢的o(n)。

④  二分查詢的缺點

雖然二分查詢的效率高,但是要將表按關鍵字排序。而排序本身是一種很費時的運算。既使採用高效率的排序方法也要花費o(nlgn)的時間。

⑤ 適用情況

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

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

STL中的二分查詢(binary search)

stl中對於有序序列 vector,list等 提供了相當相當強大的二分搜尋binary search演算法。對於可以隨機訪問容器 如vector等 binary search負載度為對數級別 logn 對於非隨機訪問容器 如list 則演算法複雜度為線性。現在簡要介紹一下幾種常用的binary s...

迭代二分查詢二分查詢

在寫這篇文章之前,已經寫過了幾篇關於改迭代二分查詢主題的文章,想要了解的朋友可以去翻一下之前的文章 bentley在他的著作 writing correct programs 中寫道,90 的計算機專家不能在2小時內寫出完整確正的二分搜尋演算法。難怪有人說,二分查詢道理單簡,甚至小學生都能明確。不過...

1128 二分 二分查詢

時間限制 10000ms 單點時限 1000ms 記憶體限制 256mb 描述nettle最近在玩 艦 因此nettle收集了很多很多的船 這裡我們假設nettle氪了很多金,開了無數個船位 去除掉重複的船之後,還剩下n 1 n 1,000,000 種不同的船。每一艘船有乙個稀有值,任意兩艘船的稀有...