二进制搜索和插入排序

时间:2014-03-01 02:10:40

标签: java algorithm sorting recursion

我的insertInOrder方法错误(它向后打印数字列表)。我正在阅读一个数字列表,我想使用插入排序算法使用二进制搜索的索引位置按升序对数字进行排序。我不太确定如何解决这个问题,非常感谢帮助。

static void insertInOrder( int[] arr, int cnt, int newVal ) {

    int index = bSearch( arr, 0, arr.length-1, newVal) ;
    if (index < 0) {
        index  = -1 - index ;
    }
    for ( int i = cnt; i >= index+1 ; --i) {
       arr[i] = arr[i-1];
    }

    arr[index] = newVal;
}


public static int bSearch(int[] a, int lo, int hi, int key) {
    int mid = (lo+hi)/2;
    if(lo>hi)
        return -1;
    else if (a[mid]==key)
        return mid;
    else if (a[mid]<key)
        return bSearch(a, mid+1, hi, key);
    else
        return bSearch(a, lo, mid-1, key);
}

Reading in: 5 13 7 9 21
Current Output: 21 9 7 13 5
Desired Output: 5 7 9 13 21

这是我主要的

中的insertInOrder
    int[] arr = new int[INITIAL_CAP];
    int arrCnt= 0;
    while (infile.hasNextInt())
    {
        if ( arrCnt==arr.length )
            arr = doubleMyLength(arr);
        insertInOrder( arr, arrCnt, infile.nextInt() );
        ++arrCnt;
    }
    infile.close();

    arr = trimMyLength( arr, arrCnt );
    System.out.println("Sorted array of " + arr.length + " ints from " + args[0] + " after insert in order:" );
    printArray( arr );  // we trimmed it so count == length so we don't bother to pass in count

2 个答案:

答案 0 :(得分:0)

如果在数组中找不到newVal(很可能发生这种情况),则bSearch()会返回-1。然后,insertInOrder()始终将项目插入位置index = -1 - index,即0。这就是结果错误的原因。

为了使其正确,您的bSearch()需要返回值大于newVal的最小索引。

答案 1 :(得分:0)

您的代码中存在两个问题。正如@timrau所指出的那样,如果找不到条目,​​则从二进制搜索方法返回错误的值-1。您应该返回-lo - 1。 (这是您应该插入值的点 - 返回一个负值用于表示在二进制搜索中找不到该值。但在您的情况下,您不关心在排序列表中获取重复项,因此您也可以直接返回lo。)

其次,将错误的数组长度传递给二进制搜索方法。它应该是cnt - 1而不是arr.length - 1

代码变为:

static void insertInOrder(int[] arr, int cnt, int newVal) {
    int index = bSearch(arr, 0, cnt - 1, newVal);
    if (index < 0) {
        index = -1 - index;
    }
    for (int i = cnt; i >= index + 1; --i) {
        arr[i] = arr[i - 1];
    }

    arr[index] = newVal;
}

public static int bSearch(int[] a, int lo, int hi, int key) {
    int mid = (lo + hi) / 2;
    if (lo > hi)
        return -lo - 1;
    else if (a[mid] == key)
        return mid;
    else if (a[mid] < key)
        return bSearch(a, mid + 1, hi, key);
    else
        return bSearch(a, lo, mid - 1, key);
}