栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

算法学习:二分查找

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

算法学习:二分查找

MidSearch
  • 一、二分查找算法
    • 1、二分查找
    • 2、递归实现二分查找
    • 3、查找第一个等于给定值的值的下标
    • 4、查找最后一个等于给定值的值的下标
    • 5、查找第一个大于等于给定值的值的下标
    • 6、查找最后一个小于等于给定值的值的下标
  • 二、二分查找的局限性

一、二分查找算法 1、二分查找
package Search_zhu;


public class MidSearch {
    public static int midsearch(int[] a,int value){
        int begin = 0;
        int end = a.length - 1;

        while (begin <= end){
            int mid = 2 * begin + (end - begin) / 2;
            if (a[mid] > value){
                end = mid - 1;
            }else if(a[mid] < value){
                begin = mid + 1;
            }else{
                return mid;
            }
        }

        return -1;
    }

    public static void main(String[] args) {
        int[] a = new int[]{3,5,9,12,39,50};
        System.out.println(midsearch(a,9));
    }
}

2、递归实现二分查找
package Search_zhu;



public class DgMidSearch {
    public static int midsearch(int[] a,int n,int value){
        return dgmidsearch(a,0,n-1,value);
    }

    public static int dgmidsearch(int[] a,int begin,int end,int value){
        if (begin > end) return -1;

        int mid = begin + (end - begin) / 2;
        if (a[mid] == value){
            return mid;
        }else if (a[mid] > value){
            return dgmidsearch(a,begin,mid - 1,value);
        }else{
            return dgmidsearch(a,mid + 1,end,value);
        }
    }

    public static void main(String[] args) {
        int[] a = new int[]{2,6,9,12,25,35,98};
        System.out.println(midsearch(a,7,12));
    }
}

3、查找第一个等于给定值的值的下标
package Search_zhu;



public class MidSearch1 {
    public static int midsearch1(int[] a,int value){
        int begin = 0;
        int end = a.length - 1;

        while (begin <= end){
            int mid =  begin + (end - begin) / 2;
            if (a[mid] > value){
                end = mid - 1;
            }else if (a[mid] < value){
                begin = mid + 1;
            }else{
                //若mid是第一个或mid的前一个不等于value,直接返回mid;否则end往前推
                if ((mid == 0) || a[mid - 1] != value)  return mid;
                else end = mid - 1;
            }
        }

        return -1;
    }

    public static void main(String[] args) {
        int[] a = new int[]{2,5,9,23,23,36,58};
        System.out.println(midsearch1(a,23));
    }
}

4、查找最后一个等于给定值的值的下标
package Search_zhu;


public class MidSearch2 {
    public static int midsearch2(int[] a,int value){
        int begin = 0;
        int end = a.length - 1;

        while (begin <= end){
            int mid = begin + (end - begin) / 2;
            if (a[mid] > value){
                end = mid - 1;
            }else if(a[mid] < value){
                begin = mid + 1;
            }else{
                if (mid == end || a[mid + 1] != value){
                    return mid;
                }else{
                    begin = mid + 1;
                }
            }
        }

        return -1;
    }

    public static void main(String[] args) {
        int[] a = new int[]{2,5,23,23,23,36,58};
        System.out.println(midsearch2(a,23));
    }
}

5、查找第一个大于等于给定值的值的下标
package Search_zhu;


public class MidSearch3 {
    public static int midsearch3(int[] a,int value){
        int begin = 0;
        int end = a.length - 1;

        while (begin <= end){
            int mid = begin + (end - begin) / 2;
            if (a[mid] >= value){
                if (mid == 0 || a[mid - 1] < value ) return mid;
                else end = mid - 1;
            }else{
                begin = mid + 1;
            }
        }

        return -1;
    }

    public static void main(String[] args) {
        int[] a = new int[]{2,5,23,23,23,36,58};
        System.out.println(midsearch3(a,5));
    }
}

6、查找最后一个小于等于给定值的值的下标
package Search_zhu;


public class MidSearch4 {
    public static int midsearch4(int[] a,int value){
        int begin = 0;
        int end = a.length - 1;

        while (begin <= end){
            int mid = begin + (end - begin) / 2;
            if (a[mid] > value){
                end = mid - 1;
            }else{
                if (mid == end - 1 || a[mid + 1] > value) return mid;
                else begin = mid + 1;
            }
        }
        return -1;
    }

    public static void main(String[] args) {
        int[] a = new int[]{2,5,23,23,23,36,58};
        System.out.println(midsearch4(a,25));
    }
}

二、二分查找的局限性
  • 二分查找依赖的是顺序表结构,就是数组。原因是二分查找需要依赖数组根据下标随机访问的特性,如果是链表的话,找到中间节点是需要遍历链表的一半
  • 二分查找依赖的是有序数据,二分查找依赖的是有序数组,如果没有序,需要先排序,堆排、快排、归并排的时间复杂度为O(nlogn),如果针对的是静态数组,可以实现一次排序,多次二分查找;如果是动态数组,不断插入或删除,数据插入和删除都要先进行排序,这时排序的成本就比较高,针对这种动态集合,更适合用二叉树来进行查找
  • 数据量太少不适合用二分查找,在这种情况下,二分查找和顺序遍历的时间差不多,但如果比较操作非常耗时,比如数组中存储的是字符串,这时还是推荐用二分查找*
  • 数据量太大也不适合用二分查找,因为二分查找依赖的是数组,数组必须要有连续的内存空间,对内存的要求比较严苛,在资源不足的情况下,使用二分查找是不合适的
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/999263.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号