歸併排序(merge sort)

歸併排序java

    這是一種分治法的應用,就是對於一個待排序的序列,將它一分爲二,二分爲四……,分到最後,每個序列中只會包含一個元素,這時,每個小序列就已經有序了(由於只有一個元素,因此確定是有序的)。而後將其兩兩歸併排序,……四合爲二,二合爲一。這樣就能完排序功能。算法

該排序算法有兩個方法:數組

1.合併方法merge(),合併一個在某一位置分開,兩邊子序列分別有序的序列。code

2.歸併排序方法mergeSort(),這個方法遞歸調用,完成序列的拆分排序。
排序

/**
     * @Description 合併排序一個在startIndex到minIndex位置有序,且在midIndex到endIndex上有序的序列
     * @param srcArray
     *            源數組,且該數組在startIndex到midIndex位置上有序,在midIndex到endIndex上有序
     * @param targetArray
     *            目標數組,排序完成以後的數組,起始位置爲srcArray的起始位置
     * @param startIndex
     *            排序開始位置 (不必定在srcArray的開始位置)
     * @param midIndex
     *            排序中間位置
     * @param endIndex
     *            排序結束位置
     * @return
     */
    public static void merge(int[] srcArray, int[] targetArray, int startIndex,
            int midIndex, int endIndex) {
        // 注意目標數組的起始位置k是startIndex,而非0,由於srcArray的起始位置要和targetArray中的起始位置相同
        int i = startIndex, j = midIndex + 1, k = startIndex;

        // 這裏i,j用來指示由srcArray拆分出的兩個有序子序列的起始位置
        // 當某一個數組中的數字已經用完,那麼就不用再循環比較了,直接將另外一個數組中剩下的數字拼接到新數組中便可
        while (i < midIndex + 1 && j < endIndex + 1) {
            if (srcArray[i] < srcArray[j]) {
                targetArray[k++] = srcArray[i++];
            } else {
                targetArray[k++] = srcArray[j++];
            }
        }

        // 若是startIndex到midIndex數組中還剩下有數,那麼將其拼接到目標數組targetArray中
        while (i < midIndex + 1) {
            targetArray[k++] = srcArray[i++];
        }

        // 若是midIndex到endIndex數組中還剩下有數,那麼將其拼接到目標數組targetArray中
        while (j < endIndex + 1) {
            targetArray[k++] = srcArray[j++];
        }
    }

    /**
     * @Description 歸併排序(遞歸),這個方法爲何須要一個開始位置和結束位置?由於這個數組在遞歸排序過程當中邏輯上會拆分紅不少小序列,
     *              (一分爲二,二分爲四……) 直到一個序列只包含一個數爲止,
     *              而這個startIndex和endIndex則是指示這些邏輯上的小數組在源數組中的正確位置。
     * @param srcArray
     *            待排序數組
     * @param targetArray
     *            目標數組
     * @param startIndex
     *            開始位置
     * @param endIndex
     *            結束位置
     * @return
     */
    public static void mergeSort(int[] srcArray, int[] targetArray,
            int startIndex, int endIndex) {
        int midIndex;
        int[] tempArray = new int[1024]; // 該數組爲臨時數組,大小須要按照須要進行更改,必須>=源數組

        // 特別注意:這是遞歸的出口,也就是指當序列一分爲二,二分爲四……,當序列被折分到子序列中只剩下一個元素的時候,
        // 那麼這個子序列就算是有序序列了(由於有一個元素,因此確定算是有序列的)。
        // 將其直接存放於target目標數組中便可
        if (startIndex == endIndex) {
            targetArray[startIndex] = srcArray[startIndex];
        } else {
            midIndex = (startIndex + endIndex) / 2;
            mergeSort(srcArray, tempArray, startIndex, midIndex); // 遞歸排序左邊的序列
            mergeSort(srcArray, tempArray, midIndex + 1, endIndex); // 遞歸排序右邊的序列

            merge(tempArray, targetArray, startIndex, midIndex, endIndex); // 遞歸將排序好的序列(存放於temp中)進行2路歸併
        }
    }
相關文章
相關標籤/搜索