zoukankan      html  css  js  c++  java
  • 二分查找(模板)

    转载自:https://www.jianshu.com/p/0f823fbd4d20

    二分查找很好写,却很难写对,出错原因主要集中在判定条件和边界值的选择上,很容易就会导致越界或者死循环的情况。

    下面对二分查找及其变形进行总结:

    首先,二分查找的序列必须是有序的、有序的、有序的

    如果环境允许,可以用库函数直接使用

    二分查找的函数有 3 个: 参考:https://www.cnblogs.com/Tang-tangt/p/9291018.html

    头文件是#include<algorithm>

    lower_bound(起始地址,结束地址,要查找的数值) - 起始地址

    upper_bound(起始地址,结束地址,要查找的数值) - 起始地址

    binary_search(起始地址,结束地址,要查找的数值) 

    说明:lower_bound()和upper_bound()返回的地址,都是从位置1开始算起的,[ first, last ),即first最小是从1开始的

    1  函数lower_bound() 

    功能:函数lower_bound()在[ first,last )区间进行二分查找,返回大于或等于val的第一个元素位置

    注意:如果val不存在,则返回last+1的位置,位置last+1是越界的!!

     

    2 函数upper_bound()

    功能:函数upper_bound()在[ first,last )区间进行二分查找,返回大于val的第一个元素位置

    注意:如果val刚好在上边界last的位置上,upper_bound()返回0;如果val不存在,则返回last+1的位置,而位置last+1是越界的!!

    3 函数binary_search()

    功能:判断查找的数是否存在,返回的是一个bool值

     

     

    #include<iostream>
    #include<algorithm>
    using namespace std;
    int a[1005];
    int main()
    {
      int n;
      cin>>n;
      for(int i=0;i<n;i++)
        cin>>a[i];
      sort(a,a+n);
      int x,y;
      cout<<binary_search(a,a+n,5)<<endl;
      x=upper_bound(a,a+n,5)-a;
      y=lower_bound(a,a+n,5)-a;
      cout<<a[x]<<endl;
      cout<<a[y]<<endl;
      return 0;
    
    }
    View Code

     

     

    1. 最基本的二分查找

    int a[100005];
    int find1(int target, int l,int r)//l,r是查找的左右区间
    {
        int left = l, right = r, mid;
        while (left <= right)
        {
            mid = left + (right - left) / 2;
            if (a[mid] == target)
                return mid;
            else if (a[mid] > target)
                right = mid - 1;
            else
                left = mid + 1;
        }
        return -1;
    }

    其中,有几个要注意的点:

    1. 循环的判定条件是:low <= high
    2. 为了防止数值溢出mid = low + (high - low)/2
    3. 当 A[mid]不等于target时,high = mid - 1low = mid + 1

    2. 当目标值有多个的时候,返回从左往右的第一个目标值。(目标值区域的左边界/查找与目标值相等的第一个位置/查找第一个不小于目标值数的位置

    eg:

    A = [1,3,3,5, 7 ,7,7,7,8,14,14]
    target = 7
    return 4

    int a[100005];
    int find2(int target,int l,int r) 
    {
        int left = l, right = r, mid;
        while (left <= right) 
        {
            mid = left + (right - left) / 2;
            if (target <= a[mid]) 
                right = mid - 1;
            else 
                left = mid + 1;
        }
        if (left <= r && a[left] == target)
            return left;
        else
            return -1;
    }

    3. 当目标值有多个的时候,返回从左往右的最后一个目标值。(查找目标值区域的右边界/查找与目标值相等的最后一个位置/查找最后一个不大于目标值数的位置

    eg:

    A = [1,3,3,5,7,7,7, 7 ,8,14,14]
    target = 7
    return 7

    int a[100005];
    int find3(int target, int l,int r) 
    {
        int left = l, right = r, mid;
        while (left <= right) 
        {
            mid = left + (right - left) / 2;
            if (target >= a[mid]) 
                left = mid + 1;
            else 
                right = mid - 1;
        }
        if (right >= 0 && a[right] == target)
            return right;
        else
            return -1;
    }
  • 相关阅读:
    有关 JavaScript 的 10 件让人费解的事情
    Apache ab介绍1
    Oracle Raw,number,varchar2... 转换
    Flex开发者需要知道的10件事
    linux命令之nice
    JavaIO复习和目录文件的复制
    使用php获取网页内容
    linux 安装sysstat使用iostat、mpstat、sar、sa
    SQL Injection 实战某基金
    ubuntu root锁屏工具
  • 原文地址:https://www.cnblogs.com/-citywall123/p/10738597.html
Copyright © 2011-2022 走看看