zoukankan      html  css  js  c++  java
  • 算法复习笔记:二分查找

      在计算机科学中,折半搜索英语:half-interval search),也称二分查找算法binary search)、二分搜索法二分搜索二分探索,是一种在有序数组中查找某一特定元素的搜索算法。搜索过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜索过程结束;如果某一特定元素大于或者小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且跟开始一样从中间元素开始比较。如果在某一步骤数组为空,则代表找不到。这种搜索算法每一次比较都使搜索范围缩小一半。

    实现:

    int binarySearch(vector<int> &v,int x)
    {
        int left = 0;
        int right = v.size() -1;
        while(left <= right)
        {
            int mid = left + ((right - left)>>1);
            if(v[mid] == x)
                return mid;
            else if(v[mid] < x)
                left = mid + 1;
            else right = mid - 1;
        }
        return -1;
    }

    注意问题

    1. 区间开闭。left和right表示算法当前处理的数组的最小下标和最大下标,上述采用闭区间[0,v.size()-1]。采用闭区间的判断条件为left<=right,如果用left<right在最后一个元素是会直接跳出[left,left]。
    2. 中间下标计算。平均值计算能出现除法性能较低,加法可能溢出采用mid = left + ((right - left)>>1)计算可避免。  
    3. 下标修改。采用+1-1修改的方式,修改之后新的区间肯定不会跟原区间一样,算法不会进入死循环。

     查找第一次出现

       在v的当前区间[left,right]中,数据为非递减序, 如果tar<=v[mid],则v[mid]右边的元素(不包括v[mid])全部都不符合要求 ,则right = mid;如果tar > v[mid], 则左边的元素包括v[mid]全部都小于tar,则left = mid +1; 此时循环条件在最后一个元素的时候,会出现死循环,需要改成left<right。

    比如:

       当前状况:        tar == V[0], left == 0,right == 0

       计算:            mid = 0

       更新:          更新right = mid = 0;

    int binarySearchFirst(vector<int> & v,int x)
    {
        int left = 0;
        int right = v.size()-1;
    
        while(left < right)
        {
            int mid = left + ((right - left)>>1);
            if(x <= v[mid])
                right = mid;
            else
                left = mid + 1;
        }
        if(v[left] == x)
            return left;
        else
            return -1;
    
    }


     查找最后一次出现

      在v的当前区间[left,right]中,数据为非递减序, 如果tar<v[mid],则v[mid]以及右边的元素全部都不符合要求 ,则right = mid - 1;如果tar >= v[mid], 则左边的元素v[mid]全部都小于tar,则left = mid ;  但是在最后两个元素的时候,循环会一直保持不变,所以采取的方法是   int mid = left + ((right - left + 1)>>1);

    比如:

       当前状况:        tar == V[0], left == 0,right == 1

       计算:            mid = 0

       更新:          更新left = mid = 0;

    int binarySearchLast(vector<int> &v,int x)
    {
        int left = 0;
        int right = v.size()-1;
    
        while(left < right)
        {
            int mid = left + ((right - left + 1)>>1);
            if(x < v[mid])
                right = mid - 1;
            else
                left = mid ;
        }
        if(v[left] == x)
            return left;
        else
            return -1;
    }

     

  • 相关阅读:
    CUUG PostgreSQL中级认证PGCP首考圆满结束!
    OCP 063中文考试题库(cuug内部资料)第21题
    OCP 063中文考试题库(cuug内部资料)第20题
    OCP 063中文考试题库(cuug内部资料)第19题
    OCP 063中文考试题库(cuug内部资料)第17题
    cdq实现树状数组
    P3810 【模板】三维偏序(陌上花开) 题解(cdq分治模板)
    CSUST 递增数组2 题解(思维+分段考虑)
    E. Clear the Multiset 题解(分治+贪心)
    P5019 [NOIP2018 提高组] 铺设道路 题解(贪心+思维)
  • 原文地址:https://www.cnblogs.com/fengyehe/p/5360099.html
Copyright © 2011-2022 走看看