算法 | 二分查找
1. 简介
将一个有序数组一分为二,将查找的数据与切分点比较,在哪一块区间。在将所在区间一分为二,将查找的数据与切分点比较,在哪一块区间…
三种情况:
- 查找数据与切分点相等直接返回索引。
- 查找数据大于切分点,按切分点右侧继续查找。
- 查找数据小于切分点,按切分点左侧继续查找。
优点:查找速度快
缺点:数据必须有序
2. 图示
3. 示例
3.1. 循环版本
#include <iostream>
using namespace std;
// 二分查找
// 如果返回值为-1表示不存在,其他返回值表示目标在数据中的索引。
int binarySearch(const int arr[], int length, int target) {
int low = 0;
int high = length - 1;
while (low < high) {
int mid = (low + high) / 2; // 提示: 数轴上2点的中点=2点值相加除2
int v = arr[mid];
if (v == target) {
return mid;
} else if (v < target) {
low = mid + 1;
} else {
high = mid - 1;
}
}
return -1;
}
int main() {
int arr[] = {1, 2, 3, 4, 5, 6};
int index = binarySearch(arr, 6, 3);
cout << "index = " << index << endl;
}
3.2. 递归版本
#include <iostream>
using namespace std;
int binarySearch(int arr[], int length, int target);
int bSearch(int arr[], int target, int low, int high);
// 二分查找
// 如果返回值为-1表示不存在,其他返回值表示目标在数据中的索引。
int binarySearch(int arr[], int length, int target) {
return bSearch(arr, target, 0, length - 1);
}
// 二分查找逻辑实现
int bSearch(int arr[], int target, int low, int high) {
if (low > high) {
return -1;
}
int mid = (low + high) / 2; // 提示: 数轴上2点的中点=2点值相加除2
int v = arr[mid];
if (v == target) {
return mid;
} else if (v < target) {
return bSearch(arr, target, mid + 1, high);
} else {
return bSearch(arr, target, low, mid - 1);
}
}
int main() {
int arr[] = {1, 2, 3, 4, 5, 6};
int index = binarySearch(arr, 6, 3);
cout << "index = " << index << endl;
}
4. 参考
- 《C/C++函数与算法速查手册》