• 数据结构与算法之美-二分查找(下)


    四种常见的二分查找变形问题

    查找第一个值等于给定值的元素

    //查找第一个等于给定值的元素
    public static int BSearch2(int[] a, int n, int value){
        //定义数组头尾索引
        int low = 0, high = n - 1;
        //循环到头索引大于等于尾索引
        while (low <= high){
            //位运算头尾索引之和除以二得到mid索引,同时避免溢出
            int mid = low + ((high - low) >> 1);
            //根据大小折半比较范围
            if (a[mid] > value)
                high = mid - 1;
            else if (a[mid] < value)
                low = mid + 1;
            //如果和value相等
            else{
                //如果mid索引是0,或者mid其前一位不等于value
                //就说明mid处的数据是第一个和value相等的
                if (mid == 0 || a[mid - 1] != value) return mid;
                //否则就以mid前一位为尾索引进行查找
                else high = mid - 1;
            }
        }
        return -1;
    }

    查找最后一个值等于给定值的元素

    //查找最后一个等于给定值的元素
    public static int BSearch3(int[] a, int n, int value){
        //定义数组头尾索引
        int low = 0, high = n - 1;
        //循环到头索引大于等于尾索引
        while (low <= high){
            //位运算头尾索引之和除以二得到mid索引,同时避免溢出
            int mid = low + ((high - low) >> 1);
            //根据大小折半比较范围
            if (a[mid] > value)
                high = mid - 1;
            else if (a[mid] < value)
                low = mid + 1;
            //如果和value相等
            else{
                //如果mid索引是n-1,或者mid其后一位不等于value
                //就说明mid处的数据是最后一个和value相等的
                if (mid == n-1 || a[mid + 1] != value) return mid;
                //否则就以mid后一位为头索引进行查找
                else low = mid + 1;
            }
        }
        return -1;
    }

    查找第一个大于等于给定值的元素

    //查找第一个大于等于给定值的元素
    public static int BSearch4(int[] a, int n, int value){
        //定义数组头尾索引
        int low = 0, high = n - 1;
        //循环到头索引大于等于尾索引
        while (low <= high){
            //位运算头尾索引之和除以二得到mid索引,同时避免溢出
            int mid = low + ((high - low) >> 1);
            //根据大小折半比较范围
            //若大于value
            if (a[mid] > value){
                //mid为0或者
                if (mid == 0 || a[mid - 1] < value) return mid;
                else high = mid - 1;
            }
            else low = mid + 1;
        }
        return -1;
    }

    查找最后一个小于等于给定值的元素

    //查找第一个大于等于给定值的元素
    public static int BSearch5(int[] a, int n, int value){
        //定义数组头尾索引
        int low = 0, high = n - 1;
        //循环到头索引大于等于尾索引
        while (low <= high){
            //位运算头尾索引之和除以二得到mid索引,同时避免溢出
            int mid = low + ((high - low) >> 1);
            //根据大小折半比较范围
            //若大于value
            if (a[mid] < value){
                //mid为0或者
                if (mid == n-1 || a[mid + 1] > value) return mid;
                else low = mid + 1;
            }
            else high = mid - 1;
        }
        return -1;
    }

     

    适用性分析

    凡是能用二分查找解决的,绝大部分我们更倾向于用散列表或者二叉查找树,

    即便二分查找在内存上更节省,但是毕竟内存如此紧缺的情况并不多。

    求“值等于给定值”的二分查找确实不怎么用到,二分查找更适合用在”近似“查找问题上。比如上面讲几种变体。

    思考

    如果有一个有序循环数组,比如4,5,6,1,2,3。针对这种情况,如何实现一个求“值等于给定值”的二分查找算法?

  • 相关阅读:
    一些网购体会
    图灵社区 : 阅读 : [讨论] Java语言被很多人抱怨语法繁琐、开发效率低、体系繁杂而笨重,为什么还有这么强的生命力,尤其是在企业软件领域?
    反爬虫策略浅析
    redis源码笔记 刘浩de技术博客 博客园
    欢迎阅读 Erlang OTP 设计原理文档!¶
    图灵社区 : 阅读 : 十年码农聚会报道——让高龄老码农social起来
    学了一年的c++,连个像样的程序都写不出来 C/C++ / C++ 语言
    2012年第一批中关村高端领军人才公示公告
    为什么Markdown+R有较大概率成为科技写作主流? ← 阳志平的个人网站::技术
    大道至易——"刺秦与灭秦"个人、团队的前途与未来
  • 原文地址:https://www.cnblogs.com/errornull/p/9948345.html
Copyright © 2020-2023  润新知