折半查找 要求數據已排序,每次將搜索範圍減半,時間複雜度 O(log n),遠優於線性查找 O(n)。
int binary_search(const int arr[], int n, int target) {
int low = 0, high = n - 1;
while (low <= high) {
int mid = low + (high - low) / 2; // 防止 (low+high) 溢出
if (arr[mid] == target) return mid;
else if (arr[mid] < target) low = mid + 1;
else high = mid - 1;
}
return -1; // 未找到
}
int binary_search_rec(const int arr[], int low, int high, int target) {
if (low > high) return -1;
int mid = low + (high - low) / 2;
if (arr[mid] == target) return mid;
if (arr[mid] < target) return binary_search_rec(arr, mid + 1, high, target);
return binary_search_rec(arr, low, mid - 1, target);
}
int main() {
int arr[] = {2, 5, 8, 12, 16, 23, 38, 56, 72, 91}; // 已排序
int n = sizeof(arr) / sizeof(arr[0]);
int target = 23;
int idx = binary_search(arr, n, target);
if (idx != -1)
printf("找到 %d 於索引 %d\n", target, idx); // 索引 5
else
printf("未找到\n");
return 0;
}
| 場景 | 修改點 |
|---|---|
| 查找第一個 ≥ target (下界) | `arr[mid] >= target` 時 `high = mid - 1`,返回 `low` |
| 查找最後一個 ≤ target (上界) | `arr[mid] <= target` 時 `low = mid + 1`,返回 `high` |
| 查找第一次出現 (有重複) | 相等時 `high = mid - 1`,記錄候選答案 |
| 查找最後一次出現 | 相等時 `low = mid + 1`,記錄候選答案 |
| 浮點數數組 | 比較用 epsilon 範圍判斷相等 |
| 旋轉有序數組 | 判斷哪半有序,再決定去哪半 |
#include <stdlib.h>
// bsearch 通用二分查找,需提供比較函數
int cmp_int(const void *a, const void *b) {
return *(const int*)a - *(const int*)b;
}
int *found = bsearch(&target, arr, n, sizeof(int), cmp_int);