这种合并排序有什么问题?

时间:2014-12-15 10:41:17

标签: java sorting groovy mergesort

int[] input = [6,5,4,3,2,1]
mergeSort(input,0,input.length)

void mergeSort(int[] A,int p,int r){
    if(p < r){
        int q = (int) Math.floor((p+r)/2)
        mergeSort(A,p,q)
        mergeSort(A,q+1,r)
        merge(A,p,q,r)
    }
}

void merge(int[] A,int p,int q,int r){
    int i = 0
    int j = 0
    int n1 = q - p + 1
    int n2 = r - q
    int[] L = new int[n1]
    int[] R = new int[n2]
    for(;i<n1;i++){ L[i] = A[p+i-1] }
    for(;j<n2;j++){ R[j] = A[q+j] }
    i = j = 0
    for(int k = p; k < r; k++){
        if(L[i] <= R[j]){ A[k] = L[i++] }
        else{ A[k] = R[j++] }
    }
}  

这是Introduction to Algorithms本书中合并排序的直接实现。虽然它看起来是正确的,但它以ArrayIndexOutOfBounds异常结束。

我一直试图调试它但不能。我想知道出了什么问题以及如何纠正错误。

可运行示例:http://ideone.com/GhuuSd

2 个答案:

答案 0 :(得分:4)

首先,虽然这是Groovy,因此@Useless强调的否定索引不会引发异常,但这表明存在问题。

我认为你有两个问题:警告:我不熟悉“算法简介”中的确切表述

  1. 您在A中填充L和R的指数偏离一个 - 它们应该是[p + i](从而避免可能的负指数问题)和[q + j + 1]。 请注意,此修订需要传入length-1作为r
  2. 的起始参数
  3. 在你底部的测试中确定用于重新填充A元素的L和R中的哪一个,你不检查i或j是否超出了那些数组的长度(即i> = n1或j> = n2)。在这些情况下(即L或R中的一个已经“耗尽”成员),您应该使用另一个数组。
  4. 下面的代码适用于您的示例,我没有对其进行过广泛的测试,但是已经尝试了重复数字,负面等情况,并认为它应该坚持下去:

    int[] input = [6,5,4,3,2,1]
    mergeSort(input,0,input.length-1)
    System.out.println(Arrays.toString(input))     
    
    void mergeSort(int[] A,int p,int r){
        if(p < r){
            int q = (int) Math.floor((p+r)/2)
            mergeSort(A,p,q)
            mergeSort(A,q+1,r)
            merge(A,p,q,r)
        }
    }
    
    void merge(int[] A,int p,int q,int r) {
        int i = 0
        int j = 0
        int n1 = q - p + 1
        int n2 = r - q
        int[] L = new int[n1]
        int[] R = new int[n2]
        for(;i<n1;i++){ L[i] = A[p+i] }
        for(;j<n2;j++){ R[j] = A[q+j+1] }
        i = j = 0
        for(int k = p; k <= r; k++){
            if(j >= n2 || (i < n1 && L[i] < R[j] )) { A[k] = L[i++] }
            else{ A[k] = R[j++] }
        }    
    }
    

答案 1 :(得分:1)

int i = 0
...
for(;i<n1;i++){ L[i] = A[p+i-1] }

第一次迭代时A的索引是什么,其中p为零?