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

来源:互联网 发布:阿里云系统盘如何扩容 编辑:程序博客网 时间:2024/05/21 12:41

四 归并排序

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

如二路归并:

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)