Java版歸併排序 演示代碼(帶註釋)

Code:

import java.util.Arrays;

/**
 * 歸併排序
 */
public class MergeSort {
    /**
     * 私有化
     */
    private MergeSort() {}

    /**
     * 歸併排序的sort方法
     * @param arr 待排序數組
     * @param <E> 可比較的元素
     */
    public static <E extends Comparable<E>> void sort(E[] arr) {
        sort(arr, 0, arr.length - 1);
    }

    /**
     * 內部sort方法
     * @param arr 待排序數組
     * @param l 左邊界索引
     * @param r 右邊界索引
     * @param <E> 元素類型(必須可比較)
     */
    private static <E extends Comparable<E>> void sort(E[] arr, int l, int r) {
        // 遞歸終止條件
        if (l >= r) {
            return;
        }
        // 分爲兩部分,取其中間索引(分治)
        int mid = (l + r) / 2;
        sort(arr, l, mid);
        sort(arr, mid + 1, r);
        // 將排好序的兩部分合二爲一(合併)
        merge(arr, l, mid, r);
    }

    /**
     * 合併兩個有序的區間 arr[l, mid] 和 arr[mid+1, r]
     * @param arr 待排序數組(整個數組或部分)
     * @param l 數組索引的左邊界
     * @param mid 數組的中間索引
     * @param r 數組索引的右邊界
     * @param <E> 元素類型
     */
    private static <E extends Comparable<E>> void merge(E[] arr, int l, int mid, int r) {
        // 備份數組的[l, r]區間
        E[] tmp = Arrays.copyOfRange(arr, l, r + 1);

        // 指針i,指向左半部的開頭
        int i = l;
        // 指針j,指向右半部的開頭
        int j = mid + 1;

        // 爲[l, r]區間的arr排序
        for (int k = l; k <= r; k++) {
            // 如果i指針移動到了mid之外(右)
            // 則說明數組左側部分已經全部遍歷過了
            if (i > mid) {
                arr[k] = tmp[j - l];
                j++;
            }
            // 如果j指針也移動出了r邊界
            // 則數組左側部分已經完成遍歷,這時處理左數組即可
            else if (j > r) {
                arr[k] = tmp[i - l];
                i++;
            }
            // 如果i指針在左半邊數組的索引範圍內
            // 且j指針也在右半邊數組的索引範圍之內
            // 則比較i,j兩索引上的元素大小
            else if (tmp[i - l].compareTo(tmp[j - l]) <= 0) {
                // tmp[i] <= tmp[j]
                arr[k] = tmp[i - l];
                i++;
            }
            // 剩下的一種情況,i,j均未越界,且tmp[i] > tmp[j]
            else {
                arr[k] = tmp[j - l];
                j++;
            }
        }
    }

    public static void main(String[] args) {
        Integer[] arr = {9, -1, 5, 8, 2, 17, 7, 0, 6};
        MergeSort.sort(arr);
        for (int item : arr) {
            System.out.println(item);
        }
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章