排序算法之歸併排序

算法思想

  • 如果要排序一個數組,我們先把數組從中間分成前後兩部分,然後對前後兩部分分別排序,再將排好序的兩部分合併在一起,這樣整個數組就都有序了。

代碼實現

/**
     * 將數組按中間位置分割成2個數組,直到分出來的數組中只有2個或者1個元素
     * @param startIdx
     * @param endIdx
     */
    public void demerge(int[] list, int startIdx, int endIdx) {
        // 2個idx相差1或者0,相差1是2個元素,相差0是1個元素
        if(endIdx - startIdx <= 1) {
            if(endIdx - startIdx == 1) {
                if (sortType == SortType.Positive.type() ? list[startIdx] > list[endIdx] : list[startIdx] < list[endIdx]) {
                    // 排序(其實就是交換)
                    int tmp = list[startIdx];
                    list[startIdx] = list[endIdx];
                    list[endIdx] = tmp;
                }
            }
            return;
        }
        else {
            // 取中間點進行分組
            int n = (startIdx + endIdx) / 2;
            int leftStartIdx = startIdx;
            int leftEndIdx = n;
            int rightStartIdx = n + 1;
            int rightEndIdx = endIdx;

            demerge(list, leftStartIdx, leftEndIdx);
            demerge(list, rightStartIdx, rightEndIdx);
            merge(list, leftStartIdx, leftEndIdx, rightEndIdx);
        }
    }

    public void merge(int[] list, int startIdxA, int seperatorIdx, int endIdxB) {
        // 左邊區間是從startIdxA到seperatorIdx - 1,右邊區間是從seperatorIdx到endIdxB
        int[] tmp = new int[endIdxB - startIdxA + 1];
        int i = startIdxA;
        int j = seperatorIdx + 1;
        for(int n = 0 ; n < tmp.length ; n++) {
            // 如果左邊區間遍歷完了,直接把右邊區間全部寫入到數組的後面
            if(i > seperatorIdx) {
                tmp[n] = list[j];
                j++;
            }
            // 如果右邊區間全部遍歷完了,把左邊區間寫到數組的尾部
            else if(j > endIdxB)
            {
                tmp[n] = list[i];
                i++;
            }
            else {
                if(sortType == SortType.Positive.type() ? list[i] <= list[j] : list[i] >= list[j]) {
                    tmp[n] = list[i];
                    i++;
                }
                else {
                    tmp[n] = list[j];
                    j++;
                }
            }
        }

        // 寫回到原數組
        for(int n = 0 ; n < tmp.length ; n++) {
            list[startIdxA] = tmp[n];
            startIdxA++;
        }
    }

完整代碼歸併排序

發佈了36 篇原創文章 · 獲贊 3 · 訪問量 6473
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章