• Java:深入了解数组Arrays.binarySearch方法的优缺点


    目录

    背景

    最近重新整理Java基础知识,在练习数组的过程中关于Arrays.binarySearch(type[] a,type key)方法的一系列问题以及解决方法

    方法介绍

      Arrays.binarySearch(type[] a,type key),第一个输入的值为相应数据类型的数组,第二个为想要查找的数值,如果查询到这个数值就会返回该数值的下标,如果没有找到,则返回插入值的负数。

    PS:在使用Arrays.binarySearch(type[] a,type key)方法前,需要对数组进行排序

    实例

            int[] num=new int[]{5,8,3,10,1};
            //对数组进行排序
            Arrays.sort(num);
            //排序后的数组为[1,3,5,8,10]
            //查询数组num数值为8的下标,有结果,返回下标
            int num1=Arrays.binarySearch(num,8);
            //查询数组num数值为6的下标,无结果,返回-1或“-”(插入点)。插入点是索引键将要插入数组的那一点,即第一个大于该键的元素的索引。
            int num2=Arrays.binarySearch(num,6);
            int num3=Arrays.binarySearch(num,-6);
            //查询数值num中下标为2到3中数值为8的下标
            int num4=Arrays.binarySearch(num,2,3,8);
            //查询数值num中下标为1到3中数值为3的下标
            int num5=Arrays.binarySearch(num,1,3,3);
            System.out.println("查询数组num数值为8的下标,有结果"+num1);
            System.out.println("查询数组num数值为6的下标,无结果"+num2);
            System.out.println("查询数组num数值为-6的下标,无结果"+num3);
            System.out.println("查询数值num中下标为2到3中,数值为8的下标"+num4);
            System.out.println("查询数值num中下标为2到3中,数值为3的下标"+num5);

    结果

    方法缺点:

    到这一步这个方法一切都是如此简单,我就不会写这个博客了,但是这个方法有1个无法解决的缺点,让我们先看一下Java自己是如何介绍这个方法的。

     对于英语不好的朋友我把第一段已经翻译后,显示在下面

    使用二进制搜索算法在指定的整数数组中搜索指定的值。在进行此调用之前,必须对数组进行排序(就像使用{@link#sort(int[])}方法一样)。如果不排序,则结果未定义。
    如果数组包含多个具有指定值的元素,则无法保证将找到哪一个元素。

    我加粗的那一行字,也就是说如果数值中有多个重复的值,它可能就无法正确定位到该位置。

    实例

    int[] num=new int[20];
            for (int i=0;i<num.length;i++){
                Random random=new Random();
                num[i]=random.nextInt(3)+1;
            }
            Arrays.sort(num);
            int num1=Arrays.binarySearch(num,1);
            int num2=Arrays.binarySearch(num,2);
            int num3=Arrays.binarySearch(num,3);
            System.out.println("1的下标"+num1);
            System.out.println("2的下标"+num2);
            System.out.println("3的下标"+num3);

    结果

    返回结果

     实际结果

     总结:所以当有多个相同的数值在数组中,Arrays.binarySearch方法无法正确找到该数值的最后一个数值的索引,或者第一个数值的索引。

    原因分析

    源码查看:查看Arrays.binarySearch()方法,这里以int类型作为解说

        public static int binarySearch(int[] a, int key) {
            return binarySearch0(a, 0, a.length, key);
        }
    
        public static int binarySearch(int[] a, int fromIndex, int toIndex,int key) {
            rangeCheck(a.length, fromIndex, toIndex);
            return binarySearch0(a, fromIndex, toIndex, key);
        }
    
        // Like public version, but without range checks.
        private static int binarySearch0(int[] a, int fromIndex, int toIndex,int key) {
            int low = fromIndex;
            int high = toIndex - 1;
    
            while (low <= high) {
                int mid = (low + high) >>> 1;
                int midVal = a[mid];
    
                if (midVal < key)
                    low = mid + 1;
                else if (midVal > key)
                    high = mid - 1;
                else
                    return mid; // key found
            }
            return -(low + 1);  // key not found.
        }

     我们可以看到调用Arrays.binarySearch()方法实际上就是调用binarySearch0()方法,binarySearch0()方法其实是一个二分查找法,这就是为什么我们使用Arrays.binarySearch()前需要进行排序,以及多个数值相同的数,无法精确定位下标的原因。

     补充说明:

      当没有定义int fromIndex, int toIndex时,fromIndex=0, toIndex=数组长度

    为什么使用>>>(无符号位右移),而不是用>>(右移)这是避免数据过大,导致溢出

    为什么使用>>>位运算符,而不是直接除以2,这是因为>>>可以提高编程的运行速度

     

  • 相关阅读:
    软件测试homework2
    软件测试homework1
    ubuntu14 安装QUME+xv6
    判断两线段是否相交 模板
    并查集 HDU1558
    并查集 HDU1272
    并查集 HDU1232
    数据结构之单向链表 UVa11988
    Java大数 字符串处理 HDU2100
    Java大数中的小数 HDU1753
  • 原文地址:https://www.cnblogs.com/hahayixiao/p/14038924.html
Copyright © 2020-2023  润新知