归并排序(Merge sort)是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。
作为一种典型的分而治之思想的算法应用,归并排序的实现由两种方法:

  • 自上而下的递归(所有递归的方法都可以用迭代重写,所以就有了第 2 种方法);
  • 自下而上的迭代;

算法步骤

  1. 申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列;
  2. 设定两个指针,最初位置分别为两个已经排序序列的起始位置;
  3. 比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置;
  4. 重复步骤 3 直到某一指针达到序列尾;
  5. 将另一序列剩下的所有元素直接复制到合并序列尾。

动图演示

mergeSort.gif

代码

  1. public class MergeSort implements IArraySort {
  2. @Override
  3. public int[] sort(int[] sourceArray) throws Exception {
  4. // 对 arr 进行拷贝,不改变参数内容
  5. int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);
  6. if (arr.length < 2) {
  7. return arr;
  8. }
  9. int middle = (int) Math.floor(arr.length / 2);
  10. int[] left = Arrays.copyOfRange(arr, 0, middle);
  11. int[] right = Arrays.copyOfRange(arr, middle, arr.length);
  12. return merge(sort(left), sort(right));
  13. }
  14. protected int[] merge(int[] left, int[] right) {
  15. int[] result = new int[left.length + right.length];
  16. int i = 0, j = 0;
  17. int t = 0;
  18. while (i < left.length && j < right.length) {
  19. if (left[i] <= right[j]) {
  20. result[t++] = left[i++];
  21. } else {
  22. result[t++] = right[j++];
  23. }
  24. }
  25. while (i < left.length) {
  26. result[t++] = left[i++];
  27. }
  28. while (j < right.length) {
  29. result[t++] = right[j++];
  30. }
  31. return result;
  32. }
  33. }