二分查找
最近写一些程序的时候发现对二分查找还不是很熟练,所以整理了一下,统一了一下格式。
例如区间取左闭右闭,做除法时向左偏(保证不会出现死循环),以下是一些常见情况。
#include<bits/stdc++.h> using namespace std; int a[1005]; //递增序列第一个大于t的下标 int bin1(int l, int r, int t) //区间左闭右开,第一个大于t的值,若没有返回r+1。 { while (l < r) { int mid = (l + r) / 2; //计算结果向左偏,由于l会更新,而r可能不会更新陷入死循环 if (a[mid] <= t) { l = mid + 1; } else { r = mid; } } if (a[l] <= t) l++; //特判特殊情况 return l; } //递增序列第一个大于等于t的下标 int bin2(int l, int r, int t) //区间左闭右开,第一个大于t的值,若没有返回r+1。 { while (l < r) { int mid = (l + r) / 2; //计算结果向左偏,由于l会更新,而r可能不会更新陷入死循环 if (a[mid] < t) { l = mid + 1; } else { r = mid; } } if (a[l] < t) l++; //特判特殊情况 return l; } //递减序列第一个小于t的下标 int bin3(int l, int r, int t) //区间左闭右开,第一个大于t的值,若没有返回r+1。 { while (l < r) { int mid = (l + r) / 2; //计算结果向左偏,由于l会更新,而r可能不会更新陷入死循环 if (a[mid] >= t) { l = mid + 1; } else { r = mid; } } if (a[l] >= t) l++; //特判特殊情况 return l; } //递减序列第一个小于等于t的下标 int bin4(int l, int r, int t) //区间左闭右开,第一个大于t的值,若没有返回r+1。 { while (l < r) { int mid = (l + r) / 2; //计算结果向左偏,由于l会更新,而r可能不会更新陷入死循环 if (a[mid] > t) { l = mid + 1; } else { r = mid; } } if (a[l] > t) l++; //特判特殊情况 return l; } int main() { int n = 0, u = 0; cin >> n; for (int i = 1; i <= n; i++) cin >> a[i]; cin >> u; cout << bin1(1, n, u) << endl; cout << bin2(1, n, u) << endl; //cout << bin3(1, n, u) << endl; //cout << bin4(1, n, u) << endl; return 0; }

浙公网安备 33010602011771号