合并排序
合并排序(Merge Sort)算法就是将多个有序数据表合并成一个有序数据表。如果参与合并的只有两个有序表,则称为二路合并。对于一个原始的待排序序列,往往可以通过分割的方法来归结为多路合并排序。
基本思路
一个待排序的原始数据序列进行合并排序的基本思路是,首先将含有n个结点的待排序数据序列看作由n个长度为1的有序子表组成,将其依次两两合并,得到长度为2的若干有序子表;然后,再对这些子表进行两两合并,得到长度为4的若干有序子表……,重复上述过程,一直到最后的子表长度为n,从而完成排序过程。
算法步骤
- 申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列;
- 设定两个指针,最初位置分别为两个已经排序序列的起始位置;
- 比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置;
- 重复步骤 3 直到某一指针达到序列尾;
- 将另一序列剩下的所有元素直接复制到合并序列尾。
动图演示
代码实现:java
public class ClassP4_7 { public static void main(String[] args) { int[] arr = sort(new int[]{5, 4, 3, 2, 1}); System.out.println(ArrayUtils.toString(arr));//{1,2,3,4,5} } public static int[] sort(int[] sourceArray) { // 对 arr 进行拷贝,不改变参数内容 int[] arr = Arrays.copyOf(sourceArray, sourceArray.length); if (arr.length < 2) { return arr; } int middle = (int) Math.floor(arr.length / 2); int[] left = Arrays.copyOfRange(arr, 0, middle); int[] right = Arrays.copyOfRange(arr, middle, arr.length); return merge(sort(left), sort(right)); } protected static int[] merge(int[] left, int[] right) { int[] result = new int[left.length + right.length]; int i = 0; while (left.length > 0 && right.length > 0) { if (left[0] <= right[0]) { result[i++] = left[0]; left = Arrays.copyOfRange(left, 1, left.length); } else { result[i++] = right[0]; right = Arrays.copyOfRange(right, 1, right.length); } } while (left.length > 0) { result[i++] = left[0]; left = Arrays.copyOfRange(left, 1, left.length); } while (right.length > 0) { result[i++] = right[0]; right = Arrays.copyOfRange(right, 1, right.length); } return result; } }
参考:
1.Java常用算法手册4.8
2.1.5 归并排序(https://www.runoob.com/w3cnote/merge-sort.html)