1. package sort;
    2. /**
    3. * 归并排序相比较之前的排序算法而言加入了分治法的思想,其算法思路如下:
    4. *
    5. * 1.如果给的数组只有一个元素的话,直接返回(也就是递归到最底层的一个情况)
    6. *
    7. * 2.把整个数组分为尽可能相等的两个部分(分)
    8. *
    9. * 3.对于两个被分开的两个部分进行整个归并排序(治)
    10. *
    11. * 4.把两个被分开且排好序的数组拼接在一起
    12. */
    13. public class Merge<T extends Comparable<T>> {
    14. public void mergeArr(T[] arr, int l, int mid, int r){
    15. T[] aux = (T[])(new Object[r - l + 1]);
    16. for(int i = l; i <= r; i++)
    17. aux[i - l] = arr[i];
    18. //双指针操作
    19. int i = l, j = mid + 1;
    20. for(int k = l; k <= r; k++){
    21. if(i > mid){
    22. arr[k] = aux[j - l];
    23. j++;
    24. }else if(j > r){
    25. arr[k] = aux[i - l];
    26. i++;
    27. }else if(aux[i-l].compareTo(aux[j - l]) < 0){
    28. arr[k] = aux[i - l];
    29. i ++;
    30. }else{
    31. arr[k] = aux[j - l];
    32. j ++;
    33. }
    34. }
    35. }
    36. //递归使用递归排序, 对arr[l...r]的范围进行排序
    37. public void merge(T[] arr, int l, int r){
    38. // if( l >= r)
    39. // return;
    40. if(r - l <= 15){
    41. insertionSort(arr, l, r);
    42. return;
    43. }
    44. int mid = (l + r) / 2;
    45. merge(arr, l, mid);
    46. merge(arr, mid + 1, r);
    47. if(arr[mid].compareTo(arr[mid + 1]) > 0)
    48. mergeArr(arr, l, mid, r);
    49. }
    50. private void insertionSort(T[] arr, int l, int r) {
    51. for(int i = l + 1; i <= r; i++){
    52. T t = arr[i];
    53. int j;
    54. //依次循环将数据后移一个位置, 最后在插入
    55. for(j = i; j > l && arr[j - 1].compareTo(t) > 0; j--)
    56. arr[j] = arr[j - 1];
    57. arr[j - 1] = t;
    58. }
    59. return;
    60. }
    61. public void mergeSort(T[] arr, int n){
    62. merge(arr, 0, n - 1);
    63. }
    64. /**
    65. * 以下是经典的归并排序算法
    66. * @param arr 数组
    67. * @param l 左边界
    68. * @param r 右边界
    69. */
    70. void mergeSort(int[] arr, int l, int r) {
    71. if (l < r) {
    72. int m = l+(r-l)/2;
    73. mergeSort(arr, l, m);
    74. mergeSort(arr, m+1, r);
    75. merge(arr, l, m, r);
    76. }
    77. }
    78. private void merge(int[] arr, int l, int m, int r) {
    79. int i, j, k;
    80. int n1 = m - l + 1;
    81. int n2 = r - m;
    82. int[] L = new int[n1];
    83. int[] R = new int[n2];
    84. /*
    85. 拷贝新数组
    86. */
    87. for (i = 0; i < n1; i++)
    88. L[i] = arr[l + i];
    89. for (j = 0; j < n2; j++)
    90. R[j] = arr[m + 1+ j];
    91. i = 0;
    92. j = 0;
    93. k = l;
    94. /*
    95. * 对两个数组在不越界的情况下,分别拷贝数组直到一个数组越界
    96. */
    97. while (i < n1 && j < n2) {
    98. if (L[i] <= R[j]) {
    99. arr[k] = L[i];
    100. i++;
    101. }else {
    102. arr[k] = R[j];
    103. j++;
    104. }
    105. k++;
    106. }
    107. /*
    108. 将不越界的数组拷贝到新数组中
    109. */
    110. while (i < n1) {
    111. arr[k] = L[i];
    112. i++;
    113. k++;
    114. }
    115. while (j < n2) {
    116. arr[k] = R[j];
    117. j++;
    118. k++;
    119. }
    120. }
    121. }