归并排序(非递归实现)

注意
1、与递归不同,Merge函数没有T到S的复制,并且S和T得作为参数传递;因为S和T要进行多次交换,最后将排好序的元素存到S;
2、还有TMerge函数中,两两合并要合并到最后两组之前,因为最后两组特殊:(1)可能有大于两组,但不是完整的两组,所以Merge函数要将Rd设置为N-1; (2)可能小于两组,只有一组,则直接将其复制过去即可;
非递归实现原理: 先将间隔length = 1进行相邻的两两合并,再以间隔length = 2*length进行合并,直到 length < N 时结束;

在这里插入图片描述

参考代码:
#include <ctime>
#include <cstdio>
#include <string>
#include <cstring>
#include <iostream>
#include <algorithm>
#define INF 0x3f3f3f3f
#define MAX 1010

using namespace std;

// 左边起始 右边起始 右边终点
// 此时S[L]~S[R-1] S[R]~S[Rd]已经有序了,进行合并
void Merge(int *S, int *T, int L, int R, int Rd)
{
    int k = L, t = L;
    int Ld = R - 1;
    //一方为空退出
    while(L <= Ld && R <= Rd)
    {
        if(S[L] < S[R]) T[k++] = S[L++];
        else T[k++] = S[R++];
    }
    //没空的一方直接复制过去
    while(L <= Ld) T[k++] = S[L++];
    while(R <= Rd) T[k++] = S[R++];
}

void TMerge(int *S, int *T, int N, int length)
{
    int i;
    //合并都得两组合并,所以最后两组可能不够两组,可能只有一组,要特殊处理
    for(i = 0; i <= N - 2*length; i += 2*length)
        Merge(S, T, i, i + length, i + 2*length - 1);
    //若仍然有两组,则将其合并(此时的Rd为N-1)
    if(i + length < N) Merge(S, T, i, i + length, N - 1);
    //若只有一组将其直接复制到T
    else for(int j = i; j < N; j++) T[j] = S[j];
}

int *Init(int N)
{
    int *t;
    t = (int *)malloc(N * sizeof(int));
    return t;
}

void MergeSort(int *S, int N)
{
    //length为当前有序序列的长度,起始有序序列为1
    int length = 1;
    int *T = (int *)malloc(N * sizeof(int));

    //退出后排好序的数据一定存到了S
    while(length < N)
    {
        //先将数据按length为间隔排好序存到T
        TMerge(S, T, N, length);
        length *= 2;
        //再将数据按2*length为间隔排好序存到S
        TMerge(T, S, N, length);
        length *= 2;
    }
}

void Print(int *S, int N)
{
    for(int i = 0; i < N; i++) cout << S[i] <<" ";
}

int main()
{
    int *S = Init(20);

    srand(time(NULL));
    for(int i = 0; i < 20; i++)
    {
        S[i] = rand() % 100;
    }
    MergeSort(S, 20);
    Print(S, 20);
    return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值