二分搜尋是查找有序陣列中目標值的高效演算法,時間複雜度 O(log n)。本文從邏輯推導、常見陷阱(死迴圈、索引越界)、完整 Java/PHP 實作三方面,帶你徹底掌握。
陣列必須已排序(升序),否則二分搜尋邏輯不成立。
int min = 0;
int max = arr.length - 1;
int mid = (min + max) / 2;
while (arr[mid] != key) {
if (key < arr[mid]) {
max = mid - 1; // 目標在左半部
} else { // arr[mid] < key
min = mid + 1; // 目標在右半部
}
mid = (min + max) / 2; // 重新計算中間
}
若目標不存在,min 會超過 max(錯位),必須加入終止條件:
while (arr[mid] != key) {
if (key < arr[mid]) {
max = mid - 1;
} else {
min = mid + 1;
}
if (min > max) return -1; // 找不到
mid = (min + max) / 2;
}
return mid;
public class BinarySearchDemo {
public static void main(String[] args) {
int[] arr = {1, 4, 6, 7, 8, 9};
System.out.println("線性搜尋 7 索引: " + linearSearch(arr, 7)); // 3
System.out.println("二分搜尋 7 索引: " + binarySearch(arr, 7)); // 3
System.out.println("二分搜尋 5 索引: " + binarySearch(arr, 5)); // -1
}
// 二分搜尋(回傳索引,找不到回傳 -1)
public static int binarySearch(int[] arr, int key) {
int min = 0, max = arr.length - 1, mid = (min + max) / 2;
while (arr[mid] != key) {
if (key < arr[mid]) max = mid - 1;
else min = mid + 1;
if (min > max) return -1;
mid = (min + max) / 2;
}
return mid;
}
// 線性搜尋(對照參考)
public static int linearSearch(int[] arr, int num) {
for (int i = 0; i < arr.length; i++) {
if (arr[i] == num) return i;
}
return -1;
}
}
<?php
class ArrayDemo {
public static function main() {
$arr = array(1, 4, 6, 7, 8, 9);
echo "線性搜尋 7 索引: " . self::linearSearch($arr, 7) . "\n"; // 3
echo "二分搜尋 7 索引: " . self::binarySearch($arr, 7) . "\n"; // 3
echo "二分搜尋 5 索引: " . self::binarySearch($arr, 5) . "\n"; // -1
}
public static function binarySearch($arr, $key) {
$min = 0; $max = count($arr) - 1; $mid = (int)(($min + $max) / 2);
while ($arr[$mid] != $key) {
if ($key < $arr[$mid]) $max = $mid - 1;
else $min = $mid + 1;
if ($min > $max) return -1;
$mid = (int)(($min + $max) / 2);
}
return $mid;
}
public static function linearSearch($arr, $key) {
for ($i = 0; $i < count($arr); $i++) {
if ($arr[$i] == $key) return $i;
}
return -1;
}
}
ArrayDemo::main();
?>
| 錯誤類型 | 錯誤寫法 | 正確寫法 | 原因 |
|---|---|---|---|
| 索引越界 | mid = (min+max)/2 溢位 | mid = min + (max-min)/2 | 大陣列 min+max 超過 int 最大值 |
| 死迴圈 | 缺少 min > max 判斷 | 迴圈內檢查並 return -1 | 目標不存在時 min/max 錯位 |
| 邊界錯誤 | max = mid 或 min = mid | max = mid-1 / min = mid+1 | 未排除已檢查的 mid,導致無限迴圈 |
| 未排序陣列 | 直接呼叫 | 先 Arrays.sort(arr) | 前提條件違反,結果不可預期 |
Arrays.binarySearch() 或 Collections.binarySearch(),經過嚴格測試並支援泛型、比較器。min 而非 -1。