归并排序

思路

将数组对半分到长度为 1 为止,再逆向合并,合并的过程中进行排序。将轮数减少到了 logn。

代码

public class MergeSort{
    public static void mergeSort(int[] arr){
        mergeSort(arr, 0, arr.length - 1);
    }

    private static void mergeSort(int[] arr, int start, int end) {
        if(start < end){
            int mid = (start + end) >>> 1;
            mergeSort(arr, start , mid);
            mergeSort(arr, mid + 1, end);
            merge(arr, start, mid, end);
        }
    }

    private static void merge(int[] arr, int start, int mid, int end) {
        int[] tmp = new int[end - start + 1];
        int p1 = start, p2 = mid + 1, p = 0;

        while(p1 <= mid && p2 <= end) 
        	tmp[p ++] = arr[p1] <= arr[p2] ? arr[p1 ++] : arr[p2 ++];

        while(p1 <= mid)
            tmp[p++] = arr[p1++];

        while(p2 <= end)
            tmp[p++] = arr[p2++];


        for(int i = 0; i < tmp.length; i++)
            arr[start + i] = tmp[i];
    }


    public static void main(String[] args){
        int[] array ={5,8,6,3,9,4,2,1,7};
        mergeSort(array);
        System.out.println(Arrays.toString(array));
    }
}

复杂度分析

时间复杂度

轮数为 logn,每一轮都要对整个数组进行操作(虽然分成了很多小块,但合起来就是整个数组),时间复杂度 O(nlogn)。最好最坏,情况不变。

空间复杂度

单次归并操作开辟的最大空间是 n(最后一次),空间复杂度O(n)。
以前创建的空间会随归并结束而释放。

稳定性分析

稳定

while(p1 <= mid && p2 <= end) {
			//下面是 <= 就会稳定,如果只是 < 就不稳定了
            if (arr[p1] <= arr[p2])
                tmp[p++] = arr[p1++];
            else
                tmp[p++] = arr[p2++];
        }

优势

与快速排序相比,稳定,时间复杂度保持在 O(nlogn)
是外部排序法,数据量太大,无法直接在内存内排序,可以依赖外部存储设备。

适用场景

需要稳定性,数据量大

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值