1,归并排序介绍
- 归并排序就是利用归并的思想实现的排序方式,采用了经典的分治策略;分治法就是先将问题分成一些小的问题然后递归求解,治阶段就是将分阶段得到的各答案补在一起,即分而治之;归并排序处理次数 = 元素个数 - 1
- 基本思想:
- 归并排序为分和治两个部分,其中分部分是对数组元素完全拆分,拆无可拆时开始治;治就是对已经拆散的数据按顺序依次重组起来;此外,归并排序需要一个额外空间进行有序数据重组
- 首先拆,归并排序拆的目的是将数组中的每一 元素都拆分出来
- 拆完之后治,治是对拆开的每一组数据依次排序,并最终递归到全数据有序
-
-
- 治过程中,需要对数组中的相邻两部分进行排序,在每一次排序过程中,首先对两部分数组中交叉重叠的部分依次有序添加到临时数组中;其次,对两部分数组中存在剩余数据数组的剩余数据依次添加到临时数组中;最后,用临时数组的元素,依次替换到原数组中参与治的两部分数组的元素,即(left - right部分)
2,归并排序示例
- 分-治示意图
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/5423610e7aac8647f93ff1fea7bc6d26.png)
- 合并子序列示意图
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/e9c784b2c524e93effe64d22b7d553b8.png)
3,代码实现
package com.self.datastructure.sort;
import java.util.Arrays;
public class MergeSort {
public static void main(String[] args) {
int[] array = new int[10000000];
int[] tempArray = new int[array.length];
for (int i = 0; i < 10000000; i++) {
array[i] = (int) (Math.random() * 8000000);
}
long startTime = System.currentTimeMillis();
mergeSort(array, 0, array.length - 1, tempArray);
System.out.println("cast time : " + (System.currentTimeMillis() - startTime));
}
private static void mergeSort(int[] array, int left, int right, int[] tempArray) {
int middle = (left + right) / 2;
if (left < right) {
mergeSort(array, left, middle, tempArray);
mergeSort(array, middle + 1, right, tempArray);
merge(array, left, right, middle, tempArray);
}
}
private static void merge(int[] array, int left, int right, int middle, int[] tempArray) {
int tempIndex = 0;
int leftIndex = left;
int rightIndex = middle + 1;
while (leftIndex <= middle && rightIndex <= right) {
if (array[leftIndex] > array[rightIndex]) {
tempArray[tempIndex++] = array[rightIndex++];
} else {
tempArray[tempIndex++] = array[leftIndex++];
}
}
while (leftIndex <= middle) {
tempArray[tempIndex++] = array[leftIndex++];
}
while (rightIndex <= right) {
tempArray[tempIndex++] = array[rightIndex++];
}
tempIndex = 0;
int tempLeft = left;
while (tempLeft <= right) {
array[tempLeft++] = tempArray[tempIndex++];
}
}
}