归并排序的递归实现

归并排序调用接口:

void MergeSort_rec(RcdSqList& L)
{// 对顺序表L作2-路归并排序(递归实现)
    RcdType* R;
    R = (RcdType*)malloc((L.length + 1) * sizeof(RcdType)); // 分配辅助空间
    MSort_rec(L.length, L.rcd, R, 0, 1, L.length);  // 对L.rcd[1.. L.length]归并排序
    free(R);
}

实现归并排序功能的函数主体:

void MSort_rec(int length, RcdType R1[], RcdType R2[], int i, int s, int t) 
{    
    // 对R1[s..t]归并排序,若i%2==1,则排序后的记录存入R2[s..t],否则存入R1[s..t]

//--------------------test code bigin---------------------------------------- 
    printParam(length, R1, R2, i, s, t);
//--------------------test code end------------------------------------------

    // 当s与t相等的时候
    // 说明当前划分的区域中仅有一个元素
    // 这是划分的结束条件
    // 无需再次划分
    if (s == t)
    {
        // 当当前划分的区域仅有一个元素的时候
        // 需要判断R1和R2两个数组哪一个是目标数组、哪一个是辅助数组
        // 由于在下面将要调用的Merge函数中
        // i控制了要将哪个数组中的数据排序后放入另外一个数组
        // 而在上一层的MSort_rec函数中
        // i的值为i-1
        // 那么就可以衍生出以下两种情况
        
        // 第一种情况:(i - 1) % 2 == 0
        // 这种情况说明在本层的MSort_rec函数执行完毕之后
        // 要将R2中的数据排序,排序完成之后存储到R1中
        // 那么就需要将本次划分的数据存入R2数组,使得R2数组中的数据最新
        // 然后才能以R2为数据源调用Merge函数

        // 第二种情况:i % 2 == 0
        // 这种情况说明在本层的MSort_rec函数执行完之后
        // 要将R1数组中的数据排序,排序完成之后存储在R2中
        // 那么理论上就需要将本次划分的数据存入R1数组,以达到更新R1数组中的数据的目的
        // 但是由于划分始终是在R1数组中进行的,因此R1数组中的数据可以不用更新

        if (1 == i % 2){
            R2[s] = R1[s];
        }
        
    }
    else
    {
        // 练习1:进行归并排序的递归实现
        // 将当前的序列分为两部分,以mid为分割点
        int mid = (s + t) / 2;
        // 对前半部分进行2-路归并排序
        MSort_rec(length, R1, R2, i+1, s, mid);
        // 对后半部分进行2-路归并排序
        MSort_rec(length, R1, R2, i+1, mid+1, t);

        // 判断要将排序之后的记录存入哪个数组
        if(1 == i % 2){
            Merge(R1, R2, s, mid, t);
        }
        else{
            Merge(R2, R1, s, mid, t);
        }
    }

//--------------------test code bigin---------------------------------------- 
    printParam(length, R1, R2, i, s, t);
//--------------------test code end------------------------------------------

}
void Merge(RcdType SR[], RcdType TR[], int i, int m, int n) 
{   // 将相邻的有序区间SR[i..m]和SR[m+1..n]归并为有序的TR[i..n]
    int k, j;
    for (j = m + 1, k = i; i <= m && j <= n; ++k)
    { // 将SR中记录按关键字从小到大地复制到TR中

        //练习3:如果 <= 改为 <,会对归并排序造成什么影响?
        if (SR[i].key <= SR[j].key) 
            TR[k] = SR[i++];
        else
            TR[k] = SR[j++];
    }
    while (i <= m) // 将剩余的 SR[i..m] 复制到TR
        TR[k++] = SR[i++];
    while (j <= n) // 将剩余的 SR[j..n] 复制到TR
        TR[k++] = SR[j++];

}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值