【问题标题】:Java - mergeSort using recursionJava - 使用递归的mergeSort
【发布时间】:2020-11-23 18:20:13
【问题描述】:

我正在浏览下面的示例程序并试图理解下面的递归是如何工作的,我无法理解左右数组元素是如何排序的,最后合并两个子数组如下。以下方法的任何图形解释都会有很大帮助,因为我试图理解下面的递归代码。

 public static int[] mergeSort(int[] arrayToSort) {

    // BASE CASE: arrays with fewer than 2 elements are sorted
    if (arrayToSort.length < 2) {
        return arrayToSort;
    }

    // STEP 1: divide the array in half
    // we use integer division, so we'll never get a "half index"
    int midIndex = arrayToSort.length / 2;

    int[] left  = Arrays.copyOfRange(arrayToSort, 0, midIndex);
    int[] right = Arrays.copyOfRange(arrayToSort, midIndex, arrayToSort.length);

    // STEP 2: sort each half
    int[] sortedLeft  = mergeSort(left);
    int[] sortedRight = mergeSort(right);

    // STEP 3: merge the sorted halves
    int[] sortedArray = new int[arrayToSort.length];

    int currentLeftIndex  = 0;
    int currentRightIndex = 0;

    for (int currentSortedIndex = 0; currentSortedIndex < arrayToSort.length;
            currentSortedIndex++) {

        // sortedLeft's first element comes next
        // if it's less than sortedRight's first
        // element or if sortedRight is exhausted
        if (currentLeftIndex < sortedLeft.length
                && (currentRightIndex >= sortedRight.length
                || sortedLeft[currentLeftIndex] < sortedRight[currentRightIndex])) {
            sortedArray[currentSortedIndex] = sortedLeft[currentLeftIndex];
            currentLeftIndex++;
        } else {
            sortedArray[currentSortedIndex] = sortedRight[currentRightIndex];
            currentRightIndex++;
        }
    }

    return sortedArray;
}

【问题讨论】:

    标签: java mergesort


    【解决方案1】:

    在合并循环中进行排序:

    • 如果数组非常小(0 或 1 个元素),mergeSort() 会立即返回它。

    • 否则,它将数组拆分为大小大致相同的 2 个子数组,leftright,通过递归调用相同的方法对它们进行排序:

        // STEP 2: sort each half
        int[] sortedLeft  = mergeSort(left);
        int[] sortedRight = mergeSort(right);
      
    • 最后一步遍历已排序的一半以生成新的排序数组。

    递归调用完成,因为它们只对严格小于参数数组的子数组执行。

    【讨论】:

    • 可能更简单的解释是,在嵌套递归拆分导致两个子数组每个大小为 1 之前,不会发生实际合并,此时这两个子数组被合并以创建一个排序的具有 2 个元素的子数组。然后拆分和合并遵循调用链,深度优先,左优先。
    • @chqrlie:谢谢。我可以理解您所解释的内容,正如查询中的评论所解释的那样。我不明白的是递归调用,2个子数组如何排序以及两个排序后的子数组最终如何使用递归合并。我确实尝试通过一个示例来理解:arrayToSort 有 11 个元素,例如 {4,1,-2, 0, 4, 6, 7, 2, 5, 3, 8}。左边有 5 个,右边有 6 个元素,比如说 - 左边:{4,1,-2, 0, 4} 和右边:{6, 7, 2, 5, 3, 8} .. 这些如何单独排序和合并。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多