序列二分查找

序列二分查找

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

原理

我们先看下原理,在一个有序的序列 a : { a 1 , a 2 , . . . , a N } a:\{a_1,a_2,...,a_N\} a:{a1,a2,...,aN}里面,假设开始和结束的位置分别是 l e f t = 1 left=1 left=1 r i g h t = N right=N right=N,待查找的数据值为 v a l u e value value,我们首先取到序列中间的位置 m i d mid mid和值 a [ m i d ] a[mid] a[mid],用这个值来与待查值比较,

① 如果相等 v a l u e = = a [ m i d ] value == a[mid] value==a[mid],说明我们找到了待查值,返回找到的下标 m i d mid mid

② 如果待查值大于中间位置的值 v a l u e > a [ m i d ] value > a[mid] value>a[mid],说明待查值只可能在 m i d + 1 mid+1 mid+1 r i g h t right right中即序列 { a m i d + 1 , . . . , a r i g h t } \{a_{mid+1},...,a_{right}\} {amid+1,...,aright}找到,此时更新 l e f t left left m i d + 1 mid+1 mid+1,重新在 l e f t 和 left和 leftright 中 即 中即 [ l e f t , r i g h t ] [left,right] [left,right]$中找;

③ 如果待查值小于中间位置的值,说明待查值只可能在 l e f t left left m i d − 1 mid-1 mid1的的序列 { a l e f t , . . . , a m i d − 1 } \{a_{left},...,a_{mid-1}\} {aleft,...,amid1}中取到,此时更新 r i g h t right right m i d − 1 mid-1 mid1,重新在 l e f t left left r i g h t right right [ l e f t , r i g h t ] [left,right] [left,right]中查找;

什么时候结束呢,当找到待查值时当然结束,如果没有找到待查值,最后会在 [ i n d e x , i n d e x + 1 ] [index,index + 1] [index,index+1] m i d = i n d e x mid = index mid=index,然后比较大小,会在 [ i n d e x , i n d e x ] [index,index] [index,index]或者 [ i n d e x + 1 , i n d e x + 1 ] [index + 1, index + 1] [index+1,index+1]中找,如果在 [ i n d e x , i n d e x ] [index,index] [index,index]没有找到,此时会在 [ i n d e x + 1 , i n d e x ] [index + 1,index] [index+1,index],或者 [ i n d e x , i n d e x − 1 ] [index,index - 1] [index,index1]去找,那么结束条件就是 l e f t > r i g h t left>right left>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;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值