返回
归并排序在代码级深入浅出剖析算法原理及时间复杂度
闲谈
2023-11-24 19:08:46
代码实现
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是归并排序的一种变体,它在归并排序的基础上进行了一些优化,使其在某些情况下具有更好的性能。