二分法总结

二分法前提条件:在一个严格递增的序列中找出给定的数字X。

//传入的初值为[0,n-1] 
int binarySearch(int a[],int left,int right,int x){   //二分查找 
	int mid;
	while(left<=right){
		mid=(right+left)/2;
		if(a[mid]==x)return mid;
		else if(a[mid]<x)right=mid-1;
		else left=mid+1;
	}

return -1;  //查找不到	
}

注意:如果二分上届超过int数据范围的一半,mid=(right+left)/2的等价语句是:mid=left+(right-left)/2;

进一步探讨:求出序列中第一个大于等于X的元素的位置L以及第一个大于X的元素的位置R。

//函数返回第一个大于等于x的元素的位置 
int lower_bound(int a[],int left,int right,int x){   //传入的区间是[0,n]    
	int mid;
	while(left<right){
		mid=(left+right)/2;
        if(a[mid]>=x)right=mid;
		else left=mid+1;
	} 
	return left;
	
 } 

如果a[mid]>=x,说明第一个大于等于X的元素的位置一定在Mid处或mid的左侧,应该往左子区间[left,right]继续查询,令right=mid;

如果a[mid]<x,说明第一个大于等于X的元素的位置一定在mid的右侧,应往右子区间[mid+1,right]继续查询,令left=mid+1。

进一步探讨:查找第一个大于X的元素的位置

 //求序列中第一个大于X的元素的位置
	 int upper_bound(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;
	 } 

总结发现:lower_bound和upper_bound都是在寻找序列中第一个满足某条件的元素的位置。

继续拓展下去发现:f(x)=x^2再[1,2]范围计算根号2.  实质是寻找在[1,2]范围内,满足f(mid)=mid^2>√2,同时是Mid的范围在10^-5范围之内。   因此x^2单调递增,可以联想到用二分法。

代码如下:

//求f(x)-2=0的根
const double eps=1e-5;
double f(double x){
	return x*x;
} 
double calSqrt(){
	double left=1,right=2,mid;
	while(right-left>eps){  
		mid=(left+right)/2;
		if(f(mid)>2){     //此处f(x)的函数可以替换成任意单调递增函数
			right=mid;
		}else {
			left=mid;
		}
	}
	return mid;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值