二分查找是一种在有序数组中高效查找目标值的算法。核心思想是:每次把搜索范围缩小一半,而不是一个一个地检查。
算法步骤:
left 和 right,分别指向数组的首尾mid = (left + right) / 2arr[mid] == target,找到啦!arr[mid] < target,目标在右半部分,令 left = mid + 1arr[mid] > target,目标在左半部分,令 right = mid - 1left > right,说明目标不在数组中时间复杂度:O(log n) — 即使有一百万个数,最多也只需要约 20 次比较!对比线性查找的 O(n) 快得多。
📝 关键行解释:
mid = left + (right - left) / 2 — 为什么不用 (left + right) / 2?因为两个大整数相加可能溢出!left + (right - left) / 2 效果一样但更安全。left <= right(有等号),漏掉等号会漏查最后一个元素!mid + 1 而不是 mid,否则当 left == right 时会死循环。while (left <= right),写成 left < right 会漏掉当 left == right 时的最后一次查找。
left = mid + 1,右边界用 right = mid - 1。如果写成 left = mid 或 right = mid,当只剩两个元素时会死循环!
(left + right) / 2 在 left 和 right 都很大时可能超出 int 范围。用 left + (right - left) / 2 或 left + (right - left) >> 1 更安全。
nums 和一个目标值 target。binarySearch 函数和 main 函数。#include <iostream>
using namespace std;
int binarySearch(int nums[], int n, int target) {
int left = 0, right = n - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (nums[mid] == target) return mid;
else if (nums[mid] < target) left = mid + 1;
else right = mid - 1;
}
return -1;
}
int main() {
int nums[] = {1, 3, 5, 7, 9, 11};
int n = 6, target = 7;
cout << binarySearch(nums, n, target) << endl; // 输出: 3
return 0;
}
left <= right 不能漏等号;mid 用防溢出写法;更新边界时 +1 / -1 不能省。