归并排序算法(介绍+图解+源码+性能)

    此为第四篇,归并排序算法。

归并排序

    “归井”的含义是将两个或两个以上的有序表组合成个新的有序表。假定待排序表含有n个记录,则可将其视为n个有序的子表,每个子表的长度为1 ,然后两两归井,得到 n/2 个长度为2或1的有序表;继续两两归并....... 如此重复,直到合并成1个长度为n的有序表为止,这种排序方法称为2路归并排序

    如下图所示为2路归并排序的一个例子,经过三趟归并后合并成了有序序列:

归并排序算法(介绍+图解+源码+性能)_第1张图片

1.例程

/********************************* 归并排序 *********************************/
#include 
#include 
#include 

// 功能:将前后相邻的两个有序表归并为一个有序表
// 将start ~ middle 和 middl+1 ~ end 归并成一个 start ~ end
// *temp是用来做两个有序表复制时的辅助数组
void merge(int *data, int *temp, int start, int middle, int end) {
    int i = start, j = middle+1, k = start;

    while (i <= middle && j <= end) {         //将小的放入辅助数组temp中
        if (data[i] > data[j]) {
            temp[k++] = data[j++];
        } else {
            temp[k++] = data[i++];
        }
    }
            
    while (i <= middle) {                     //若i有剩余则将剩余的部分直接复制到temp中
        temp[k++] = data[i++];
    }

    while (j <= end) {                        //若j有剩余则将剩余的部分直接复制到temp中
        temp[k++] = data[j++];
    }

    for (i = start;i <= end;i ++) {           //把排好的temp全部复制到data
        data[i] = temp[i];
    }
}

// 功能:将表的前后两部分进行递归分解,然后归并
// start 和 end 可以说是为了方便递归用
int merge_sort(int *data, int *temp, int start, int end) {
    int middle;
    
    if (start < end) {
        middle = start + (end - start) / 2;                 //从中间划分为两个子序列

        merge_sort(data, temp, start, middle);              //对左侧子序列进行递归排序
        merge_sort(data, temp, middle+1, end);              //对右侧子序列进行递归排序

        merge(data, temp, start, middle, end);              //归并
    }
    return 0;
} 

int main() {
    int i = 0;
    int data[] = {23, 64, 24, 12, 9, 16, 53, 57};
    int temp[] = {0};
    int length = sizeof(data) / sizeof(int);

    merge_sort(data, temp, 0, length-1);

    for (i = 0;i < length;i ++) {
        printf("%4d", data[i]);
    }
    printf("\n");
}

2.性能分析

2.1空间复杂度

    在merge函数中,辅助数组temp刚好为n个单元,所以空间复杂度为:O(n)。

2.2时间复杂度

    每趟归并的时间复杂度为O(n),共需进行log2n 趟归并,所以算法的时间复杂度为 O(nlog2n)。

2.3稳定性

    由于merge函数在操作不会改变相同关键字记录的相对次序,所以2路归并排序算法是一种稳定的排序方法。

至此,排序算法笔记已完,下次更新其它专栏的笔记。

个人公众号:拾一札记

参考:

《王道数据结构》

你可能感兴趣的:(#,排序算法,算法,数据结构,排序算法)