排序算法之归并排序

算法思想

  • 如果要排序一个数组,我们先把数组从中间分成前后两部分,然后对前后两部分分别排序,再将排好序的两部分合并在一起,这样整个数组就都有序了。

代码实现

/**
     * 将数组按中间位置分割成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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章