探秘二分查找

前言

众所周知, 二分查找(Binary Search)是极其高效的查找方法, 在最坏的情况下才会以logN的时间运行, 时间复杂度表示为O(logN). 当然, 二分查找适用于已排序的数组. 二分查找开始于将数组中间的元素与目标值进行比较. 如果目标值与元素匹配, 则返回其在数组中的位置. 如果目标值小于该元素, 则搜索在数组的下半部分继续. 如果目标值大于元素, 则搜索将在数组的上半部分继续. 通过这样做, 该算法消除了每次迭代中不能匹配的一半.

算法1

int BinarySearch(int A[], int n, int elem){
    int L = 0, R = n - 1, m = 0;
    while(L <= R){
        m = (L + R) / 2;
        if(A[m] > elem){
            R = m - 1;
        }else if(A[m] < elem){
            L = m + 1;
        }else
            return m;
    }
    return -1;
}

这个方法逻辑很简单, 但是有一个致命的问题就是如果遇到多次重复的项输出结果很不稳定.

总结一下算法1问题的原因: 每次执行时都会判断中值是否等于目标值, 若相等即输出.

算法21

int BinarySearch(int A[], int n, int elem){
    int L = 0, R = n - 1;
    float m = 0;
    while(L != R){
        m = ceilf((L + R) / 2.0);
        if(A[(int)m] > elem){
            R = m - 1;
        }else
            L = m;
    }
    if(A[L] == elem){
        return L;
    }
    return -1;
}

我们改了一下判定方法, 这次的确稳定了, 稳定输出最后一项(虽说这样做的确没错, 包括算法1, 其实也是正确解), 但其实也不是很符合我们的逻辑, 我们可以在改进一下.

算法3

int BinarySearch(int A[], int n, int elem){
   int L = 0, R = n - 1, m = 0;
   while(L < R){
       m = (L + R) / 2;
       if(A[m] < elem){
           L = m + 1;
       }else
           R = m;
   }
   if(A[R] == elem){
       return R;
   }
   return -1;
}

这下改好了, 其实它也有一个输出最右端数的变形, 就交给爱思考的同学了


  1. Hermann Bottenbruch published the first implementation to leave out this check in 1962. ↩︎

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值