二分法:也称折半查找(Binary Search),折半查找要求线性表必须采用顺序的存储结构,而且表中元素关键字有序排列。
首先判断a(n/2)和x谁大谁小,如果x大的话,那么x可能在a(n/2+1)到a(n)这个区间里,而一定不会再a(1)到a(n/2)这个范围内,因为是数组是递增的。然后再按同样的方法查找后半个区间即可。这样的时间复杂度是O(logn)
bool find(int A[],int N,int x){
int L=0,R = N-1,M;//left right middle
while(R>L){
M=(L+R)/2;
if(A[M]==x)return 1;//表示查找到了
else if(A[M]>x)R=M-1;
else L=M+1;
}//如果r==l的话循环就停了
if(A[L]==x)return 1;//如果执行这个判断语句说明L==R
return 0;
}
二分查找应用的对象满足某种单调性,可以是下标,也可以是元素。
典型的应用:最小化的问题(例如最大值尽可能小)。如果先给出一个上限M,要求所有数都不大于M,然后如果存在一种方案的话,说明最后的答案一定小于等于,。所以用二分法一次次去逼近答案即可!
三分法:三分查找对应的是双调函数,也就是求先增后减或者先减后增函数的极值。
图片见算法竞赛。。。
#define e 0.0001//根据题目需要的精确度来定量
double l,r,m,mm;
while(r-l>e){
m=(l+r)/2.0;
mm(m+r)/2.0;
if(f(m)>f(mm))l=m;
else r=mm;
}//先减后增