合并排序

合并排序就是将两个或多个有序表合并成一个有序表:

#include <stdio.h>
#include <stdlib.h>
void MergeStep(int * a, int * r, int s, int m, int n)  //相邻有序段合并
{
    int i, j, k;
    k = s;
    i = s;
    j = m + 1;
    while(i <= m && j <=n )                               //当两个有序表都结束时,循环比较
    {
        if(a[i] <= a[j])                                           //当较小的元素复制到 R 中
            r[k++] = a[i++];
        else
            r[k++] = a[j++];
    }
    while(i <= m)                                            //将未合并的部分复制到 R 中
        r[k++] = a[i++];
    while(j <= n)
        r[k++] = a[j++];                                    //将未合并的部分复制到 R 中
}

void Mergepass(int * a, int * r, int n, int len)        //完成一遍合并的函数
{
    int s, e;
    s = 0;
    while(s + len < n)                                   //至少有两个有序段
    {
        e = s + 2 * len - 1;
        if(e >= n)                                           //最后一段可能少于len个节点
            e = n - 1;
        MergeStep(a, r, s, s + len - 1, e);     //相邻有序段合并
        s = e + 1;                                         //下一对有序段中左端的开始下标
    }
    if(s < n)                                                //还剩一个有序段,将其从 A 中复制到 R 中
        for( ; s < n; s++)
            r[s] = a[s];    
}

void MergeSort(int * a, int n)
{
    int * p;
    int len = 1;                                          //有序序列的长度
    int f = 0;                                              //变量 f 作标志
    if( !(p = (int *)malloc(sizeof(int) * n)) )  //分配内存空间,保存临时数据
    {
        printf("分配临时内存失败!\n");
        exit(0);
    }
    while(len < n)
    {
        if(f)                                                 //交替地在 A 和 p 之间来回合并
            Mergepass(p, a, n, len);           //调整Mergepass,对 p 合并到 a  
        else
            Mergepass(a ,p ,n ,len);
        len *= 2;
        f = 1 - f;
    }
    if(f)
        for(f = 0; f < n; f++)
            a[f] = p[f];
    free(p);
}

int main()
{
    int a[4] = {4,3,2,1};
    Mergepass(a, 4);
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值