二路归并算法非递归C实现
2011-03-20 16:09
288 查看
算法思想是Horowitz E.Sahni S. Fundamentals of Data Structures, 1976上的。二路归并的递归实现相对简单,但是非递归实现却有些绕脑。所以尝试写代码并做一些跟踪,才最终理解了这个算法。
.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; }
#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; }
相关文章推荐
- 二路归并算法的实现
- 二路归并算法的实现方法,用到vector容器
- 二路归并2算法的java实现(普通方法)
- 白话经典算法系列之五 归并排序的实现
- 白话经典算法系列之五 归并排序的实现
- 常见的五类排序算法图解和实现(归并类:二路归并排序)
- 【算法】归并--C语言实现归并排序递归算法
- 【算法】归并排序的java实现
- 微软笔试题 大型文件外部排序(二路归并和k路归并的实现和比较)
- 白话经典算法系列之五 归并排序的实现
- 算法系列(四)归并排序及其改进(java实现)
- 简单归并算法-有序数组合并算法实现
- 白话经典算法系列之五 归并排序的实现
- 白话经典算法系列之五 归并排序的实现
- 白话经典算法系列之五 归并排序的实现
- 白话经典算法系列之五 归并排序的实现(讲的真好)(转载)
- SortedList排序列表 算法实现 -- (实现了两个有序链表的归并排序功能)
- 白话经典算法系列之五 归并排序的实现
- 白话经典算法系列之五 归并排序的实现
- 实现一个简单的c++ list容器(含sort排序 链表归并算法实现)