二分查找法

二分查找方法
二分查找经常用来在有序的数列查找某个特定的位置。

因此,应用二分查找法,这个数列必须包含以下特征:

  • 存储在数组中
  • 有序排列

二分查找方法不适用于链表,因为链表方法需要遍历,应用二分查找法意义不大。

一般情况下,我们默认数组是单调递增数列,且无重复元素。(有重复元素的题应该如何解决)

 

二分查找方法递归和非递归实现

 第一种是递归方法实现,递归方法一般走的比较深,容易超时:

public int binarySearch(int [] A, int low, int high, int target){
    if (low > high)
        return -1;

    int mid = (low + high)/2;
    if (A[mid]> target)
        return    binarySearch(array, low, mid -1, target);
    if (array[mid]< target)
        return    binarySearch(array, mid+1, high, target);
    
    if (A[mid] == target)
        return mid;
}

第二种是非递归实现方法,更常用一些:

public int binarySearch(int[] A, int low, int high, int target){
    if(low > high)
        return -1;

    while(low<=high){
        int mid = low+high/2;
        if(A[mid] == target)
            return mid;
        if(A[mid] > target)
            high = mid-1;
        if(A[mid] < target)
            low = mid+1;
    }
    return -1;
}

Rotated Sorted Array

这是二分查找方法的一个变种,在leetcode中出现过。

它是有序数组,取期中某一个数为轴,将其之前的所有数都轮转到数组的末尾所得。比如{7, 11, 13, 17, 2, 3, 5}就是一个轮转后的有序数组。非严格意义上讲,有序数组也属于轮转后的有序数组——我们取首元素作为轴进行轮转。

public int SearchInRotatedSortedArray(int [] array, int low, int high, int target) 
{
    while(low <= high)
    {
        int mid = (low + high) / 2;
        if (target < array[mid])
            if (array[mid] < array[high])//the higher part is sorted
                high = mid - 1; //the target would only be in lower part
            else //the lower part is sorted
                if(target < array[low])//the target is less than all elements in low part
                    low = mid + 1;
                else
                    high = mid - 1;

        else if(array[mid] < target)
            if (array[low] < array[mid])// the lower part is sorted
                low = mid + 1; //the target would only be in higher part
            else //the higher part is sorted
               if (array[high] < target)//the target is larger than all elements in higher part
                    high = mid - 1;
                else
                    low = mid + 1;
        else //if(array[mid] == target)
            return mid;
    }

    return -1;
}

二分查找缺陷

二分查找法的O(log n)让它成为十分高效的算法。不过它的缺陷却也是那么明显的。就在它的限定之上:

必须有序,我们很难保证我们的数组都是有序的。当然可以在构建数组的时候进行排序,可是又落到了第二个瓶颈上:它必须是数组。

数组读取效率是O(1),可是它的插入和删除某个元素的效率却是O(n)。因而导致构建有序数组变成低效的事情。

 

解决这些缺陷问题更好的方法应该是使用二叉查找树了,最好自然是平衡二叉树了,自能高效的(O(n log n))构建有序元素集合,又能如同二分查找法一样快速(O(log n))的搜寻目标数。

 

二分查找其他应用 

1. 寻找上下界

2. 寻找范围 

本文基于:http://www.cnblogs.com/springfor/p/3857646.html


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值