• Binary Search in Java


      关于折半查找中的几个注意点.

    Version 1:

    public static <T extends Comparable<? super T>> int binSearch(T[] arr,
            T element) {
        int length = arr.length;
        int middle = length / 2;
        int index;
        if (length == 0) {
            return -1;
        }
        if (arr[middle].compareTo(element) == 0) {
            index = middle;
        } else if (arr[middle].compareTo(element) < 0) {
            index = middle
                    + 1
                    + binSearch(Arrays.copyOfRange(arr, middle + 1, length),
                            element);
        } else {
            index = binSearch(Arrays.copyOfRange(arr, 0, middle), element);
        }
        return index;
    }

      要保证接口为binSearch(array, target),所以此处使用了Arrays.copyOfRange()--导致造成了额外的空间消耗(创建新的数组)。

    Version 2:

    // 注意这种切换接口的方式
    public static <T extends Comparable<? super T>> int binSearch_JDK(T[] arr,
            T element) {
        //With Recursion
        return binSearch_JDK(arr, 0, arr.length - 1, element);
    }
    
    // With Recursion
    public static <T extends Comparable<? super T>> int binSearch_JDK(T[] arr, int start, int end, T element) {
        if(start > end){
            return -1;
        }
        int middle = (start + end) / 2;
        if(arr[middle].compareTo(element) == 0){
            return middle;
        }else if(arr[middle].compareTo(element) < 0){
            return binSearch_JDK(arr, middle + 1, end, element);
        }else{
            return binSearch_JDK(arr, 0, middle - 1, element);
        }
    }

      保证了接口原型不变,而且没有额外的空间消耗(创建新的数组)。注意这种切换接口的方式。

    Version 3:

    // 注意这种切换接口的方式
    public static <T extends Comparable<? super T>> int binSearch_JDK(T[] arr,
            T element) {
        //Without Recursion
        return binarySearch(arr, 0, arr.length - 1, element);
    }
    
    // JDK SOURCE CODE jdk没有使用泛型,而是直接使用了long
    // 能不用递归就不要用
    public static <T extends Comparable<? super T>> int binarySearch(T[] arr, int start, int end, T element) {
        int middle = start;
        while(start <= end){
            //middle = (start + end) / 2;
            middle = (start + end) >>> 1;
            if(arr[middle].compareTo(element) == 0){
                return middle;
            }else if(arr[middle].compareTo(element) < 0){
                start = middle + 1;
            }else{
                end = middle - 1;
            }
        }
        return -1;
    }

      这种方法相对于前2种方法要好很多:接口原型不变,而且没有额外的空间消耗(创建新的数组)并且没有使用递归。

  • 相关阅读:
    游标
    js问题杂记
    博客园页面设置
    Natas13 Writeup(文件上传,绕过图片签名检测)
    Natas12 Writeup(文件上传漏洞)
    Natas11 Writeup(常见编码、异或逆推、修改cookie)
    Natas10 Writeup(正则表达式、grep命令)
    Natas9 Writeup(命令注入)
    Natas8 Writeup(常见编码、php函数)
    Natas7 Writeup(任意文件读取漏洞)
  • 原文地址:https://www.cnblogs.com/lxw0109/p/Binary_Search.html
Copyright © 2020-2023  润新知