基础排序:归并排序

一、归并算法

2路归并。
采用分治的思想:将数组区间不断二分,直至每个区间只有一个元素。单个元素自然是有序的。然后将有序区间两两合并,最后得到一个有序数组。
用递归来实现分治。

void merge(int *arr, int L1, int R1, int L2, int R2)
{
    // 申请辅助空间用于临时保存合并后的序列
    int *temp = malloc(sizeof(int)*(R2-L1+1)), index = 0;
    // 有序合并左右子区间:如果左右子区间不等长,最后有一方会有剩余元素,直接加入temp。
    int i = L1, j = L2;
    while(i <= R1 && j <= R2)
    {
        if(arr[i] <= arr[j]) temp[index++] = arr[i++];
        else temp[index++] = arr[j++];
    }
    while(i <= R1)  temp[index++] = arr[i++];
    while(j <= R2)  temp[index++] = arr[j++];
    // 将合并后的有序区间放回arr
    for(int k=0; k<R2-L1+1; k++)
    {
        arr[L1+k] = temp[k];
    }
    // 释放申请的辅助空间,避免内存泄露
    free(temp);
}// end of function merge

void mergeSort(int *arr, int left, int right)
{
    //递归终止条件:子区间长度等于1,即left == right,只剩一个元素
    if(left < right)
    {
        // 二分法划分左、右子区间:[left, mid],[mid+1, right]
        // 分别对左右子区间排序
        int mid = left + (right-left)/2;

        mergeSort(arr, left, mid);
        mergeSort(arr, mid+1, right);
        // 合并两个有序左右子区间
        merge(arr, left, mid, mid+1, right);
    }
}// end of function mergeSort

时间复杂度 O ( n l o g n ) O(nlogn) O(nlogn):递归树高 ( l o g 2 n ) + 1 (log_2n)+1 (log2n)+1,每一层中所有元素都参与过比较和移位,代价为 c n cn cn,总代价为 O ( n l o g n ) O(nlogn) O(nlogn)
空间复杂度 O ( n ) O(n) O(n):辅助空间 O ( n ) O(n) O(n),栈深 O ( l o g n ) O(logn) O(logn)

二、测试代码

void printArray(int *arr, int length)
{
    for(int i=0; i<length; i++)
    {
        printf("%d ", arr[i]);
    }
    printf("\n");
}

void test()
{
    int arr[] = {66,12,33,57,64,27,18};
    printArray(arr, sizeof(arr)/sizeof(arr[0]));
    mergeSort(arr, 0,  sizeof(arr)/sizeof(arr[0])-1);
    printArray(arr, sizeof(arr)/sizeof(arr[0]));
}

运行结果:

66 12 33 57 64 27 18
12 18 27 33 57 64 66
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值