二分查找(折半查找)的递归和非递归实现(c++)

1步骤描述

使用前提:有序数组中查找关键词所在位置。

1.首先确定整个查找区间的中间位置 mid = start+(end-start)/2。

2使用待查关键字key值与中间位置的关键字值进行比较。

3 若相等,则查找成功

若大于,则在后(右)半个区域继续进行折半查找

若小于,则在前(左)半个区域继续进行折半查找

4 对确定的缩小区域再按折半公式,重复上述步骤。

2 非递归二分查找算法

int bin_search1(int key,int arr[],int length){
    int start =0,endend = length-1;
    int mid = start +(endend-start)/2;
    if(arr[mid]==key)
        return mid;
    while(start<=endend){
        mid = start +(endend-start)/2;
        if(arr[mid]>key){
            endend = mid-1;
        }
        else if(arr[mid]<key){
            start = mid +1;

        }
        else{
            return mid;
        }
    }
    return -1;
}

3 递归二分查找方式

int binary_search2(int key,int arr[],int start,int endend){
    int mid = (endend - start)/2 +start;
    if(arr[mid]==key){
        return mid;
    }

    if(start>=endend){
        return -1;
    }
    else if(key>arr[mid]){
        return binary_search2(key,arr,mid+1,endend);
    }
    else if(key<arr[mid]){
        return binary_search2(key,arr,start,mid-1);
    }

    return -1;
}

4 主函数

int main(){
    int arr[] = {1,3,5,7,12,13,15,18,23,45};
    int arr_length = sizeof(arr)/sizeof(arr[0]);
    cout<<arr_length<<endl;
    int resultPos = bin_search1(18,arr,arr_length);
    int resPos = binary_search2(12,arr,0,arr_length);
    cout<<"18的位置"<<resultPos<<endl;
    cout<<"12的位置"<<resPos<<endl;

    return 0;
}

5 结果显示

在这里插入图片描述

注意:二分查找的问题,对于 mid=beg+(end-beg)/2 与 mid=(beg+end)/2 区别?

  • 首先第二种数学上得到的结果是完全一样的,这个可以通过取整函数的方法证明。但是beg+end这一步操作很可能会出现整数溢出的风险,而 beg + (end-beg)/2 写法不会出现比end要大的中间数据,所以比较安全。如果你是用 python 这种自带大数支持的语言,就不用担心这种写法会整数溢出了。

  • 你要是看c++ stl源码就会发现用的也是第一种,因为考虑了通用性,用第二种如果beg和end是指针或者迭代器的话是无法编译通过的,因为指针和迭代器运算不支持相加运算,却支持相减运算,所以第一种通用性强。(迭代器的话要求是随机访问迭代器random access iterator)。基本就是这两点原因了,这个问题也是c++primer fifth edition 3.26 上问到的。

二分法特殊使用

牛客题目(答案暂时么有整理)

https://www.nowcoder.com/practice/72ff6503455c4a008675e79247ef2a3a?tpId=8&&tqId=11047&rp=1&ru=/activity/oj&qru=/ta/cracking-the-coding-interview/question-ranking

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值