zoukankan      html  css  js  c++  java
  • 极客时间课程《数据结构与算法之美》笔记08

    二分查找

    普通循环代码:

    public int bsearch(int[] a, int n, int value) {
      int low = 0;
      int high = n - 1;
    
      while (low <= high) {
        int mid = (low + high) / 2;
        if (a[mid] == value) {
          return mid;
        } else if (a[mid] < value) {
          low = mid + 1;
        } else {
          high = mid - 1;
        }
      }
    
      return -1;
    }
    
    

    关键点:

    • 循环退出条件:是low<=high,而不是low<high
    • mid 取值,如果low和high比较大,则会让mid溢出。改进:mid = low+(high-low)/2。甚至优化为mid = (low+(high-low)>>1),右移k相当于缩小2^k倍
    • low和high的更新分别要+1,-1。如果low = mid则可能发生死循环。

    递归写法:

    // 二分查找的递归实现
    public int bsearch(int[] a, int n, int val) {
      return bsearchInternally(a, 0, n - 1, val);
    }
    
    private int bsearchInternally(int[] a, int low, int high, int value) {
      if (low > high) return -1;
    
      int mid =  low + ((high - low) >> 1);
      if (a[mid] == value) {
        return mid;
      } else if (a[mid] < value) {
        return bsearchInternally(a, mid+1, high, value);
      } else {
        return bsearchInternally(a, low, mid-1, value);
      }
    }
    
    

    应用场景:

    • 依赖顺序表结构,最好是数组,可以根据下标快速访问。
    • 有序数据。
    • 数据量太小太大都不适合二分查找。

    二分查找底层依赖数组,不需要存储额外的其他信息。

    二分查找的变形与改进

    常见问题:

    • 查找第一个,值(等于)给定值的元素
    • 查找最后一个,值(等于)给定值的元素
    • 查找第一个,值(大于等于)给定值的元素
    • 查找最后一个,值(大于等于)给定值的元素
    public int bsearch(int[] a, int n, int value) {
      int low = 0;
      int high = n - 1;
      while (low <= high) {
        int mid =  low + ((high - low) >> 1);
        if (a[mid] > value) {
          high = mid - 1;
        } else if (a[mid] < value) {
          low = mid + 1;
        } else {
          if ((mid == 0) || (a[mid - 1] != value)) return mid;
          else high = mid - 1;
        }
      }
      return -1;
    }
    
    

    核心处理部分:当a[mid] ==value的时候要有判断,看是否前面元素和它不相等。

     if ((mid == 0) || (a[mid - 1] != value)) return mid;
          else high = mid - 1;
    
  • 相关阅读:
    Oracle Instant Client(即时客户端) 安装与配置
    面试中经典的数据库问题
    MySQL 大表优化方案
    mysql中Timestamp,Time,Datetime 区别
    HTML学习之给div高度设置百分比不生效的问题
    textarea文本域宽度和高度width及height自动适应实现代码
    JAVA基础----java中E,T,?的区别?
    去除ArrayList集合中的重复自定义对象元素
    sql select中加入常量列
    mysql 将null转代为0
  • 原文地址:https://www.cnblogs.com/JackKing-defier/p/11288950.html
Copyright © 2011-2022 走看看