【演算法筆記】二分法的使用(使用目的+模板)
阿新 • • 發佈:2018-12-21
今天看完《演算法筆記》裡二分法這個章節,稍微總結一下。
二分法的思想主要就是折半查詢,達到O(logn)的查詢速度。
使用目的或者說使用情景主要有如下三個,下面將依次介紹。
- 查詢有序序列中是否存在滿足條件的元素
- 查詢有序序列中滿足條件的第一個元素
- 對一些函式進行求根(近似)計算
1. 查詢有序序列中是否存在滿足條件的元素
下面的函式是找到a[]陣列中是否有等於x的元素,如果有返回索引下標,如果沒有則返回-1。
要注意二分的使用條件是序列有序,下面程式碼中的判斷條件可以根據使用需求進行修改。
對於一些下標快達到int上限的搜尋區間時,可以把
mid = (left + right) / 2;
替換為
mid = left + (right - left) / 2;
int binary_search(int a[], int left, int right, int x) { int mid; while (left < right) { mid = (left+right) / 2; if (a[mid] == x) return mid; if (a[mid] > x) { // 可以根據具體使用需求修改條件 right = mid - 1; } else { left = mid + 1; } } return -1; }
2.查詢有序序列中滿足條件的第一個元素
下面的函式是找到a[]陣列中等於x的第一個元素的索引下標。
同樣的,程式碼中的判斷條件可以根據使用需求進行修改。
int binary_search(int a[], int left, int right, int x) { int mid; while (left < right) { mid = (left+right) / 2; if (a[mid] >= x) { // 條件可以根據需求進行修改 right = mid; } else { left = mid + 1; } } return left; }
3.對一些函式進行求根(近似)計算(求根號2近似值為例)
const int eps = 1e-5; // 求根精度為1e-5
double f(double x) {
return x*x-2;
}
int solve(double L, double R) { // L R為求根區間
int l = L, r = R, mid = (l + r) / 2;
while (r - l < eps) {
mid = (l + r) / 2;
if (f(mid) > 0) {
r = mid;
}
else {
l = mid;
}
}
return mid;
}