cpp二分

简而言之就是一分为二的去查找,一种常用的查找方式。

```CPP
/* 对一个队列进行二分,这里考虑的总是有解的情况的整数二分 */
int find(int x){  
    int l = 0, r = q.size() - 1;  
    /* 一定有解的情况,在r=l时循环结束 */
    while(r > l){  
        /* 这里的情况下,由于在计算二分时向下取整的性质,所以等号的所处的位置对r和l的复制是有影响的!!! */
        int mid = l + (r - l >> 1); 
        /**  
         * 这里的写法本质上就是 mid = l + r >> 1;
         * 这种写法可以有效的避免变量在l + r时发生溢出
         * 同时可以改善运行效率(4倍以上,原因未知)
         * */  
        if(q[mid] >= x){
            /* 这里的条件是带等号的,说明mid是有可能是解的,所以移动边界时一定要到mid */   
            r = mid;  
        } else{
            /**  
             * else里面自然就是不含等号的情况,这种情况看起来直接移动边界到mid好像也没有什么影响  
             * 但实际上在确定了mid一定不为解之后,就应该把mid筛掉  
             * 不妨假设这样的情形,在else中仍然“l=mid”只剩最后2个选项进行二分  
             * 由于向下取整的性质,总是有mid=l,倘若q[r]=x,q[mid]<x,就会令l=mid=l这样的死循环  
             * 这个二分算法就会永远都持续下去  
             * 当然也可以写成对称的形式,如下  
             */
            l = mid + 1;  
        }  
    }  
    return r;  
}

/* 对中间的特殊部分有另一种形式的写法 */
if(q[mid] > x){
    r = mid - 1;
}else{
    l = mid;
}

/* 同理也有小于号的写法 */
if(q[mid] < x)
    l = mid + 1;
else
    r = mid;

/* 这两种写法本质是一样的,只是要注意等号带来的影响 */
```

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值