二分法——区间与选择

二分法——区间与选择

常见区间分类

1.左闭右闭

左闭右闭区间——[L,R];

while (l <= r) {
	int mid = l + (r - l) / 2;
	if (a[mid] > x) {
		r = mid - 1;
	}
	else if (a[mid] < x) {
		l = mid + 1;
	}
	else {
		l = mid;
		break;
	}
}

因为区间的两个端点都是可以取到的,所以while循环中,l==r是合法的,即存在[1,1]这种合法情况,if判断语句中,一定要把a[mid] == x和<或>关系分开来写,因为a[mid]>=x;表示——>a[mid]>x a[mid]==x,因为端点r或者l是包括在区间内部的,所以当a[mid]>x时,r不能等于mid,因为mid处的值已经被判断为了比x大,应该将mid排除在区间外,但是如果a[mid]= =x同时与a[mid]>x同时存在时,r若不等于mid(即r= =mid-1),那么就直接将a[mid]= =x这种mid的情况排除在了区间外,这样子无法得到正确的结果,所以a[mid]>x与a[mid]= =x分开来判断。

2.左闭右开

左闭右开区间——[L,R);

while (l < r) {
	int min = l + (r - l) / 2;
	if (a[mid]>=x) {
		r = mid;
	}
	else {
		l = mid + 1;
	}
}

区间的左端点l包括在区间内,而右端点r不包括在区间内,故l不能等于r,即[1,1)——1既存在在区间内,又不存在在区间内,这种区间是不合法的,由此,while循环判断条件l不能等于r。当a[mid]>=x时,为什么mid可以赋值给了r呢?——>因为,r不属于区间内,所以r= =mid时,新的区间内并不包含mid,但是这样的不包含,不影响对于a[mid]= =x的情况的后续操作,因为r依旧指向x元素,在接下来的二分中,r始终指向x元素,而l在不断向x元素逼近,最终,当l= =r的时候,就找到了x的位置。l=mid+1;——>当a[mid]<x的时候,x一定位于不包含mid位置的右区间里面,而[L,R),区间更新后,l始终位于区间内部,所以若l= mid,那么就把已经判断过不属于新区间的值又包含在区间内了,故r=mid+1;将mid位置排除在区间外面。

3.实数二分区间

实数二分区间不需要区间判断,需要考虑的是精度的问题

while ((r - l) > eps) {
	double mid = l + (r - l) / 2;
	if (check(mid))
		l = mid;
	else
		r = mid;
}

l,r直接用mid来赋值就可以了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值