簡體   English   中英

這種合並排序有什么問題?

[英]What is wrong with this merge sort?

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

首先,盡管這是Groovy,因此@Useless突出顯示的負索引不會引發異常,但這表明存在問題。

我認為您有兩個問題: 注意:我對“算法簡介”中的確切介紹不熟悉

  1. 您在A中填充L和R的索引相差一-它們應該為[p + i](從而避免可能出現的負索引問題)和[q + j + 1]。 請注意,通過此修訂,您需要傳入長度1作為r的起始參數
  2. 在底部的測試中確定要在L和R中使用哪個L和R來重新填充A的元素時,您不會檢查i或j是否超出了這些數組的長度(即i> = n1或j> = n2 )。 在這些情況下(即L或R中的一個成員“用完”了),您應該使用另一個數組。

下面的代碼適用於您的示例,我尚未對其進行廣泛的測試,但是嘗試了帶有重復數字,負數等的案例,並認為它應該成立:

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++] }
    }    
}
int i = 0
...
for(;i<n1;i++){ L[i] = A[p+i-1] }

第一次迭代中A的索引是多少,其中p為零?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM