二分查詢法過程詳解

2021-09-19 16:39:48 字數 2715 閱讀 1062

現在我們來玩乙個猜數的遊戲,假設有乙個人要我們猜0-99之間的乙個數。那麼最好的方法就是從0-99的中間數49開始猜。如果要猜的數小於49,就猜24(0-48的中間數);如果要猜的數大於49,就猜74(50-99的中間數)。重複這個過程來縮小猜測的範圍,直到猜出正確的數字。二分查詢的工作方法類似於此。

二分查詢操作的資料集是乙個有序的資料集。開始時,先找出有序集合中間的那個元素。如果此元素比要查詢的元素大,就接著在較小的乙個半區進行查詢;反之,如果此元素比要找的元素小,就在較大的乙個半區進行查詢。在每個更小的資料集中重複這個查詢過程,直到找到要查詢的元素或者資料集不能再分割。

二分查詢能應用於任何型別的資料,只要能將這些資料按照某種規則進行排序。然而,正因為它依賴於乙個有序的集合,這使得它在處理那些頻繁插入和刪除操作的資料集時不太高效。這是因為,對於插入和操作來說,為了保證查詢過程正常進行,必須保證資料集始終有序。相對於查詢來說,維護乙個有序資料集的代價更高。此外,元素必須儲存在連續的空間中。因此,當待搜尋的集合是相對靜態的資料集時,此時使用二分查詢是最好的選擇。

二分查詢的介面定義

bisearch

int bisearch(void *sorted, void *target, int size, int esize, int (compare *)(const void *key1, const void *key2);

返回值:如果查詢成功返回目標的索引值;否則返回-1。

描述:利用二分查詢定位有序元素陣列sorted中target。陣列中的元素個數由size決定,每個元素的大小由esize決定。函式指標compare指向乙個使用者自定義的比較函式。如果key1大於key2,函式返回1,如果key1=key2,函式返回0,如果key1小於key2,函式返回-1。

複雜度:o(lg n),n為要查詢的元素個數。

二分查詢的實現與分析

二分查詢法實質上是不斷地將有序資料集進行對半分割,並檢查每個分割槽的中間元素。在以下介紹的實現方法中,有序資料集存放在sorted中,sorted是一塊連續的儲存空間。引數target是要查詢的資料。

此實現過程的實施是通過變數left和right控制乙個迴圈來查詢元素(其中left和right是正在查詢的資料集的兩個邊界值)。首先,將left和right分別設定為0和size-1。在迴圈的每次迭代過程中,將middle設定為left和right之間區域的中間值。如果處於middle的元素比目標值小,將左索引值移動到middle後的乙個元素的位置上。即下一組要搜尋的區域是當前資料集的上半區。如果處於middle的元素比目標元素大,將右索引值移動到middle前乙個元素的位置上。即下一組要搜尋的區域是當前資料集的下半區。隨著搜尋的不斷進行,left從左向右移,right從右向左移。一旦在middle處找到目標,查詢將停止;如果沒有找到目標,left和right將重合

二分查詢的時間複雜度取決於查詢過程中分割槽數可能的最大值。對於乙個有n個元素的資料集來說,最多可以進行lg n次分割槽。對於二分查詢,這表示最終可能在最壞的情況下執行的檢查的次數:例如,在沒有找到目標時。所以二分查詢的時間複雜度為o(lg n)。

示例:二分查詢的實現

複製**

#include

#include

#include 「search.h」

/bisearch 二分查詢函式/

int bisearch(void *sorted, const void *target, int size, int esize,

int (*compare)(const void *key1, const void key2))

}/*目標未找到,返回-1*/

return -1;}

複製**

二分查詢的例子:拼寫檢查器

拼寫檢查器在各種各樣的文件中已經成為一種預設的工具。從計算機的角度來看,乙個基本的拼寫檢查器的工作原理就是簡單地將文字字串中的單詞與字典中的單詞進行比對。字典包含可接受的單詞集合。

在些介紹的乙個例子,它包含乙個函式spell。spell一次檢查乙個文字字串中的單詞。它接受三個引數:dictionary是乙個可接受的有序字串陣列;size是字典中字串的個數;word是將要被檢查的單詞。此函式呼叫bisearch在dictionary中查詢word。如果單詞找到,那麼拼寫正確。

函式spell的時間複雜度為o(lg n),與bisearch相同,其中n是dictionary中的單詞的個數。檢查整個文件的時間複雜度是o(m lg n),m是文件中要檢查的單詞個數。

示例:拼寫檢查器的標頭檔案

複製**

/spell.h/

#ifdef spell_h

#define spell_h

/定義字典單詞的最大位元組數/

#define spell_size 31

/公共介面/

int spell(char(*dictionary)[spell_size],int size, const char *word);

#endif // spell_h

複製**

示例:拼寫檢查器的實現

複製**

#include

#include 「search.h」

#include 「spell.h」

/字義字串比較函式/

static int compare_str(const void str1, const void str2)

/spell 函式/

int spell(char(*dictionary)[spell_size],int size,const void *word)

二分查詢法(STL)詳解

二分查詢也稱折半查詢 binary search 它是一種效率較高的查詢方法。二分查詢要求 線性表是有序表,即表中結點按關鍵字有序,並且要用向量作為表的儲存結構。不妨設有序表是遞增有序的。查詢過程 首先,假設表中元素是按公升序排列,將表中間位置記錄的關鍵字與查詢關鍵字比較,如果兩者相等,則查詢成功 ...

二分查詢法

二分查詢要求 1.必須採用順序儲存結構 2.必須按關鍵字大小有序排列。優缺點 折半查詢法的優點是比較次數少,查詢速度快,平均效能好 其缺點是要求待查表為有序表,且插入刪除困難。因此,折半查詢方法適用於不經常變動而查詢頻繁的有序列表。演算法思想 首先,將表中間位置記錄的關鍵字與查詢關鍵字比較,如果兩者...

二分查詢法

有序陣列中的find 方法 public int find long serchkey int lowerbound 0 int upperbound nelems 1 while true curin lowerbound upperbound 2 if a curin serchkey retu...