3路合并排序C计划

时间:2017-10-01 15:38:11

标签: c sorting merge

我试图"升级"我对学校项目的正常合并排序。但我的新代码似乎不应该合作,因为它应该

所以我有一个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个sigle排序数组

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小时的方式进行排序,结果总是一样的。提前致谢,请不要有任何难过的感觉,因为这是我第一次使用该网站。

2 个答案:

答案 0 :(得分:0)

如果这应该是升序排序,那么如果(B [i]&lt; C [j])&amp;&amp; (B [i]&lt; 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 [],但这不会导致问题。

答案 1 :(得分: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++;
 }

需要改为:

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,那么,如果在对数组的每个1/3部分进行排序之后,如果这样:

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

首先使用normal mergesort组合两个已排序部分中的任何一个,然后使用normal mergesort再次将它们的结果与第三部分组合。例如:首先使用sorted Bsorted C合并normal mergesort,让他们调用他们的结果BmC,然后将他们的结果BmC与{{1}合并使用sorted D,引导我们进入最终合并结果:normal mergesort