【排序】归并排序

本文介绍归并排序,它利用归并思想和分治策略实现排序。主方法将数组分成左右两部分递归排序,再用merge操作合并。其时间复杂度为O(N * logN),通过Master公式分析得出,且避免了比较行为的浪费。额外空间复杂度为O(N),因merge使用辅助数组。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

归并排序

归并排序(MERGE-SORT) 是利用归并的思想实现的排序方法, 该算法采用经典的分治(divide-and-conquer)策略(分治法将问题分(divide)成一些小的问题然后递归求解, 而治(conquer)的阶段则将分的阶段得到的各答案"修补"在一起, 即分而治之)。

1) 整体就是一个简单递归, 左边排好序、 右边排好序、 合并左边和右边让其整体有序
2) 让其整体有序的过程里用了外排序方法

思路

1.主方法merSort将原来的部分分成左边部分和右边部分,对这两部分进行递归,递归完成后进行merge合并操作
2.merge操作将两个部分的的元素排序好写入辅助数组,完成后再将辅助数组中的值拷贝到原数组的对应位置

代码

    public void mergeSort(int[] arr) {
        if (arr == null || arr.length < 2) return;
        mergeSort(arr, 0, arr.length - 1);
    }

    public void mergeSort(int[] arr, int L, int R) {
        if (L == R) return;
        int mid = L + ((R - L) >> 1);
        mergeSort(arr, L, mid);
        mergeSort(arr, mid + 1, R);
        merge(arr, L, R, mid);

    }

    public void merge(int[] arr, int L, int R, int M) {
        int[] temp = new int[R - L + 1]; //辅助数组
        int i = 0; //变量i给辅助数组使用
        int p1 = L;
        int p2 = M + 1;
        while (p1 <= M && p2 <= R) {
            temp[i++] = arr[p1] <= arr[p2] ? arr[p1++] : arr[p2++];
        }
        while (p1 <= M) {
            temp[i++] = arr[p1++];
        }
        while (p2 <= R) {
            temp[i++] = arr[p2++];
        }
        //将结果拷贝到原数组中
        for (int j = L; j <= R; j++) {
            arr[j] = temp[j - L];
        }
    }

时间复杂度

O (N * logN)

Master公式

对递归的时间复杂度计算涉及到Master公式(Master公式是用来解决递归问题时间复杂度的公式)

记录主方法的表现形式:

 T [n] = aT[n/b] +O(N^d)

①当d<logb a时,时间复杂度为O(n^(logb a))
②当d=logb a时,时间复杂度为O((n^d)*logn)
③当d>logb a时,时间复杂度为O(n^d)

其表示的意义是n表示问题的规模,a表示递归的次数也就是生成的子问题数,b表示每次递归是原来的1/b之一个规模,f(n)表示分解和合并所要花费的时间之和。

然后我们来分析一下归并排序的时间复杂度:
a=2 每次生成的子问题数为2
b= 2 每次递归是原来1/2的规模
d=1 递归过程中除了递归部分其他部分使用的时间为O(N)

所以此时d= logb a 时间复杂度为O((n^1) * logn)=O (N * logN)

为什么时间复杂度能够达到O(N *logN)

简单排序为什么是O(N^2),因为浪费了大量的比较行为,遍历1次只搞定了一个数,每一轮的比较都是独立,前面的比较信息被丢弃了但是归并排序没有浪费比较行为,比较行为信息被留下来了变成了整体有序的部分,比较信息实际通过已经排序好的部分向上传递给将要排序的部分。

额外空间复杂度

递归过程中merge方法使用到辅助数组,使用完之后回收,数组的最大长度等于原数组的长度,所以额外空间复杂度为O(N)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值