C++ 二分查找避免死循环

二分查找

自己写二分查找很容易写错边界,进入死循环,这里总结下模板,分为三种类型(假设数组a递增):

  1. 查找坐标i,使得a[i]=num,这个比较简单,不会陷入死循环:
while(left<right){
    int middle = (left+right)/2;
    if(a[middle]=num) ans=middle;
    else if(a[middle]>num) right=middle-1;
    else left=middle+1;
}
  1. 查找满足a[i]>=num的最小坐标i
while(left<right){
    int middle = (left+right)/2;
    if(a[middle]<num) left=middle+1;
    else right=middle;
}

注意,死循环通常发生在left+1=right的情况,因此需要格外注意if-else中right=middle的情形。假设left=0,right=1,不论条件语句if-else走向哪个分支,都不会死循环。
3. 查找满足a[i]<=num的最大坐标i

while(left<right){
    int middle = (left+right+1)/2;
    if(a[middle]>num) right=middle-1;
    else left=middle;
}

同理,假设left=0,right=1,如果middle采取上述的方案:middle=(left+right)/2=0,然后条件分支进入else语句,left=middle=0,则陷入了死循环。

总结

只需额外关注if-else中赋值为middle的分句,并在middle的赋值对应上取整或下取整,以避免陷入死循环。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值