归并排序 | 递归 & 非递归 |C语言

在这里插入图片描述

一、递归算法

在这里插入图片描述
在这里插入图片描述

// L = 左边起始位置,R = 右边起始位置,RightEnd = 右边终点位置
void Merge(ElementType A[], ElementType TmpA[], int L, int R, int RightEnd)
{   // 将有序的A[L]~A[R-1]和A[R]~A[RightEnd]归并成一个有序序列
    int LeftEnd, NumElements, Tmp;
    int i;
    
    LeftEnd = R - 1;  // 左边终点位置
    Tmp = L;  // 有序序列的起始位置
    NumElements = RightEnd - L + 1;
    
    while (L <= LeftEnd && R <= RightEnd) {
        if (A[L] <= A[R]) {
            TmpA[Tmp++] = A[L++];  // 将左边元素复制到TmpA
        } else {
            TmpA[Tmp++] = A[R++];  // 将右边元素复制到TmpA
        }
    }
    
    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];  // 将有序的TmpA[]复制回A[]
    }
}

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, L, Center+1, RightEnd);  // 合并两段有序序列
    }
}

void MergeSort(ElmentType A[], int N)
{   // 归并排序
    ElementType *TmpA;
    TmpA = (ElmentType *)malloc(N * sizeof(ElementType));
    
    if (TmpA != NULL) {
        Msort(A, TmpA, 0, N-1);
        free(TmpA);
    }
    else printf("空间不足")}

在这里插入图片描述

二、非递归算法

在这里插入图片描述

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

void Merge_Sort(ElementType A[], int N)
{
    int length;
    ElementType *TmpA;
    
    length = 1;  // 初始化子序列长度
    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 printf("空间不足");
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值