歸併排序

歸併排序的JAVA實現

import java.util.Arrays;

//歸併排序之JAVA實現(迭代法)
public class MergeSort {

    public void Merge(int[] array, int low, int mid, int high) {

        int i = low; // i是第一段序列的下標
        int j = mid + 1; // j是第二段序列的下標
        int k = 0; // k是臨時存放合併序列的下標
        int[] arrayTemp = new int[high - low + 1]; // arrayTemp是臨時合併序列
        // 掃描第一段和第二段序列,直到有一個掃描結束
        while (i <= mid && j <= high) {
            // 判斷第一段和第二段取出的數哪個更小,將其存入合併序列,並繼續向下掃描
            if (array[i] <= array[j]) {
                arrayTemp[k] = array[i];
                i++;// 小的往前走
                k++;
            } else {
                arrayTemp[k] = array[j];
                j++;// 小的往前走
                k++;
            }
        }

        // 若第一段序列還沒掃描完,將其全部複製到合併序列
        while (i <= mid) {
            arrayTemp[k] = array[i];
            i++;
            k++;
        }
        // 若第二段序列還沒掃描完,將其全部複製到合併序列
        while (j <= high) {
            arrayTemp[k] = array[j];
            j++;
            k++;
        }

        // 將合併序列複製到原始序列中
        for (k = 0, i = low; i <= high; i++, k++) {
            array[i] = arrayTemp[k];
        }

    }

    /** * * @param array * 待排序數組 * @param gap * 歸併子數組長度 * @param length * 待排序數組的長度 */
    public void MergePass(int[] array, int gap, int length) {

        int i = 0; // 每趟合併的起始位置索引(都是從第一個開始)
        // 歸併gap長度的兩個相鄰子表
        // (i + 2 * gap - 1) 本次合併的兩組序列中右邊序列的最後索引位置
        // (i = i + 2 * gap) 下組合並的起始索引位置
        // 通過(i + 2 * gap - 1 <length)的比較可
        // 以判斷出是否剩餘兩組可以進行合併,如果小於,說明至少還有兩組可以進行合併,
        // 如果不小於,說明只剩一組,對於剩下的一組,則不用關心
        // 1、剩餘一組,可能小於也可能等於一個gap長度
        // 2、剩餘兩組,最後一組小於一個gap長度
        for (i = 0; i + 2 * gap - 1 < length; i = i + 2 * gap) {
            Merge(array, i, i + gap - 1, i + 2 * gap - 1);// 此方法實現具體的比較過程
            // 每一次排序往兩個子數組之後,通過(i = i + 2 * gap)來索引到下一組待排序的子數組
        }

        // 當存在這樣餘下的兩個子表,前者子數組的長度爲當前gap,後者長度小於本次合併子序列的gap
        // 通過(i + gap - 1 < length)的比較可以讓最後一組合併到前面的大組中去。
        System.out.println("(" + i + "+" + gap + "-1)=" + (i + gap - 1) + "==" + length);
        if (i + gap - 1 < length) {
            Merge(array, i, i + gap - 1, length - 1);// 如果配對完剩餘一個子數組,則(i + gap -
                                                        // 1)==(length - 1)
        }
    }

    public int[] Sort(int[] list) {
        int cishu = 0;
        for (int gap = 1; gap < list.length; gap = 2 * gap) {
            MergePass(list, gap, list.length);// 此方法實現具體的比較過程
            System.out.println("歸併排序第[" + (++cishu) + "]次:" + Arrays.toString(list));
        }
        return list;
    }

}
点赞