二分查找(binary search)

二分查找对于学过数据结构或者算法的人来说,应该是非常熟悉的。其基本思想是:比较目标(target)和中间关键字的大小关系,如果二者相等,则查找完毕;如果二者不等,则可以根据二者的大小关系,将查找的范围减半。

虽然二分查找的算法很简单,但是对于一个code新手来说,正确无误地实现一个二分查找算法也不是那么容易的。

最近,刷了几道二分查找的题目,将刷题的一点收获整理如下:

1.二分查找算法适用的范围:

①必须是顺序表,不适用于链式存储
②查找之前,序列必须是有序的。对于无序的序列,可以先采用合适的排序算法进行排序后,再使用二分查找。

2.二分查找算法的基本模式:

递归方式:

int binary_search(const int[] arr,int start,int end,int khey){
    if(start > end)
        return -1;
    int mid = start + (end - start) / 2;
    if(arr[mid] > khey)
        return binary_search(arr,start,mid-1,khey);
    if(arr[mid] < khey)
        return binary_search(arr,mid+1,end,khey);
    return mid;//最后检测相等是因为大多数情况下是小于或者大于
}

非递归方式:(更常用)

int binary_search(const int[] arr,int start,int end,int khey){
    int mid;
    while(start <= end){
        mid = start + (end - start) / 2;
        if(arr[mid] < khey)
            start = mid +1;
        else if(arr[mid] > khey)
            end = mid - 1;
        else 
            return mid;
    }
    return -1;
}

其中,需要注意的地方有:
① 我们学习二分算法的时候,求mid可能会用:mid = (start + end)/2,这时,在计算start+end的时候,可能会产生溢出,故以上所写的两种方式,均采用start + (end - start) / 2的方式,有时候可以避免溢出。
②在非递归算法中,while循环中究竟应该是(start < end)还是(start <= end),这应该具体情况具体分析;
③对于mid和khey比较的三种情况(大于,小于,相等)的排列顺序,大多数情况下,是影响不大的,实际中,可以根据三种情况出现的概率,决定其顺序;
④以上仅仅是二分查找算法的模板,具体使用时应该具体情况具体分析,灵活运用。

3.二分查找的复杂度

时间复杂度:O(logn)
空间复杂度:O(1)

在有些地方你可能会看到三分查找(ternary search),三分查找基本思想和二分查找一致,具体来讲:每次选出三分之一点和三分之二点,而不是中点,然后比较target和这两个点的大小关系,从而将查找的范围缩小至原来的三分之一。

二分查找和三分查找的空间复杂度都是O(1),而二分查找的时间复杂度是O(log2n),三分查找的时间复杂度是O(log3n)。既然三分查找的时间复杂度要优于二分查找,那我们为什么不经常使用三分查找,而经常使用二分查找呢?原因在于在最坏情况下,三分查找要明显劣于二分查找。这个具体的推导过程就不详述了, 想了解的可以参考这道题目

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值