二分查找(英語:binary search),也稱折半搜索(英語:half-interval search)對數搜索(英語:logarithmic search,是一種在有序數組中查找某一特定元素的搜索算法。搜索過程從數組的中間元素開始,如果中間元素正好是要查找的元素,則搜索過程結束;如果某一特定元素大於或者小於中間元素,則在數組大於或小於中間元素的那一半中查找,而且跟開始一樣從中間元素開始比較。如果在某一步驟數組爲空,則代表找不到。這種搜索算法每一次比較都使搜索範圍縮小一半。
適合的場景:
- Sorted(單調遞增或者遞減)
- Bounded (存在上下界,因爲要一分爲二的進行查找)
- Accessible by index(能夠通過索引訪問)
時間複雜度:
- O(logN)
空間複雜度:
- O(N) 使用常數空間,無論任何大小的輸入數據,算法使用的空間都是一樣的
適用的數據結構:
數組,因爲在內存中時連續的適合使用二分查找。但是鏈表不適合,因爲鏈表座標不是固定的,訪問a[2]需要先從a[0]的後繼節點找到a[1]再通過a[1]的後繼節點才能訪問到a[2]。
步驟:
- 初始狀態left、right 分別指向數組的頭和尾。
- 通過(left + right) /2 得到中間位置mid,訪問數組中mid位置的元素。
- 判斷其與查找目標的大小關係,相等則程序返回,
- 比目標小則挪動left指針到mid + 1;比目標大則挪動right指針到mid - 1
- 重複上面步驟2 ~ 3直到找到目標元素或者程序退出。
代碼實現:
<?php
$list = [1, 2, 5, 6, 8, 9, 12, 15, 23, 32, 56, 67, 73, 85];
function bioSearch($list, $target)
{
$left = 0;
$right = count($list) - 1;
while ($left <= $right) {
$mid = ($left + $right) / 2;
if ($list[$mid] == $target) {
return true;
} else if ($list[$mid] < $target) {
$left = $mid + 1;
continue;
} else {
$right = $mid - 1;
continue;
}
}
return false;
}