歸併排序的介紹
歸併排序(英語:Merge sort,或Mergesort),是創建在歸併操作上的一種有效的排序算法,其時間複雜度爲O(N*logN)。1945年由約翰·馮·諾伊曼首次提出。該算法是採用分治法(Divide and Conquer)的一個非常典型的應用,且各層分治遞歸可以同時進行。
概念
是利用遞歸與分治的技術將數據序列劃分爲越來越小的半子表,再對半子表排序,最後再用遞歸方法將排好序的半子表合併成越來越大的有序序列。
核心思想
將兩個有序的數列合併成一個大的有序的序列。通過遞歸,層層合併,即爲歸併。
實現代碼
import java.util.Arrays;
/**
* @author god-jiang
* @date 2020/1/13
*/
//歸併排序,時間複雜度爲O(N*logN),空間複雜度爲O(N)
public class MergeSort {
public static void MergeSort(int[] arr, int start, int end) {
//分治的結束條件
if (start >= end) {
return;
}
//保證不溢出取start和end的中位數
int mid = start + ((end - start) >> 1);
//遞歸排序並且合併
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 p1 = start;
int p2 = mid + 1;
int p = 0;
while (p1 <= mid && p2 <= end) {
if (arr[p1] > arr[p2]) {
temp[p++] = arr[p2++];
} else {
temp[p++] = arr[p1++];
}
}
while (p1 <= mid) {
temp[p++] = arr[p1++];
}
while (p2 <= end) {
temp[p++] = arr[p2++];
}
for (int i = 0; i < temp.length; i++) {
arr[i + start] = temp[i];
}
}
public static void main(String[] args) {
int[] a = {2, 4, 6, 1, 3, 7, 9, 8, 5};
MergeSort(a, 0, a.length - 1);
System.out.println(Arrays.toString(a));
}
}
運行截圖
1、以上就是今天分享的歸併排序,時間複雜度爲O(N*logN),空間複雜度爲O(N)
2、歸併排序的額外空間複雜度可以做到O(1),但是非常難,不需要掌握,有一篇論文”歸併排序內部緩存法”可以做到