1.归并排序的思想
分而治之:将一个大数组均分为两个大小相等的数组(奇数容量下有 1 的差值),然后进行排序的话,时间就从对T = O(n^2)操作变成了2*O((n/2)^2) =2*O((n^2)/4) = O(n^2) / 2 = T / 2,时间缩小了一倍,我们将这个过程循环下去,直到所有数组都被分成一个元素为止,由归纳可得时间为O(n*lgn),之后进行循环有序合并,那么明显时间为O(n),舍去,所以归并排序将基础排序中的O(n^2)改进为了O(n*lgn);有效的改进了时间复杂度。
2.见名之意
归并排序就是将原来的数组分为两个小的数组就行排序之后进行合并,因为常常使用递归实现(由先拆分后合并的性质决定的),所以我们称其为归并排序。
3.抽象过程
- 对于一个大小为n的待排序数组,将其划分为n个小数组,即每个数划分为一个数组,对于只有一个元素的数组,那么该数组有序。
- 有序合并相邻相同大小的数组,即合并两个有序数组为一个有序数组。
- 循环上一步直到所有小数组合并到一个数组中为止。
- 此时排序就已经在不断的有序中完成,数组有序。
4.实例操作
package core_data_structure; import java.util.Arrays; public class MergeSort_01 { public static void main(String[] args) { int[] array = { 3, 9, 9, 2, 3, 8, 8, 4, 1, 0, 5, 7, 6 }; System.out.println("归并排序前" + Arrays.toString(array)); mergeSort(array); System.out.println("归并排序后" + Arrays.toString(array)); } private static void mergeSort(int[] array) { mergeSort(array, 0, array.length - 1); } private static void mergeSort(int[] array, int lo, int hi) { // 归并两个数组需要额外的存储空间 ,我们直接在此new一个,放置递归时循环申请空间 int[] temp = new int[array.length]; mergeSort(array, temp, lo, hi); } private static void mergeSort(int[] array, int[] temp, int lo, int hi) { int mid = (lo + hi) / 2; if (hi - lo > 1) {// 子数组长度大于1时进行拆分 mergeSort(array, temp, lo, mid); mergeSort(array, temp, mid + 1, hi); } // 合并array[lo..mid]和array[mid..hi],此时两个数组都是有序的。 merge(array, temp, lo, mid, hi); } private static void merge(int[] array, int[] temp, int lo, int mid, int hi) { int arr1Begin = lo; int arr1End = mid; int arr2Begin = mid + 1; int arr2End = hi; int k = lo; while (arr1Begin <= arr1End || arr2Begin <= arr2End) { if (arr1Begin > arr1End) {// 说明1号数组中已经无值 temp[k++] = array[arr2Begin++]; } else if (arr2Begin > arr2End) {// 说明2号数组中已经无值 temp[k++] = array[arr1Begin++]; } else {// 两个数组都没有结束,比大小添加 if (array[arr1Begin] < array[arr2Begin]) {// 比大小添加 temp[k++] = array[arr1Begin++]; } else { temp[k++] = array[arr2Begin++]; } } } for (int i = lo; i <= hi; i++) { array[i] = temp[i]; } } }
转自:https://blog.youkuaiyun.com/m0_37961948/article/details/81585489