二分查詢(binary search)的思想非常簡單,但看似越簡單的東西往往越難掌握好,想要靈活運用就更加困難。生活中二分查詢的思想無處不在。乙個最常見的就是猜數遊戲,我隨機寫乙個 0 到 99 的數,然後你來猜我寫的是什麼。猜的過程中,我會告訴你每次是猜大了還是猜小了,直到猜中為止。假如我寫的數是 23,猜數過程如下所示。
最多隻需要 7 次就猜出來了,這個過程是很快的。同理,要查詢某個資料是否在給定的陣列中,我們同樣也可以利用這個思想。
二分查詢針對的是乙個有序的資料集合,查詢思想有點類似於分治,每次都通過和中間元素進行比較,將待查詢區間縮小為之前的一半,直到找到要查詢的元素或者區間縮小為 0 為止。
我們假設資料大小為 n,每次查詢資料大小都會縮小為原來的一半,最壞情況下,直到查詢區間縮小為空時停止查詢。
若經過 k 次區間縮小最後變為空,則
這種對數時間複雜度的演算法是一種非常高效的演算法,有時候甚至比時間複雜度為常量級的演算法還要高效。因為常量級的時間複雜度對應的常數可能非常大,比如 o(100), o(1000),因此這些演算法有時候可能還沒有
迴圈法
float
binary_search
(float data, int left, int right, float value)
else
if (value < data[mid])
else
}return
-1;}
複製**
遞迴法
float
binary_search
(float data, int left, int right, float value)
else
if (value < data[mid])
else
}return
-1;}
複製**
注意事項
二分查 找依賴的是順序表結構,也就是陣列,需要能夠按照下標隨機訪問元素。
二分查詢針對的是有序資料,如果資料無序,需要先進行排序。而如果有頻繁的插入、刪除操作,則每次查詢前都需要再次排序,這時候,二分查詢將不再適用。
資料量太小可以直接遍歷查詢,沒有必要用二分查詢。但如果資料之間的比較操作非常耗時,比如資料為長度超過 300 的字串,則不管資料量大小,都推薦使用二分查詢。
而如果資料量過大,則意味著我們需要用非常大的連續記憶體空間來儲存這些資料,記憶體開銷可能無法滿足。
資料結構和演算法之 二分查詢下
最簡單的二分查詢情況下,我們假設陣列中沒有重複元素,因此很容易實現。如果陣列中存在重複元素,二分查詢就沒有想象中那麼容易了。如果資料中存在相同的元素,但我們要查詢第乙個值等於給定值的元素,如果直接用最簡單的二分查詢,顯然是不滿足的。看下面的例子,有 3 個等於 8 的元素,簡單二分查詢會返回 7,但...
資料結構和演算法之 二分查詢下
最簡單的二分查詢情況下,我們假設陣列中沒有重複元素,因此很容易實現。如果陣列中存在重複元素,二分查詢就沒有想象中那麼容易了。如果資料中存在相同的元素,但我們要查詢第乙個值等於給定值的元素,如果直接用最簡單的二分查詢,顯然是不滿足的。看下面的例子,有 3 個等於 8 的元素,簡單二分查詢會返回 7,但...
資料結構之二分查詢
二分查詢又稱折半查詢,優點是比較次數少,查詢速度快,平均效能好 其 缺點是要求待查表為有序表,且插入刪除困難。因此,折半查詢方法適用於不經常變動而查詢頻繁的有序列表。首先,假設表中元素是按公升序排列,將表中間位置記錄的 關鍵字與查詢關鍵字比較,如果兩者相等,則查詢成功 否則利用中間位置 記錄將表分成...