ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

排序算法:递归排序和非递归法(有序子列的归并)

2021-02-05 22:32:03  阅读:165  来源: 互联网

标签:ElementType 子列 递归 int 位置 起始 RightEnd 排序


递归法(有序子列的归并)

/*    有序子列的归并  */
// T = O( N )
/*  L = 左边起始位置,R = 右边起始位置, RightEnd = 右边终点位置  */
void Merge ( ElementType A[], ElementType TmpA[], int L, int R, int RightEnd ) {
    LeftEnd = R - 1;  /* 左边终点位置。假设左右两列挨着   */
    Tmp = L;   /*  存放结果的数组的起始位置  */ 
    NumElements = RightEnd - L + 1;
    
    while ( L <= LeftEnd && R <= RightEnd ) {
        if ( A[L] <= A[R] ) TmpA[Tmp++] = A[L++];
        else                TmpA[Tmp++] = A[R++];
    }
    while ( L <= LeftEnd )  //  直接复制左边剩下的
        TmpA[Tmp++] = A[L++];
    while ( R <= RightEnd )  // 直接复制右边剩下的
        TmpA[Tmp++] = A[R++];
    for ( i=0; i<NumElements; i++, RightEnd-- )
        A[RightEnd] = TmpA[RightEnd];  //  导出
}


/*  递归算法  分而治之  */
//  T = O( NlogN )
void MSort ( ElementType A[], ElementType TmpA[], int L, int RightEnd ) {
    int Center;
    
    if ( L < RightEnd ) {
        
        Center = ( L + RightEnd ) / 2;
        
        MSort ( A, TmpA, L, Center );   //  递归处理左半边
        MSort ( A, TmpA, Center+1, RightEnd );   //递归处理右半边
        
        Merge ( A, TmpA, Center+1, RightEnd );   //  归并
    }
}

/*  统一函数接口   递归排序  */
void Merge_sort ( ElementType A[], int N ) {
    ElementType *TmpA;
    TmpA = malloc(sizeof( ElementType ));
    if ( TmpA != NULL ) {
        MSort ( A, TmpA, 0, N-1 );
        free ( TmpA );
    }
    else  Error ( "空间不足" );
}

非递归法

/*    有序子列的归并  */
// T = O( N )
/*  L = 左边起始位置,R = 右边起始位置, RightEnd = 右边终点位置  */
void Merge ( ElementType A[], ElementType TmpA[], int L, int R, int RightEnd ) {
    
    LeftEnd = R - 1;  /* 左边终点位置。假设左右两列挨着   */
    Tmp = L;   /*  存放结果的数组的起始位置  */ 
    NumElements = RightEnd - L + 1;
    
    while ( L <= LeftEnd && R <= RightEnd ) {
        if ( A[L] <= A[R] ) TmpA[Tmp++] = A[L++];
        else                TmpA[Tmp++] = A[R++];
    }
    
    while ( L <= LeftEnd )  //  直接复制左边剩下的
        TmpA[Tmp++] = A[L++];
    
    while ( R <= RightEnd )  // 直接复制右边剩下的
        TmpA[Tmp++] = A[R++];
    
    for ( i=0; i<NumElements; i++, RightEnd-- )
        A[RightEnd] = TmpA[RightEnd];  //  导出
}

void Merge_pass ( ElementType A[], ElementType TmpA[], int N, int length ) {  // length 为当前有序子列长度
    
    for ( i=0; i <= N-2*length; i += 2*length )
        Merge ( A, TmpA, i, i+length, i+2*length-1 );
    
    if ( i+length < N )             //  归并最后两个子列
        Merge ( A, TmpA, i, i+length, N-1 );
    
    else      //  最后只剩一个子列
        for ( j=i; j < N; j++ ) TmpA[j] = A[j];
}

/*  稳定排序   */
void Merge_sort ( ElementType A[], int N ) {
    
    int length = 1;   //  初始化子列长度
    ElementType *TmpA;
    TmpA = malloc( N*sizeof ( ElementType ));
    
    if ( TmpA != NULL ) {
        
        while ( length < N ) {
            
            Merge_pass ( A, TmpA, N, length );
            length *= 2;
            Merge_pass ( TmpA, A, N, length  );
            length *= 2;
        }
        free ( TmpA );
    }
    
    else Error ( "空间不足" );
}

 

标签:ElementType,子列,递归,int,位置,起始,RightEnd,排序
来源: https://www.cnblogs.com/Pio-GD/p/14380027.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有