数据结构之排序--归并排序

四 归并排序

归并:把若干个有序的数列, 合成一个有序的数列

如二路归并:

void merge(int d1[], int len1, int d2[], int len2, int tmp[])
{
    int i, j, k;

    i = j = k = 0;

    while (i < len1 && j < len2) {
        if (d1[i] < d2[j])
            tmp[k++] = d1[i++];
        else
            tmp[k++] = d2[j++];
    }

    while (i < len1)
        tmp[k++] = d1[i++];

    while (j < len2)
        tmp[k++] = d2[j++];
}


1, 二路归并排序

迭代法:

把待排数列(长度为len)中的每个元素看作一个有序数列,两两归并, 再以相邻的两个元素为一个有序数列,两两归并,重复以上步骤,直到有序数列的长度大于或等于len。

void merge(int d1[], int len1, int d2[], int len2, int d[])
{
    int i, j, k;
    int tmp[len1 + len2];

    i = j = k = 0;

    while (i < len1 && j < len2) {
        if (d1[i] < d2[j])
            tmp[k++] = d1[i++];
        else
            tmp[k++] = d2[j++];
    }   

    while (i < len1)
        tmp[k++] = d1[i++];

    while (j < len2)
        tmp[k++] = d2[j++];

    for (i = 0; i < k; i++)    // k 改为k-1可以吗? 不可以!k是从0开始,且tmp[k-1]有值
        d[i] = tmp[i];
}

void merge_sort(int d[], int len)
{
    int i; //遍历数列
    int gap = 1; //合并前一组数列的长度

    while (gap < len) {
        for (i = 0; i < len - 2 * gap; i = i + 2 * gap)
            merge(d + i, gap, d + i + gap, gap, d + i); 

        if (len - i > gap)
            merge(d + i, gap, d + i + gap, len - i - gap, d + i); 

        gap = gap * 2;
    }   
}


递归法:

把前后两个有序序列“归并”成一个有序序列

前、后两个有序序列,又由“归并排序(递归)”得来!


(递归法)由整个有序往前推理(往无序的方向推理,也是初始的方向)(由“果”到“因”,所以应用递归算法时,可以把结果看作已经实现)!

(迭代法)由无序往有序的方向推理(由“因”到“果”)

void merge_rec_sort(int d[], int len)
{
    if (len <= 1)
        return ;

    merge_rec_sort(d, len / 2); 
    merge_rec_sort(d + len / 2, len - len / 2); 

    merge(d, len / 2, d + len / 2, len - len / 2, d); 
}

注:归并排序是稳定的排序

      时间复杂度最好最坏都为O(nlgn)


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值