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种方法要好很多:接口原型不变,而且没有额外的空间消耗(创建新的数组)并且没有使用递归。

 

posted @ 2014-07-03 22:51  XiaoweiLiu  阅读(661)  评论(0编辑  收藏  举报