二分查找函数
写一个函数BinarySearch,在包含size个元素的、从小到大排序的int数组a里查找元素p,如果找到则返回元素下标,如果找不到,则返回-1.
int BinarySearch(int a[],int size,int p) { int L=0;//查找区间的左端点 int R=size-1;//查找区间的右端点 while(L<=R)//如果区间不为空就继续查找 { int mid=L+(R-L)/2;//取查找区间正中元素的下标 if(p==a[mid]) return mid; else if(p>a[mid]) L=mid+1;//设置新的查找区间的左端点 else R=mid-1;//设置新的查找区间的右端点 } return -1; }写一个函数LowerBound,在包含size个元素的、从小到大排序的int数组a里查找比给定整数p小的,下标最大的元素。找到则返回其下标,找不到则返回-1.
#include<iostream> using namespace std; int LowerBound(int a[], int size, int p) { int L = 0; int R = size - 1; int lastPos = -1; while (L < R){ int mid = L + (R - L) / 2; if (a[mid] >= p) R = mid - 1; else { lastPos = mid; L = mid + 1; } } return lastPos; } int main() { int a[5], p; cout << "please enter 5 numbers:" << endl; for (int i = 0; i < 5; i++) cin >> a[i]; cout << "please enter p:" << endl; cin >> p; cout<<LowerBound(a, 5, p)<<endl; return 0; }
注意:int mid=(L+R)/2;
为了防止(L+R)过大溢出:int mid=L+(R-L)/2;
例 二分法求方程的根
代码实现
#include<iostream> #include<cmath> #include<cstdlib> using namespace std; double EPS = 1e-6; double f(double x){ return x*x*x - 5 * x*x + 10 * x - 80; } int main() { double root, x1 = 0, x2 = 100, y; root = x1 + (x2 - x1) / 2; int triedTimes = 1;//记录一共尝试多少次 y = f(root); while (fabs(y) > EPS) { if (y > 0) x2 = root; else x1 = root; root = x1 + (x2 - x1) / 2; y = f(root); triedTimes++; } printf("%.8f\n", root);//关于该函数的相关定义 http://www.cplusplus.com/reference/cstdio/printf/?kw=printf printf("%d", triedTimes); return 0; }
例 找一对数
下面编了个包含10个元素的程序:
代码实现
#include<iostream> #include<algorithm> using namespace std; int main() { int a[10] = { 11, 15, 16, 23, 2, 1, 0, 35, 64, 94 },m; cout << "please enter m:" << endl; cin >> m; sort(a, a + 10);//调用库函数sort(start,end,排序方法) int i = 0, j = 9; while (a[i] + a[j] != m) { if (a[i] + a[j] < m) i++; else j--; } cout << a[i] << " " << a[j]; return 0; }