在int数组上使用二进制搜索按降序排序

时间:2015-02-02 17:50:29

标签: java sorting binary-search

import java.util.*;
import java.io.*;
import java.util.Arrays;
import java.util.Collections;
import org.apache.commons.lang3.ArrayUtils;
@SuppressWarnings("unused")
public class Tester {
    public static void main(String args[]){
        int i[] = {-7, 15, 21, 22, 43, 49, 51, 67, 81, 84, 89, 95, 97};
        ArrayUtils.reverse(i);
        System.out.println(binarySearch(i, 22));
        System.out.println(binarySearch(i, 89));
        System.out.println(binarySearch(i, -100));
        System.out.println(binarySearch(i, 72));
        System.out.println(binarySearch(i, 102));
    }
    private static int binarySearch(int a[], int srchVal){
        int lb = 0;
        int ub = a.length - 1;

        while(lb <= ub){
            int mid = (lb + ub)/2;
            if(a[mid] == srchVal){
                return mid;
            }
            else if(srchVal > a[mid]){
                lb = mid + 1;
            }
            else{
                ub = mid - 1;
            }
         }
        return -1;
    }
}

对于类中的赋值,我需要修改BinarySearch方法,以便它可以与反向数组一起正常工作。但我无法弄清楚我应该如何修改它。

6 个答案:

答案 0 :(得分:3)

如果数组按降序排序,如果您反转搜索算法执行的所有值比较的意义,二进制搜索仍然可以工作。

等于大小写仍然正常,但您可以将else if中的对比转换为<else不需要修改,因为else if更改意味着else块现在将代表>条件。

答案 1 :(得分:0)

二进制搜索假设数据是有序的。如果是这种情况,那么,只要知道所选索引(mid)的值是否小于该值,该值必须在0..mid-1范围内,反之亦然。

如果数组反向排序,则可以知道如果值较小,则必须在第二部分中搜索。您必须修改的唯一内容是else if

中的条件
else if(srchVal < a[mid]){ //change < to >
    lb = mid + 1;
}

也就是说,一个更好的方法使得该方法更通用,因此可以使比较器更通用:

private static<T> int binarySearch(T[] a, Comparator<T> c, T srchVal){
    int lb = 0;
    int ub = a.length - 1;

    while(lb <= ub){
        int mid = (lb + ub)/2;
        int ci = c.compare(a[mid],srchVal);
        if(ci == 0){
            return mid;
        }
        else if(ci < 0){
            lb = mid + 1;
        }
        else{
            ub = mid - 1;
        }
     }
    return -1;
}

如果您提供反向数组,则只需提供一个Comparator<T>,其-val返回val原始数组的比较器。

答案 2 :(得分:0)

有一个黑客: 1)反转整个数组,以便现在增加顺序数组。 2)应用二进制搜索,然后找到合适的索引。 3)n-index将是你的答案。

答案 3 :(得分:0)

二进制搜索适用于有序集。您的代码假定订单是递增的,但它是反向的。因此,您需要反转条件:

while(lb > ub){

更笼统地说,你可能对方向不了解:

private static int binarySearch(int a[], int srchVal, boolean isAscending){
    int lb = 0;
    int ub = a.length - 1;

    while((lb <= ub) == isAscending){
        int mid = (lb + ub)/2;
        if(a[mid] == srchVal){
            return mid;
        }
        else if(srchVal > a[mid]){
            lb = mid + 1;
        }
        else{
            ub = mid - 1;
        }
     }
    return -1;
}

并默认使用升序:

private static int binarySearch(int a[], int srchVal){
    return binarySearch(a, srchVal, true);
}

但你的情况下降

public static void main(String args[]){
    int i[] = {-7, 15, 21, 22, 43, 49, 51, 67, 81, 84, 89, 95, 97};
    ArrayUtils.reverse(i);
    System.out.println(binarySearch(i, 22), false);
    System.out.println(binarySearch(i, 89), false);
    System.out.println(binarySearch(i, -100), false);
    System.out.println(binarySearch(i, 72), false);
    System.out.println(binarySearch(i, 102), false);
}

答案 4 :(得分:0)

答案 5 :(得分:0)