簡體   English   中英

3向合並排序C程序

[英]3-way Merge Sort C program

我試圖為學校項目“升級”我的常規合並排序。 但是我的新代碼似乎並沒有協調

因此,我有一個MergeSort3way函數,該函數將輸入的數組拆分為3個子數組,然后調用它自己,直到排序完成,但輸出距離正確為止。

void Mergesort3way(int A[],int n){
//Sort array A with divition of 3
int B[n/3];
int C[n/3];
int D[n/3];
int i,c;

if(n>1){
    for(i=0;i<n/3;i++){
        B[i]=A[i];
    }
    for(i=n/3;i<2*n/3;i++){
        c= i-n/3;
        C[c]=A[i];
    }
    for(i=2*n/3;i<n;i++){
        c=i-(2*n/3);
        D[c]=A[i];
    }

Mergesort3way(B,n/3);
Mergesort3way(C,n/3);
Mergesort3way(D,n/3);
int bn = sizeof(B)/sizeof(B[0]);
int cn = sizeof(C)/sizeof(C[0]);
int dn = sizeof(D)/sizeof(D[0]);
Merge3way(B,C,D,A,bn,cn,dn);    
}

}

之后,merge3way將它們合並為1個單根排序數組

void Merge3way(int B[],int C[],int D[],int A[],int p,int q,int r){
int i=0,j=0,u=0,k=0;

while(i<p && j<q && u<r){
    if(B[i]<C[j]){
        if(B[i]<D[u]){
            A[k]=D[u];
            u++;
        }else{
            A[k]=B[i];
            i++;
        }
    }else{
        if(C[j]<D[u]){
          A[k]=D[u];
          u++;  
        }else{
          A[k]=C[j];
          j++;
        }
    }
    k++;
 }
int all = p+q+r;    
if(i==p){
    if(u==r){
     while(j<q && k<all){
        A[k]=C[j];
        k++;
        j++;            
     } 
    }else{
        while(u<r && k<all){
        A[k]=D[u];
        k++;
        u++;
        }
    }
}else if(j==q){
    if(u==r){
     while(i<p && k<all){
        A[k]=B[i];
        k++;
        i++;            
     } 
}
  }
} 

您能建議我任何解決方案,以便我進行整理,因為我應該嘗試超過2個小時來修改它,並且結果始終相同。 在此先感謝您,這是我第一次使用該網站,請不要感到難過。

如果認為這是升序排序,則如果(B [i] <C [j])&&(B [i] <D [u]),則代碼應做A [k] = B [i]。

一旦到達B [],C []或D []的末尾,代碼需要在其余兩個代碼上切換為2方式合並。 為了簡化此操作,可以交換數組名稱(實際上是被調用函數中的指針),因此2方式合並使用B和C。如果先到達B的末尾,則B = C和C =D。首先到達C的末尾,然后C =D。如果首先到達D的末尾,則不需要數組(指針)分配。

一旦到達B或C的末尾,則只需復制其余的子數組。

為了在索引上保持一致的命名,我將k用於D [],將u用於A [],但這不會引起問題。

我認為您的代碼的這一部分,

while(i<p && j<q && u<r){
    if(B[i]<C[j]){
        if(B[i]<D[u]){
            A[k]=D[u];
            u++;
        }else{
            A[k]=B[i];
            i++;
        }
    }else{
        if(C[j]<D[u]){
          A[k]=D[u];
          u++;  
        }else{
          A[k]=C[j];
          j++;
        }
    }
    k++;
 }

需要更改為:

while(i<p && j<q && u<r){
    if(B[i]<C[j]){
        if(B[i]<D[u]){
            A[k]=B[i];
            i++;
        }else{
            A[k]=D[u];
            u++;
        }
    }else{
        if(C[j]<D[u]){
          A[k]=C[j];
          j++;  
        }else{
          A[k]=D[u];
          u++;
        }
    }
    k++;
 }

而這部分代碼:

if(i==p){
    if(u==r){
     while(j<q && k<all){
        A[k]=C[j];
        k++;
        j++;            
     } 
    }else{
        while(u<r && k<all){
        A[k]=D[u];
        k++;
        u++;
        }
    }
}else if(j==q){
    if(u==r){
     while(i<p && k<all){
        A[k]=B[i];
        k++;

需要改變的東西是這樣的:

if (i < p && j < q){
  # append the result of normal merge of remaining elements of B and C to A
} else if (j < q && u < r) {
  # append the result of normal merge of remaining elements of C and D to A
} else if (i < p && u < r) {
  # append the result of normal merge of remaining elements of B and D to A
} else {
      if (i == p && j == q && u < r){
         # append remaining elements of D to A
      } else if (i < p && j == q && u == r){
         # append remaining elements of B to A
      } else if (i == p && j < q && u == r){
         # append remaining elements of C to A
      }
}

雖然,正如您所說的那樣,您有一個normal mergesort嘗試修改的normal mergesort ,但是,如果對數組的第1/3部分進行排序后,如何處理呢?

Mergesort3way(B,n/3);
Mergesort3way(C,n/3);
Mergesort3way(D,n/3);

您首先使用normal mergesort合並兩個排序部分中的任何一個,然后使用normal mergesort再次將兩個部分的結果與第三部分normal mergesort 例如:首先使用normal mergesortsorted Bsorted C合並,讓我們將其稱為結果BmC ,然后使用normal mergesort將其結果BmCsorted D合並,使我們normal mergesort最終合並結果: BmCmD

暫無
暫無

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

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