简体   繁体   English

3向合并排序C程序

[英]3-way Merge Sort C program

I have trying to "upgrade" my normal merge sort for a school project. 我试图为学校项目“升级”我的常规合并排序。 But my new code seems to not coorporate as it should 但是我的新代码似乎并没有协调

so i have a MergeSort3way function that splits the Array inputed in 3 subArrays then it call itself till the sort is finished but the outputs are far from right. 因此,我有一个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);    
}

} }

After that the merge3way combines them into 1 sigle sorted array 之后,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++;            
     } 
}
  }
} 

Can you suggest me any solution so i can sort as it should i've been trying over 2 hours of moding it and the result are always the same. 您能建议我任何解决方案,以便我进行整理,因为我应该尝试超过2个小时来修改它,并且结果始终相同。 Thanks in advance please no hard feeling as it is my first time using the site. 在此先感谢您,这是我第一次使用该网站,请不要感到难过。

If this is supposed to be an ascending sort, then if (B[i] < C[j]) && (B[i] < D[u]), the code should do A[k] = B[i]. 如果认为这是升序排序,则如果(B [i] <C [j])&&(B [i] <D [u]),则代码应做A [k] = B [i]。

Once the end of B[], C[], or D[] is reached the code needs to switch to a 2 way merge on the remaining two. 一旦到达B [],C []或D []的末尾,代码需要在其余两个代码上切换为2方式合并。 You can swap array names (which are effectively pointers in a called function), to simplify this, so the 2 way merge uses B and C. If the end of B is reached first, then B = C and C = D. If the end of C is reached first, then C = D. If the end of D is reached first, then no array (pointer) assignments are needed. 为了简化此操作,可以交换数组名称(实际上是被调用函数中的指针),因此2方式合并使用B和C。如果先到达B的末尾,则B = C和C =D。首先到达C的末尾,然后C =D。如果首先到达D的末尾,则不需要数组(指针)分配。

Once the end of B or C is reached, then just copy the remaining sub-array. 一旦到达B或C的末尾,则只需复制其余的子数组。

For consistent naming on the indices, I would have used k for D[], and u for A[], but this isn't causing a problem. 为了在索引上保持一致的命名,我将k用于D [],将u用于A [],但这不会引起问题。

I think this part of your code, 我认为您的代码的这一部分,

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++;
 }

needs to change to this: 需要更改为:

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++;
 }

And this portion of your code: 而这部分代码:

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++;

needs to change to something like this: 需要改变的东西是这样的:

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
      }
}

Although, as you said that you had a normal mergesort which you are trying to modify, well, how about if after sorting every 1/3 rd portion of the array, like this: 虽然,正如您所说的那样,您有一个normal mergesort尝试修改的normal mergesort ,但是,如果对数组的第1/3部分进行排序后,如何处理呢?

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

you combine any of the two sorted portions first using normal mergesort , and then combine the result of both of them with the third portion again using normal mergesort . 您首先使用normal mergesort合并两个排序部分中的任何一个,然后使用normal mergesort再次将两个部分的结果与第三部分normal mergesort For example: first merge sorted B with sorted C using normal mergesort , let's call their result BmC , then merge their result BmC with sorted D using normal mergesort , leading us to final merge result: BmCmD . 例如:首先使用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