目录

归并排序

基本介绍

归并排序(MERGE-SORT)是利用归并的思想实现的排序方法,该算法采用经典的分治(divide-and-conquer) 策略(分治法将问题分(divide)成一些小的问题然后递归求解,而治(conquer)的阶段则将分的阶段得到的各答案"修补"在一起,即分而治之)。

排序流程

https://gitee.com/lienhui68/picStore/raw/master/null/20200624155846.png

代码实现

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
    /**
     * 归并排序
     *
     * @param arr
     */
    public static void mergeSort(int[] arr) {
        sort(arr, 0, arr.length - 1);
    }

    /**
     * 归并排序-分解(分解到只剩下一个元素再合并)
     *
     * @param arr
     * @param L
     * @param R
     */
    public static void sort(int[] arr, int L, int R) {
        // 只有一个元素表示分阶段结束,开始治阶段
        if (L == R) {
            return;
        }
        int mid = (L + R) >> 1;
        // 分
        sort(arr, L, mid);
        sort(arr, mid + 1, R);
        // 治
        merge(arr, L, R, mid);
    }

    /**
     * 归并排序-合并(对两个有序有组合并)
     *
     * @param arr
     * @param L
     * @param R
     * @param mid
     */
    public static void merge(int[] arr, int L, int R, int mid) {
        // 定义一个临时数组用来存放(R-L+1)个元素
        int[] temp = new int[R - L + 1];
        // 临时数组指针
        int i = 0;
        // 遍历左边有序数组指针p1
        int p1 = L;
        // 遍历右边有序数组指针p2
        int p2 = mid + 1;
        // 合并两个有序数组
        while (p1 <= mid && p2 <= R) {
            temp[i++] = arr[p1] < arr[p2] ? arr[p1++] : arr[p2++];
        }
        // 遍历完之后会有一个有序数组还剩余一些元素直接赋值即可
        while (p1 <= mid) {
            temp[i++] = arr[p1++];
        }
        while (p2 <= R) {
            temp[i++] = arr[p2++];
        }
        // 将临时数组复制给原始数组
        for (i = 0; i < temp.length; i++) {
            arr[L + i] = temp[i];
        }
    }