image.png
image.png

归并过程

归并排序无法原地完成!
image.png
每次只比较a中最小的元素和b中最小的元素,谁更小就把谁拿出来。
image.png
image.png
复制一份原数组出来,比较i与j
image.png

Merge过程

我们申请一个临时数组 tmp,大小与 A[p…r]相同。我们用两个游标 i 和 j,分别指向 A[p…q]和 A[q+1…r]的第一个元素。比较这两个元素 A[i]和 A[j],如果 A[i]<=A[j],我们就把 A[i]放入到临时数组 tmp,并且 i 后移一位,否则将 A[j]放入到数组 tmp,j 后移一位。

5.归并排序法(自顶向下) - 图7
image.png

  1. package com.hoho.algorithms.sort.mergesort;
  2. import com.hoho.algorithms.api.ArrayGenerator;
  3. import com.hoho.algorithms.api.SortingHelper;
  4. import com.hoho.algorithms.basesort.InsertSort;
  5. import java.util.Arrays;
  6. import java.util.SortedMap;
  7. public class MergeSort {
  8. private MergeSort() {
  9. }
  10. public static <E extends Comparable<E>> void sort(E[] arr) {
  11. sort(arr, 0, arr.length - 1);
  12. }
  13. private static <E extends Comparable<E>> void sort(E[] arr, int l, int r) {
  14. if (l >= r) {
  15. return;
  16. }
  17. int mid = l + (r - l) / 2;
  18. sort(arr, l, mid);
  19. sort(arr, mid + 1, r);
  20. merge(arr, l, mid, r);
  21. }
  22. /**
  23. * 合并两个有序的数组 arr[l,mid] 与 arr[mid+1,r]
  24. */
  25. private static <E extends Comparable<E>> void merge(E[] arr, int l, int mid, int r) {
  26. //Arrays.copyOfRange(T[ ] original,int from,int to),包括from,不包括to
  27. E[] temp = Arrays.copyOfRange(arr, l, r + 1);
  28. int i = l;
  29. int j = mid + 1;
  30. //每轮循环为arr[k]赋值
  31. for (int k = l; k <= r; k++) {
  32. //判断i与j是否越界
  33. if (i > mid) {
  34. //i越界
  35. //j-l: arr数组是从l开始的,temp数组是从0开始的,所以要用j-l表示j在temp中的位置
  36. arr[k] = temp[j - l];
  37. j++;
  38. } else if (j > r) {
  39. //j越界
  40. arr[k] = temp[i - l];
  41. i++;
  42. } else {
  43. //都没有越界
  44. if (temp[i - l].compareTo(temp[j - l]) <= 0) {
  45. arr[k] = temp[i - l];
  46. i++;
  47. } else {
  48. arr[k] = temp[j - l];
  49. j++;
  50. }
  51. }
  52. }
  53. }
  54. }