归并排序

69 阅读1分钟
public class MergeSort {
    public static void sort(int[] nums) {
        if (nums == null || nums.length < 2) {
            return;
        }
        doSort(nums, 0, nums.length - 1);
    }

    /**
     * 左闭右闭区间
     *
     * @param nums
     * @param startIdx
     * @param endIdx
     */
    private static void doSort(int[] nums, int startIdx, int endIdx) {
        // 设置结束条件
        if (endIdx <= startIdx) {
            return;
        }

        // 分割下标
        int midIdx = (startIdx + endIdx) / 2;
        // 递归
        doSort(nums, startIdx, midIdx);
        doSort(nums, midIdx + 1, endIdx);
        // 将大的子数组进行合并
        merge(nums, startIdx, midIdx, endIdx);
    }

    private static void merge(int[] nums, int startIdx, int midIdx, int endIdx) {
        int[] tmp = new int[endIdx - startIdx + 1];
        int idx1 = startIdx;
        int idx2 = midIdx + 1;
        int idx = 0;
        // 归并,小的先放前面
        while (idx1 <= midIdx && idx2 <= endIdx) {
            if (nums[idx1] <= nums[idx2]) {
                tmp[idx++] = nums[idx1++];
            } else {
                tmp[idx++] = nums[idx2++];
            }
        }

        while (idx1 <= midIdx) {
            tmp[idx++] = nums[idx1++];
        }
        while (idx2 <= endIdx) {
            tmp[idx++] = nums[idx2++];
        }
        // 将临时存放的数组复制回去
        for (int i = 0; i < tmp.length; i++) {
            nums[startIdx + i] = tmp[i];
        }
    }
}