排序算法之归并排序(递归与非递归实现)C语言实现

对于归并排序的思想,步骤,这篇博客讲的十分清楚排序算法c语言描述—归并排序,我就依自己对这个排序算法的理解尝试着进行一些补充(针对非递归实现归并排序)。

先上代码:

将SR[i…m]和SR[m+1…n]归并成一个有序的TR[i…n]:

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

将SR[]中长度为s的子序列两两合并到TR[]中:

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<n-s+1感到迷惑?不要着急,下面会讲解
    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循环的i的取值:

while循环里执行的是对两个长度都刚好是s的子序列进行合并。
在这里插入图片描述
我们可以想象,当while循环执行完毕,剩下的就是不能两两配对的子序列。
这时候就有两种可能:

  1. 剩下未配对的子序列的长度 > s,那么可以对一个长度 < s的子序列和一个长度刚好 = s的子序列进行配对,即if中执行的代码
  2. 剩下未配对的子序列的长度 <= s,这就意味着他不能分出长度为s的子序列来和另一个子序列进行配对,迫于无奈只能把剩下的子序列全部加入到TR[]数组中去了,即执行else的代码。

接下来是if中的判断语句:i < n - s + 1

在这里插入图片描述

最后就是else

在这里插入图片描述

最后再附上源代码:

#include<stdio.h>
#include<stdlib.h>

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

  • 5
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值