Hello,World…… 排序:归并排序

 

 
  
/* *
* @author Xiang Shouding <fansekey@gmail.com>
* @time 2010-4-27 12:21:55
* @desc 归并排序的实现
*/

 

 

一,归并算法:
算法M(两路合并)算法把有序序列X1 ≤ X2 ≤ ... ≤ Xn 和 Y1 ≤ Y2 ≤ ... ≤ Ym 合并成单一序列Z1 ≤ Z2 ≤ ... ≤ Zm+n
M1. [初始化]    置i ←  1, j ←  1, k ←  1
M2. [找较小者]  如果Xi ≤ Yj, 则转到步骤M3, 否则转到M5。
M3. [出处Xi]    置Zk ←  Xi, k ← k + 1, i ← i + 1。如果i ≤ m, 则返回M2
M4. [传送Yj, ..., Ym] 置(Zk, ..., Zm+n) ← (Yj, ..., Yn)并终止此算法
M5. [出处Yj]    置Zk ←  Yj, k ← k + 1, j ← j + 1。如果j ≤ n, 则返回M2
M6. [传送Xi, ..., Xn] 置(Zk, ..., Zm+n) ← (Xi, ..., Xn)并终止此算法
归并实现:

 

ContractedBlock.gif ExpandedBlockStart.gif 代码
 
   

void merge( int * l, int p, int q, int r)
{
int n = q - p + 1 ;
int m = r - q;
int * L = ( int * ) malloc(n * sizeof ( int ));
int * R = ( int * ) malloc(m * sizeof ( int ));
int i;
int j;
int k;
/* *
* init array
*/
memset(L,
0 , n);
memset(R,
0 , m);
for (i = 0 ; i < n; i ++ ) {
L[i]
= l[p + i];
}
for (j = 0 ; j < m; j ++ ) {
R[j]
= l[q + j + 1 ];
}
i
= 0 ;
j
= 0 ;
k
= p;
while (i < n && j < m) {
if (L[i] <= R[j])
l[k
++ ] = L[i ++ ];
else
l[k
++ ] = R[j ++ ];
}
while (i < n)
l[k
++ ] = L[i ++ ];
while (j < m) {
l[k
++ ] = R[j ++ ];
}
free(L);
free(R);
}

 

 

 

二,归并排序

 

 
  
void merge_sort( int * l, int p, int r)
{
int q;
q
= (r + p) / 2 ;
if (p < r) {
merge_sort(l, p, q);
merge_sort(l, q
+ 1 , r);
merge(l, p, q, r);
}
}

 

三,测试

ContractedBlock.gif ExpandedBlockStart.gif 代码
 
   
int main( int argc, char * argv[])
{
int x[ 10 ] = { 1 , 3 , 2 , 3 , 4 , 22 , 5 , 6 , 99 , 80 };
int i;
merge_sort(x,
0 , 9 );
printf(
" ------Result------\n " );
for (i = 0 ; i < 10 ; i ++ )
printf(
" l[%d] = %d " , i, x[i]);
printf(
" \n " );
return 0 ;
}

 

 

四,归并过程

 

2010042712282997.png

关于画图软件 Graphviz
在Ubuntu下安装 apt-get install graphviz

五,上图merge_sort.dot文件

 

ContractedBlock.gif ExpandedBlockStart.gif 代码
 
   
digraph G {
node [shape
= record, height = . 1 ];
node1 [label
= " 1|2|3|3|4|5|6|22|80|99 " ];
node21 [label
= " 1|2|3|3|4 " ];
node22 [label
= " 5|6|22|80|99 " ];

node31 [label
= " 1|2|3 " ];
node32 [label
= " 3|4 " ];
node33 [label
= " 5|6|22 " ];
node34 [label
= " 80|99 " ];

node41 [label
= " 1|3 " ];
node42 [label
= " 2 " ];
node43 [label
= " 3 " ];
node44 [label
= " 4 " ];
node45 [label
= " 5|22 " ];
node46 [label
= " 6 " ];
node47 [label
= " 99 " ];
node48 [label
= " 80 " ];

node51 [label
= " 1 " ];
node52 [label
= " 3 " ];
node53 [label
= " 22 " ];
node54 [label
= " 5 " ];

node51
-> node41;
node52
-> node41;

node53
-> node45;
node54
-> node45;

node41
-> node31;
node42
-> node31;
node43
-> node32;
node44
-> node32;
node45
-> node33;
node46
-> node33;
node47
-> node34;
node48
-> node34;

node31
-> node21;
node32
-> node21;
node33
-> node22;
node34
-> node22;

node21
-> node1;
node22
-> node1;
}

 

生成命令:dot -Tpng merge_sort.dot -o merge_sort.png

六, 源码下载
merge_sort.c : http://www.uushare.com/user/mobey/file/2911821
merge_sort.dot : http://www.uushare.com/user/mobey/file/2911824

转载于:https://www.cnblogs.com/fansekey/archive/2010/04/27/mergeSort.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值