返回

归并排序在代码级深入浅出剖析算法原理及时间复杂度

闲谈

代码实现

public class MergeSort {

    public static void main(String[] args) {
        int[] arr = {10, 7, 8, 9, 1, 5};
        mergeSort(arr, 0, arr.length - 1);
        System.out.println(Arrays.toString(arr));
    }

    public static void mergeSort(int[] arr, int start, int end) {
        if (start >= end) {
            return;
        }
        int mid = (start + end) / 2;
        mergeSort(arr, start, mid);
        mergeSort(arr, mid + 1, end);
        merge(arr, start, mid, end);
    }

    public static void merge(int[] arr, int start, int mid, int end) {
        int[] temp = new int[end - start + 1];
        int i = start;
        int j = mid + 1;
        int k = 0;
        while (i <= mid && j <= end) {
            if (arr[i] <= arr[j]) {
                temp[k] = arr[i];
                i++;
            } else {
                temp[k] = arr[j];
                j++;
            }
            k++;
        }
        while (i <= mid) {
            temp[k] = arr[i];
            i++;
            k++;
        }
        while (j <= end) {
            temp[k] = arr[j];
            j++;
            k++;
        }
        System.arraycopy(temp, 0, arr, start, temp.length);
    }
}

时间复杂度分析

由代码可知,归并排序递归调用的次数为log2N,每次递归调用的时间复杂度为N,因此总时间复杂度为Nlog2N。下面通过master公式进行计算:

  • T(n) = aT(n/b) + d n^c
  • a = 2 ,因为每次递归调用将数组划分为两个大小相等的部分。
  • b = 2 ,因为每次递归调用将数组划分为两个大小相等的部分。
  • c = 1 ,因为merge方法的时间复杂度为O(N)
  • d = 1 ,因为merge方法的时间复杂度为O(N)

代入master公式,可得:

  • T(n) = 2T(n/2) + n
  • T(n) = 2(2T(n/4) + n/2) + n
  • T(n) = 4T(n/4) + 2n
  • T(n) = 8T(n/8) + 4n
  • ...

不断递归下去,最终得到:

  • T(n) = nlog2N

因此,归并排序的时间复杂度为O(nlog2N)

优化方法

归并排序是一种相对高效的排序算法,但仍有优化空间。以下是一些常见的优化方法:

  • 使用归并排序对较小的数组使用插入排序。 当数组规模较小时,插入排序比归并排序更有效率。
  • 使用多线程并行执行归并排序。 当数组规模较大时,可以将数组划分为多个部分,并使用多线程并行执行归并排序。
  • 使用优化的归并排序算法,如Timsort。 Timsort是归并排序的一种变体,它在归并排序的基础上进行了一些优化,使其在某些情况下具有更好的性能。