序列二分查找

序列二分查找

二分查找是在有序序列上的快速查找方法,二分查找的时间复杂度为O(logn)O(logn)O(logn),现实中很多情形我们需要先排序,然后再查找指定元素,这里就会用到二分查找
二分查找非常简单,实现上分为递归实现和非递归实现,这里其实有些需要注意的点。

原理

我们先看下原理,在一个有序的序列a:{a1,a2,...,aN}a:\{a_1,a_2,...,a_N\}a:{a1,a2,...,aN}里面,假设开始和结束的位置分别是left=1left=1left=1right=Nright=Nright=N,待查找的数据值为valuevaluevalue,我们首先取到序列中间的位置midmidmid和值a[mid]a[mid]a[mid],用这个值来与待查值比较,

① 如果相等value==a[mid]value == a[mid]value==a[mid],说明我们找到了待查值,返回找到的下标midmidmid

② 如果待查值大于中间位置的值value>a[mid]value > a[mid]value>a[mid],说明待查值只可能在mid+1mid+1mid+1rightrightright中即序列{amid+1,...,aright}\{a_{mid+1},...,a_{right}\}{amid+1,...,aright}找到,此时更新leftleftleftmid+1mid+1mid+1,重新在left和left和leftright中即中即[left,right][left,right][left,right]$中找;

③ 如果待查值小于中间位置的值,说明待查值只可能在leftleftleftmid−1mid-1mid1的的序列{aleft,...,amid−1}\{a_{left},...,a_{mid-1}\}{aleft,...,amid1}中取到,此时更新rightrightrightmid−1mid-1mid1,重新在leftleftleftrightrightright[left,right][left,right][left,right]中查找;

什么时候结束呢,当找到待查值时当然结束,如果没有找到待查值,最后会在[index,index+1][index,index + 1][index,index+1]mid=indexmid = indexmid=index,然后比较大小,会在[index,index][index,index][index,index]或者[index+1,index+1][index + 1, index + 1][index+1,index+1]中找,如果在[index,index][index,index][index,index]没有找到,此时会在[index+1,index][index + 1,index][index+1,index],或者[index,index−1][index,index - 1][index,index1]去找,那么结束条件就是left>rightleft>rightleft>right

递归实现
int binarySearch(int *a, int left, int right, int value) {
    if (left > right) {
        return -1;
    }
    int mid = (left + right) / 2;
    if (a[mid] == value) {
        return mid;
    } else if (a[mid] < value) {
        left = mid + 1;
        binarySearch(a, left, right, value);
    } else {
        right = mid - 1;
        binarySearch(a, left, right, value);
    }
}
非递归实现

二分查找改为非递归实现,需要一个while循环,循环退出条件和递归一样

int binarySearch(int *a, int left, int right, int key){
   int mid;
   while (left <= right){
       mid = (left + right)  / 2;
       if(a[mid] == key){
           return mid;
       }else if(a[mid] < key){
           left = mid + 1;
       }else{
           right = mid - 1;
       }
   }
    return  -1;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值