zoukankan      html  css  js  c++  java
  • 一起手写吧!二分查找!

    二分查找,也称折半查找。利用二分思想,每次查找的时候把数据分为两半,从中间值开始找。

    如上图所示,low和high代表数组的两边下标,mid代表数组的中间下标。

    • 若目标值比中间值大,即目标值在mid与high之间,就修改low的值。再对比中间值。

    • 若目标值比中间值小,即目标值在low与mid之间,就修改high的值。再对比中间值。

    上述就是二分查找的过程,那它的时间复杂度怎么求呢❓

    假设数组的长度为n,那么查找一次后长度变为n/2,再查找一次后长度变为n/4,以此类推,最坏情况下,n/2^k为空,查找停止。于是我们有以下的公式:

    n * n/2 * n/4 * n/8 * n/2^k ·····

    以上是一个等比数列,n / 2^k = 1时,k就是查找的次数。即k=log2n,所以时间复杂度为O(logn),这是一种非常高效率的算法。 

    非递归版

    function binary_search(arr, key) {
        var low = 0, high = arr.length - 1;
        while(low <= high){
            var mid = parseInt(low + (high - low) / 2); 
            if(key === arr[mid]){
                return  mid;
            } else if (key > arr[mid]){
                low = mid + 1;
            } else if (key < arr[mid]){
                high = mid -1;
            } else {
                return -1;
            }
        }
    };
    var arr = [5,13,19,21,37,56,64,75,80,88,92];
    var result = binary_search(arr, 21);
    console.log(result);
    需要注意的是,mid的取值不要写成(low + high) / 2,因为如果low+high很大的话,会溢出。因此写成low+(high-low)/2就不会有这个问题。
    更进一步,当然也可以用位运算来low+((high-low)>>1)代替low+(high-low)/2,而且这种位运算的效率更高一些。

    递归版

    二分查找除了上边介绍的循环方法外,还可以用递归来实现。

    function binary_search(arr,low, high, key) {
        if (low > high){
            return -1;
        }
        var mid = low + ((high - low) >> 1);
        if(arr[mid] == key){
            return mid;
        }else if (arr[mid] > key){
            high = mid - 1;
            return binary_search(arr, low, high, key);
        }else if (arr[mid] < key){
            low = mid + 1;
            return binary_search(arr, low, high, key);
        }
    };
    var arr = [5,13,19,21,37,56,64,75,80,88,92];
    var result = binary_search(arr,0, 11, 21);
    console.log(result);

    3.数组中存在重复的数据,怎么找出元素最后一次出现的位置

    和上边介绍的二分查找思路一样:

    function binary_search(arr, key) {
        var low = 0, high = arr.length - 1;
          while (low <= high) {
            var mid =  low + ((high - low) >> 1);
            if (arr[mid] > key) {
              high = mid - 1;
            } else if (arr[mid] < key) {
              low = mid + 1;
            } else {
              if ((mid == arr.length - 1) || (arr[mid + 1] != key)) return mid;
              else low = mid + 1;
            }
        }
        return -1;
    }
    var arr = [5,13,19,21,21,37,56,64,75,80,88,92];
    var result = binary_search(arr, 21);
    console.log(result);
  • 相关阅读:
    mac os programming
    Rejecting Good Engineers?
    Do Undergrads in MIT Struggle to Obtain Good Grades?
    Go to industry?
    LaTex Tricks
    Convert jupyter notebooks to python files
    How to get gradients with respect to the inputs in pytorch
    Uninstall cuda 9.1 and install cuda 8.0
    How to edit codes on the server which runs jupyter notebook using your pc's bwroser
    Leetcode No.94 Binary Tree Inorder Traversal二叉树中序遍历(c++实现)
  • 原文地址:https://www.cnblogs.com/magicg/p/12749445.html
Copyright © 2011-2022 走看看