归并排序学习

130 阅读2分钟

归并排序(Merge Sort)

​ 归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为2-路归并。

算法描述
  1. 把长度为n的输入序列分成两个长度为n/2的子序列;
  2. 对这两个子序列分别采用归并排序;
  3. 将两个排序好的子序列合并成一个最终的排序序列。
例子
数组: 3  17  12  11  2  20  27  23
先分两组:3  17  12  11  | 2  20  27  23
每组再分:3  17 ; 12  11 | 2  20 ; 27  23
第一次: 3  17  12  11  2  20  27  23
第二次: 3  17  11  12  2  20  27  23
第三次: 3  11  12  17  2  20  27  23
第四次: 3  11  12  17  2  20  27  23
第五次: 3  11  12  17  2  20  23  27
第六次: 3  11  12  17  2  20  23  27
第七次: 2  3  11  12  17  20  23  27
结束
算法复杂度

空间复杂度: O(n)

时间复杂度:

O(nlog2n)最坏结果O(nlog_2n) 最坏结果
O(nlog2n)平均结果O(nlog_2n) 平均结果
O(nlog2n)最好结果O(nlog_2n) 最好结果

排序稳定,原来相等的两个参数排在前面的依旧是排在前面。

代码实现
 public static int[] sort(int[] sourceArray) throws Exception {
     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));
 }

private 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);
    }
    System.out.println(Arrays.toString(result));
    return result;
}

运行结果

输入数组:int[] arr = {3,17,12,11,2,20,27,23};
[3, 17]
[11, 12]
[3, 11, 12, 17]
[2, 20]
[23, 27]
[2, 20, 23, 27]
[2, 3, 11, 12, 17, 20, 23, 27]

但是按照上面的步骤,这时候我们可以看到和演算结果一致。