MergeSort归并排序

本文深入介绍了归并排序算法,基于分治策略实现高效排序。通过递归分解数组,再合并有序子数组完成排序过程。文章提供了详细的代码示例,解释了时间复杂度为O(NlogN)的原因。

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

MergeSort归并排序

@(算法)
本节介绍MergeSort,归并排序是基于分治思想的,即divide-and-conquer
递归的将一个数组元素不断二分,等到实在不能分为止,开始对小数组排序,并将两个小数组merge成更大的已排序数组,直到原数组排好序为止。
MergeSort算法的时间复杂度为 O(NlogN)


先上MergeSort的代码,对算法的思路有个大致的了解:

public class Merge {
    private static Comparable[] aux;

    public static void sort(Comparable[] a) {
        aux = new Comparable[a.length];
        sort(a, 0, a.length - 1);
    }

    private static void sort(Comparable[] a, int lo, int hi) {
        if (hi <= lo) return;
        int mid = lo + (hi - lo) / 2;
        sort(a, lo, mid);
        sort(a, mid + 1, hi);
        merge(a, lo, mid, hi);
    }

    public static void merge(Comparable[] a, int lo, int mid, int hi) {
        int i = lo, j = mid + 1;
        for (int k = lo; k <= hi; k++)
            aux[k] = a[k];
        for (int k = 0; k < hi; k++) {
            if (i > mid) a[k] = aux[i++];
            else if (j > lo) a[k] = aux[j++];
            else if (less(aux[j], aux[i])) a[k] = aux[j++];
            else a[k] = aux[i++];
        }
    }

    private static boolean less(Comparable v, Comparable w) {
        return v.compareTo(w) < 0;
    }

    private static void exch(Comparable[] a, int i, int j) {
        Comparable t = a[i];
        a[i] = a[j];
        a[j] = t;
    }
}

举个栗子,当需要对一个长度为16的数组进行归并排序时,程序的执行顺序为:
这里写图片描述
程序在执行 sort() 方法时递归地将数组二分,直到细分的小数组只有两个元素为止,此时程序跳出最内层的递归,开始执行最内层递归的 merge() 方法。
例如:

private static void sort(Comparable[] a, int lo, int hi) {
    if (hi <= lo) return;//1
    int mid = lo + (hi - lo) / 2;//2
    sort(a, lo, mid);//3
    sort(a, mid + 1, hi);//4
    merge(a, lo, mid, hi);//5
}

第一次分到只有两个元素时是sort(a,0,1),代入sort()中,if()不执行,mid=0;代入sort(a,0,0),此时进入if()语句程序return,此时触发了递归终止条件,开始跳出递归慢慢往外层执行,语句3sort(a,0,0)执行完,执行语句4sort(a,1,1)也是return,执行merge(a,0,0,1),执行完后,此时sort(a,0,1)执行完了,开始执行语句4sort(a,2,3)…….


为什么MergeSort复杂度为O(NlgN)

从树的角度来分析:
这里写图片描述
如上图所示,这里默认以数组长度N是2的整数次方,及2x =N
这里插播一下树的相关知识点:from Wikipedia
- 树的深度:对于任意节点i,i的深度为从根到i的唯一路径长,根的深度为0;
- 树的高度:对于任意节点i,i 的高度为从i到一片树叶的最长路径长,叶子节点的高度为0.
这里写图片描述

当数组长度为N时,树有 n=lgN 层,从根节点往下,每层分别为 0,1,2,.....n1 ,每层用 k 表示。
由上图可以看到,第k层有2k个子数组,第 k 层每个子数组的长度为2n-k,每个子数组merge()时比较的次数最多为2n-k,所以每层花费为2k*2n-k=2n,总共n层,总花费为n*2n,n=lgN,带入得到总花费为NlgN.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值