二分法 查詢 排序以及庫函式bsearch的用法

2021-05-24 21:27:16 字數 2892 閱讀 9316

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].key3、二分查詢演算法

int binsearch(seqlist r,keytype k)

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)二分查詢判定樹的組成

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

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

③樹中某結點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(3)二分查詢的平均查詢長度

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

aslbn≈lg(n+1)-1

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

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

6、二分查詢的優點和缺點

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

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

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

#include

#include

void twoinsertsort(int array,int n)

for( j = i-1;j >= left;j-- )// 後移排序碼大於r[i]的記錄

array[j+1] = array[j];

array[left] = num;// 插入}}

int rcmp( const int *a, const int *b)

void main() 

twoinsertsort(array,sizeof(array)/sizeof(int));//二分法排序

printf("/nafter sorted :/n");

for( i=0; i<50; i++ )

printf("array[%d]:%d/n", i, array[i]);

//庫函式bsearch用二分法查詢乙個有序陣列中的乙個特定數,並返回該數的位址

a = (int *)bsearch(&b, numarray, sizeof(numarray)/sizeof(numarray[0]), sizeof(int),rcmp);

C 二分法查詢,遞迴二分法

用二分法來求需要查詢的值.includeusing namespace std 查詢key元素是否存在 int findkey const int buf 100 const int ilen,const int key else right left mid 1 查詢失敗 return 1 查詢k...

python二分法查詢 Python 二分法查詢

二分法查詢主要的作用就是查詢元素 lst 1,3,5,7,12,36,68,79 資料集 百萬級資料 num int input 請輸入你要查詢的元素資訊 for el in lst if num el print 存在 break else print 不存在 len lst 0 1 2 3 4 ...

二分法查詢

前幾天csdn上說只有10 程式設計師能寫出正確的二分法查詢 so.我在看過二分法查詢方法後寫了乙個 一次測試成功.範圍 需要次數 10 4 100 7 1000 10 10000 14 100000 17 1000000 20 除了對特別小的陣列外,二分法查詢表現是非常優秀的.每次對範圍加倍可以建...