折半查詢(binary search)技術,又稱為二分查詢。它的前提是線性表中的記錄必須是關鍵碼有序(通常從小到大有序),線性表必須採用順序儲存。折半查詢的基本思想是:在有序表中,取中間記錄作為比較物件,若給定值與中間記錄的關鍵字相等,則查詢成功;若給定值小於中間記錄的關鍵字,則在中間記錄的左半區繼續查詢;若給定值大於中間記錄的關鍵字,則在中間記錄的右半區繼續查詢。不斷重複上述過程,直到查詢成功,或所有查詢區域無記錄,查詢失敗為止。乙個有序表陣列,除0下標外共10個數字。對它進行查詢是否存在62這個數。折半查詢演算法如下所示:
/*折半查詢*/
int binary_search(int *a,int n,int key)
return
0;}
上述**的具體執行流程1.程式開始執行,引數a=,n=10,key=62,第3~5行,此時low=1,high=10,如下圖所示:
2.6~15行迴圈,進行查詢
3.第8行,mid計算得到5,由於a[5]=47 < key,所以執行了第12行,low=5+1=6,如下圖所示:
4.再次迴圈,mid=(6+10)/2=8,此時a[8]=73>key,所以執行第10行,high=8-1=7,如下圖所示:
5.再次迴圈,mid=(6+7)/2=6,此時a[6]=59 < key,所以執行12行,low=6+1=7,如下圖所示:
6.再次迴圈,mid=(7+7)/2=7,此時a[7]=62=key,查詢成功,返回7。
實現的目錄結構
折半查詢類
package com.red.binary.search;
public
class
binarysearch else
if(arr[middle] > key) else
}return -1;}}
測試類package com.red.binary.search;
public
class
binarysearchtest ;
binarysearch bs = new binarysearch();
int search = bs.binarysearch(arr, 62);
system.out.println("key所在位置:" + search);}}
輸出結果key所在位置:6
該演算法的效率非常高,但到底高多少?關鍵在於此演算法的時間複雜度分析。首先,我們將這個陣列的查詢過程繪製成一棵二叉樹,如下圖所示,從圖上就可以理解,如果查詢的關鍵字不是中間記錄47的話,折半查詢等於是把靜態有序查詢表分成了兩棵子樹,即查詢結果只需要找其中的一半資料記錄即可,等於工作量少了一半,然後繼續折半查詢,效率當然是非常高了。
根據二叉樹的性質,具有n個結點的完全二叉樹的深度為
⌊log2n
⌋+1 。在這裡儘管折半查詢判定二叉樹並不是完全二叉樹,但同樣可以得出,最壞情況是查詢到關鍵字或查詢失敗的此時為
⌊log2n
⌋+1 。因此最終我們折半查詢演算法的時間複雜度為o(logn),它顯然遠遠好於順序查詢的o(n)時間複雜度了。
不過由於折半查詢的前提條件是需要有序表順序儲存,對於靜態查詢表,一次排序後不再變化,這樣的演算法已經比較好了。但對於需要頻繁執行插入或刪除操作的資料集來說,維護有序的排序會帶來不小的工作量,那就不建議使用。
二分查詢(折半查詢)
二分查詢 折半查詢 從有序序列中找到給出的要查詢的數字。原理是 首先把乙個有序序列中間位置的值與要查詢的數比較,若相等則找到了有序序列中的此數 否則比較兩者的大小,若前者大,則把有序序列的中間位置以前的元素都去掉,餘下的元素組成乙個新的有序數列繼續上一步的操作,直到找到為止 若後者大,則把有序數列中...
折半查詢(二分查詢)
折半查詢 又稱二分查詢,優點是比較次數少,查詢速度快,平均效能好 其缺點是要求待查表為有序表,且插入刪除困難。因此,折半查詢方法適用於不經常變動而查詢頻繁的有 序列表。首先,假設表中元素是按公升序排列,將表中間位置記錄的關鍵字與查詢關鍵字比較,如果兩者相等,則查詢成功 否則利用中間位置記錄將表分成前...
二分查詢(折半查詢)
時間限制 3000 ms 記憶體限制 65535 kb難度 3描述 在某一國度裡流行著一種遊戲。遊戲規則為 在一堆球中,每個球上都有乙個整數編號i 0 i 100000000 編號可重複,現在說乙個隨機整數k 0 k 100000100 判斷編號為k的球是否在這堆球中 存在為 yes 否則為 no ...