归并排序(Merge Sort)简介和代码实现

算法复杂度

时间复杂度:O(nlogn)
空间复杂度:T(n)

算法策略

分而治之

基本逻辑

将相邻的数两两排序,排序好的2个数合并作为一组。
然后再把相邻的两组数两两排序,排序好的两组数合并为新的一组。
直到最后只剩一组,排序完成。

图解

在这里插入图片描述
在这里插入图片描述

代码实现

void merge_sort(int arr[], int len) {
    devide_arr_merge(arr, 0, (len - 1));
    for (int i = 0; i < 9; i++) {
        std::cout << arr[i] << " ";
    }
    std::cout << std::endl;
}

void devide_arr_merge(int arr[], int start, int end) {
    //如果传入数组为空,或者数组内只有1个元素,则返回
    if (arr == NULL || start >= end) {
        return;
    }

    //取中间值
    int middle = (start + end) / 2;
    //分解数组
    devide_arr_merge(arr, start, middle);
    devide_arr_merge(arr, middle + 1, end);

    //分解到1时,两个devide直接返回
    //此时this的start和end为相邻整数,middle == start
    //调用merge将这两个数排序,回到上一层

    //此时,上一层的2个devide执行完毕,上一层的start到middle是有序的,middle+1到end是有序的
    //继续merge,直到所有递归调用完毕,数组变得有序

    //合并排序
    merge(arr, start, middle, end);
}
void merge(int arr[], int start, int middle, int end) {
    int* temp = new int[end - start + 1];//排序好的数组临时放在这里

    int left = start;
    int right = middle + 1;

    for (int i = 0; i < (end - start + 1); i++) {
        if (left > middle) {
            //如果左边的数据已经用完了,此时右边剩下的数都是有序的,且都比已排数更大
            for (int j = right; j <= end; j++) {
                temp[i] = arr[j];
                i++;
            }
            break;
        }
        else if (right > end) {
            //左边没用完,但右边用完了,同理
            for (int j = left; j <= middle; j++) {
                temp[i] = arr[j];
                i++;
            }
            break;
        }
        else if (arr[left] > arr[right]) {
            //左右都还有数,正常排序
            temp[i] = arr[right];
            right++;
        }
        else {
            temp[i] = arr[left];
            left++;
        }
    }

    //排序完毕,将临时数组中的数填回原数组对应的位置
    //因为传参传数组属于引用类型,在函数内部可以直接操作数组本身
    for (int i = 0; i < (end - start + 1); i++) {
        arr[start + i] = temp[i];
    }

    //最后别忘了释放临时数组
    delete[] temp;
}

ps. 代码自己写的,但是写完发现VS出了点问题,网速过慢修复需要好久,又没有单独安装cmake。所以,基本逻辑没啥问题,但是好久没写C++了,细节上不太敢确定,不保证代码能直接跑。

参考资料

归并排序算法
排序算法-归并排序的时间复杂度分析

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值