zoukankan      html  css  js  c++  java
  • 二分查找(Binary Search)

    二分查找算法在程序设计中并不陌生,它可以在O(log(n))的时间复杂度内找到自己想要的值。

    首先需要待查找序列有序,然后需要你想要寻找的值即可,本文给出三种二分查找的例子,即:

    1. 精确二分查找,如果找不到返回error
    2. 进行精确查找,如果找不到则返回第一个小于该数值的元素的位置
    3. 进行精确查找,如果找不到则返回第一个大于该数值的元素的位置

    首先我们来看第一种(也是最简单的):

    int binarySearch(int *arr, int n, int value) {
        int l, r, mid;
        l = 0;
        r = n - 1;
        mid = 0;
        while (l <= r) {
            mid = (l + r) / 2;
            if (arr[mid] < value) {
                l = mid + 1;
            }
            else if (arr[mid] > value) {
                r = mid - 1;
            }
            else {
                return (mid);
            }
        }
        return -1;//error
    }
    

    简单易读。没找到就一直缩小区间,直到找到或者二分辅助变量l(左边界)与r(右边界)不符合要求,此时返回error。

    下面来看第二种情况的代码:

    int binarySearch(int *arr, int n, int value) {
        int l, r, mid;
        l = 0;
        r = n - 1;
        mid = 0;
        while (l <= r) {
            mid = (l + r) / 2;
            if (arr[mid] < value) {
                l = mid + 1;
            }
            else if (arr[mid] > value) {
                r = mid - 1;
            }
            else {
                break;
            }
        }
        if (arr[mid] != value && arr[mid] > x) {
            mid--;
        }
        return mid;
    }
    

    此时,无法找到第一个小于value的数(比如数列“1, 2, 3, 4, 5”中查找“0”是无法找到第一个小于它的数的),返回(左边界 - 1)*,此时需要程序进行特殊处理。

    最后我们来看一下最后一种情况的代码:

    int binarySearch(int *arr, int n, int value) {
        int l, r, mid;
        l = 0;
        r = n - 1;
        mid = 0;
        while (l <= r) {
            mid = (l + r) / 2;
            if (arr[mid] < value) {
                l = mid + 1;
            }
            else if (arr[mid] > value) {
                r = mid - 1;
            }
            else {
                break;
            }
        }
        if (arr[mid] != value && arr[mid] < x) {
            mid++;
        }
        return mid;
    }
    

    此时,无法找到第一个大于value的数(比如数列“1, 2, 3, 4, 5”中查找“6”是无法找到第一个大于它的数的),返回(右边界 + 1)*,此时需要程序进行特殊处理。

    *解释一下所谓的“左边界”与“右边界”,个人的编程习惯中在使用数组等结构时会使用0~n-1这n个位置,区别于使用1-n这n个位置,即遍历操作为:

    for (int i = 0; i < n; i++) {
        //do something with arr[i]
    }
    

    上问代码中对于“l”、“r”的初始值为“0”、“n - 1”也是这个原因,请读者注意。

    如有错误敬请指出,感谢阅读!

  • 相关阅读:
    FastJson的简单使用
    一些没用过的方法的学习
    Windows系统激活
    mysql数据库运行性能检查脚本
    基于windows 的Apache HTTP Server的一次小安装
    MySQL、Oracle批量插入、更新批量inisert、update
    IDEA中右键没有“Subversion”相关目录解决方法
    关于spring boot项目启动报错问题
    我的2016
    用intellij IDEA 编写时,无编程提示问题
  • 原文地址:https://www.cnblogs.com/yeehok/p/15311858.html
Copyright © 2011-2022 走看看