对于归并排序的思想,步骤,这篇博客讲的十分清楚排序算法c语言描述—归并排序,我就依自己对这个排序算法的理解尝试着进行一些补充(针对非递归实现归并排序)。
void Merge( int *SR , int *TR , int i , int m , int n )
{
int j , k , l ;
for( k = i , j = m + 1 ; i <= m && j <= n ; k++ )
TR[ k ] = SR[ i ] < SR[ j ] ? SR[ i++ ] : SR[ j++ ] ;
if( i <= m )
for( l = 0 ; l <= m - i ; l++ )
TR[ k+l ] = SR[ i+l ] ; //注意这里不能是TR[k++]=SR[i++],否则TR第n个元素不会被赋值,下面同理
if( j <= n )
for( l = 0 ; l <= n - j ; l++ )
TR[ k+l ] = SR[ j+l ] ;
}
void MergePass( int *SR , int *TR , int s , int n )
{
int j , i = 0 ;//如果要从数组下标为1开始排序,令i初值为1即可。
while( i <= n - 2 * s + 1 )
{
Merge( SR , TR , i , i + s - 1 , i + 2 * s - 1 ) ;
i = i + 2 * s ;
}
//是否对i<=n-2*s+1,和i
if( i < n - s + 1 )
Merge( SR , TR , i , i + s - 1 , n ) ;
else
for( j = i ; j <= n ; j++ )
TR[ j ] = SR[ j ] ;
}
void MergeSort1( int *SR )
{
int *TR = ( int * )malloc( sizeof( int ) * 10 ) ;
int k = 1 ;
while( k < 10 )
{
MergePass( SR , TR , k , 10 ) ;
k *= 2 ;
MergePass( TR , SR , k , 10 ) ;
k *= 2 ;
}
}
要彻底弄懂非递归实现归并排序,就要理解MergePass函数。
在刚开始看非递归算法的时候,我对MergePass函数中while,if,else中的i的取值感到迷惑,后来晚上睡觉的时候脑子突然开窍了(你懂的),顿时就豁然开朗了。
void MergePass( int *SR , int *TR , int s , int n )
{
int j , i = 0 ;
while( i <= n - 2 * s + 1 )
{
Merge( SR , TR , i , i + s - 1 , i + 2 * s - 1 ) ;
i = i + 2 * s ;
}
if( i < n - s + 1 )
Merge( SR , TR , i , i + s - 1 , n ) ;
else
for( j = i ; j <= n ; j++ )
TR[ j ] = SR[ j ] ;
}
while循环里执行的是对两个长度都刚好是s的子序列进行合并。
我们可以想象,当while循环执行完毕,剩下的就是不能两两配对的子序列。
这时候就有两种可能:
#include
#include
void Merge( int *SR , int *TR , int i , int m , int n ) ;
void MergeSort1( int *SR ) ;
void MergePass( int *SR , int *TR , int s , int t ) ;
int main( void )
{
int i ;
int SR1[ 10 ] = { 1 , 5 , 3 , 4 , 6 , 46 , 8 , 41 , -2 , 23 } ;
MergeSort1( SR1 ) ;
for( i = 0 ; i < 10 ; i++ )
printf( "%d " , SR1[ i ] ) ; printf( "\n" ) ;
return 0 ;
}
void Merge( int *SR , int *TR , int i , int m , int n )
{
int j , k , l ;
for( k = i , j = m + 1 ; i <= m && j <= n ; k++ )
TR[ k ] = SR[ i ] < SR[ j ] ? SR[ i++ ] : SR[ j++ ] ;
if( i <= m )
for( l = 0 ; l <= m - i ; l++ )
TR[ k+l ] = SR[ i+l ] ;
if( j <= n )
for( l = 0 ; l <= n - j ; l++ )
TR[ k+l ] = SR[ j+l ] ;
}
void MergePass( int *SR , int *TR , int s , int n )
{
int j , i = 0 ;
while( i <= n - 2 * s + 1 )
{
Merge( SR , TR , i , i + s - 1 , i + 2 * s - 1 ) ;
i = i + 2 * s ;
}
if( i < n - s + 1 )
Merge( SR , TR , i , i + s - 1 , n ) ;
else
for( j = i ; j <= n ; j++ )
TR[ j ] = SR[ j ] ;
}
void MergeSort1( int *SR )
{
int *TR = ( int * )malloc( sizeof( int ) * 10 ) ;
int k = 1 ;
while( k < 10 )
{
MergePass( SR , TR , k , 10 ) ;
k *= 2 ;
MergePass( TR , SR , k , 10 ) ;
k *= 2 ;
}
}