Binary search
Example: A thinks a number between 1-1000 in his mind, B guesses it, can ask questions, A can only answer yes or no. How to guess the least number of questions?
- Sequential search: Is it 1? Is it 2?… Is it 999? Ask 500 times on average
- Binary search: Is it greater than 500? Is it greater than 750? Is it greater than 625?… It only takes 10 times to reduce the guess range to half of the last time
- The content of binary search must be in order.
Example 1: Write a function BinarySeach to find the element p in an int array a containing size elements, sorted from small to large, if found, return the element index, if not found, return -1. Requires complexity O(log(n)).
Code:
int BinarySeach(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]) //说明p在a[]的左半部
L = mid + 1; //重置查找区间的左端点
else
R = mid - 1; // 重置查找区间的右端点
}
return -1;
}
Example 2: Write a function LowerBound to find the element with the largest subscript that is smaller than the given integer p in the int array a containing size elements and sorted from small to large. If found, return its subscript, if not found, return -1.
Code:
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;
}
Note:
int mid = (L+R)/2;
//取查找区间正中元素的下标
To prevent (L+R) from overflowing too much:
int mid = L+(R-L) /2;
Example 3: Finding the roots of the equation by dichotomy Find a root of the
following equation: f(x) = x 3 -5x 2 +10x-80 = 0; If the root to be found is a, then |f(a)|< = 10 -6 .
Solution: Take the derivative of f(x) and get f'(x)=3x 2 -10x+10. The formula for finding the roots of a quadratic equation in one variable knows that the equation f'(x) = 0 has no solution, so f'(x) is always greater than 0. Therefore, f(x) is monotonically increasing. It is easy to know that f(0) <0 and f(100)>0, so there must be one and only one root in the interval [0, 100]. Since f(x) is monotonic in [0, 100], we can find the root in the interval [0, 100] by using a bisection method.
Code
#include <iostream>
#include <cmath>
#include <cstdio>
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("%.08f\n",root);
printf("%d",triedTimes);
return 0;
}