您的位置:首页 > 其它

二路归并算法非递归C实现

2011-03-20 16:09 288 查看
算法思想是Horowitz E.Sahni S. Fundamentals of Data Structures, 1976上的。二路归并的递归实现相对简单,但是非递归实现却有些绕脑。所以尝试写代码并做一些跟踪,才最终理解了这个算法。  
#include <stdio.h>


#include <stdlib.h>


// X[0] is guard


void Print(int *X, int n)


{


printf("/n");


for(int i=1; i<=n; i++){


printf(" %d", X[i]);


}


}


 


// merge X[l]..X[m], X[m+1]..x
to Z


void MERGE(int* X


, int l/*first-sequence-start-postion, 1-based*/


, int m/*first-sequence-length, 1-based*/


, int n/*last-sequence-position, 1-based*/


, int* Z)


{


printf("/nMERGE(%08X, %d, %d, %d, %08X)", X, l, m, n, Z);


int i, j, k, t;


for(i=l, j=m+1, k=l; i<=m && j<=n; ){


if(X[i]<=X[j]){Z[k++]=X[i]; ++i;}


else{Z[k++]=X[j]; ++j;}


}


 


if(i>m){


printf("/nMerge: i=%d > m=%d", i, m);


for(t=j; t<=n; ++t)


Z[k++] = X[t];


}else{


printf("/nMerge: i=%d <= m=%d", i, m);


for(t=i; t<=m; ++t)


Z[k++] = X[t];


}


}


 


// One pass for sort X[1+l*k]..x[1+l-1+l*k]


void MPASS(int* X, int* Y, int n, int l)


{


printf("/nMPASS(%08X, %08X, %d, %d)", X, Y, n, l);


int i=1;


printf("/nMPASS(): i=%d", i);




while(i<=n-2*l+1){


MERGE(X, i, i+l-1, i+2*l-1, Y);


i=i+2*l;


printf("/nMPASS(): i=%d", i);


}


 


printf("/nMPASS(): i+l-1=%d, n=%d", i+l-1, n);


// merge remaining file of length < 2l


if(i+l-1<n){// "i+l-1"正好是下一个分区的中间值m


// 如果m(=i+l-1)<n, 说明剩下的未归并分区中的数目多于“归并长度的一半”(即l/2)


// 则还需要进行一次归并


MERGE(X, i, i+l-1, n, Y);


}else{


// 否则,不需要再排序,因为这里只有不到本次归并长度一般的数目,显然已经在上一次归并循环中排好序了


// 简单的拷贝即可,等待下一次2倍归并长度的排序


for(int t=i; t<=n; ++t){


Y[t] = X[t];


}


}


Print(Y, n);


}


 


 


void MSORT(int* X, int n)


{


int* Y = (int *)malloc(sizeof(int)*(n+1)/*Guard 1*/);


int l = 1;


 


printf("/nStart sorting!");


Print(X, n);


while(l<n){


MPASS(X, Y, n, l);


l = 2*l;


MPASS(Y, X, n, l);


l = 2*l;


}


free(Y);


printf("/nFinished!");


}


 


int main(){


 


int A[] = {0, 435, 6};


int B[] = {0, 7, 7435, 23, 66, 32, 75, 45, 886, 3456, 34234, 32, 45, 78, 8, 78, 34, 79, 567, 17, 34, 754, 345, 78, 9};


 


MSORT(A, sizeof(A)/sizeof(A[0])-1);


//MSORT(B, sizeof(B)/sizeof(B[0])-1);


 


return 0;


}


.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: