一、简述
归并排序是建立在归并操作上的一种有效,稳定的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列:即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并(binary merge)。速度仅次于快速排序,内存少的时候使用,可以进行并行计算的时候使用。
- 选择相邻两个数组成一个有序序列。
- 选择相邻的两个有序序列组成一个有序序列。
- 重复第二步,直到全部组成一个有序序列。
二、归并排序算法原理
1️⃣申请大小为两个已经排序序列之和的空间,用来存放合并后的序列。
2️⃣设定两个指针,最初位置分别为两个已经排序序列的起始位置。
3️⃣比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置。
4️⃣重复步骤3️⃣直到某一指针超出序列尾。
5️⃣将另一序列剩下的所有元素直接复制到合并序列尾。
三、示例
1️⃣递归应用
public class MergeSort {
public static int[] mergeSort(int[] source, int start, int h) {
if (start == h)
return new int[]{
source[start]};
int mid = start + (h - start) / 2;
int[] leftArr = mergeSort(source, start, mid); //左有序数组
int[] rightArr = mergeSort(source, mid + 1, h); //右有序数组
int[] target = new int[leftArr.length + rightArr.length]; //新有序数组
int m = 0, n = 0, s = 0;
while (m < leftArr.length && n < rightArr.length) {
target[s++] = leftArr[m] < rightArr[n] ? leftArr[m++] : rightArr[n++];
}
while (m < leftArr.length)
target[s++] = leftArr[m++];
while (n < rightArr.length)
target[s++] = rightArr[n++];
return target;
}
public static void main(String[] args) {
int[] source = new int[]{
1, 3, 6, 7, 5, 9, 4, 2, 8, 10};
int[] target = mergeSort(source, 0, source.length - 1);
for (int tar : target) {
System.out.println(tar);
}
}
}
2️⃣二路归并,首先要使待排序的数组为有序的。数组排序方法举例:
- 排序api:
Arrays.sort(array);
- 部分排序法:
Arrays.sort(arr, 2, 6);
选择想要排序的部分数字,排前不排后[排列部分为 2、3、4、5],其他数字顺序不变。 - 冒泡排序法
- 选择排序法
- 插入排序法
- 快速排序法