【问题标题】:Getting StackOverFlow error while trying to code Merge Sort in Java尝试在 Java 中编写合并排序时出现 StackOverFlow 错误
【发布时间】:2021-04-12 13:03:03
【问题描述】:

我是编码新手,我试图在 java 中创建归并排序算法。我收到太多错误,我无法找出确切的错误 在代码中。 我觉得我的逻辑是正确的,但不知道是哪个步骤导致了错误。有人可以帮我纠正以下代码中的错误。 谢谢

package com.company;
public class MergeSort_Array {
    //Method created to print Input Array
    public static void printInputArray(int inputArray[]) {
        for (int i:inputArray) { //for-each loop
            System.out.print(i + " ");
        }
        System.out.println();
    }

    //Function created to sort and merge Input Array:
    public static void SortArray(int[] A) {
        int midpoint = A.length / 2;
        int[] left = new int[midpoint];
        int[] right;
        if (A.length % 2 == 0) {
            right = new int[midpoint];
        } else {
            right = new int[midpoint + 1];
        }
        //Copying values from super Array to left Array:
        for (int i = 0; i < midpoint; i++) {
            left[i] = A[i];
        }
        //Copying elements from super Array to right Array:
        for (int j = 0; j < right.length; j++) {
            right[j] = A[midpoint + j];
        }
        //using Recursion
        SortArray(left);
        SortArray(right);
        MergeArray(A, left, right);
    }

    // Creating a Function to merge left and right arrays.
    public static void MergeArray(int[] result, int[] L, int[] R) {
        //result array length = length of left array+ right array length
        result = new int[L.length + R.length];
        int i = 0, j = 0, k = 0;
        while (k < result.length) {
            if (L[i] < R[j]) {
                result[k] = L[i];
                i++;
            } else
            if (R[j] < L[i]) {
                result[k] = R[j];
                j++;
            } else
            if (i > L.length) {
                while (j <= R.length) {
                    result[k] = R[j];
                    j++;
                }
            } else
            if (j > R.length && i <= L.length) {
                while (i <= L.length) {
                    result[k] = L[i];
                    i++;
                }
            }
            k++;
        }
    }

    public static void main(String[] args) {
        int[] inputArray = { 2, 5, 4, 1, 7, 9, 6 };
        MergeSort_Array ms = new MergeSort_Array();
        ms.printInputArray(inputArray);
        SortArray(inputArray);

        for (int i: inputArray) {
            System.out.println(i + " ");
        }
    }
}

【问题讨论】:

  • 除了你的主要问题(我已经在答案中解释过)之外,当你真的应该将结果写入传入的数组时(即摆脱result = new int[L.length + R.length];这一行。
  • @ShantanuStudyCircle:您可以通过单击分数下方的灰色复选标记来接受其中一个答案。

标签: java arrays sorting recursion mergesort


【解决方案1】:

您的代码存在多个问题:

  • [Major] SortArray() 总是尝试拆分数组并对两半进行排序。如果数组长度小于 2,则不应这样做,否则会导致无限递归导致 堆栈溢出 异常。

  • [提示] right可以无条件初始化为int[] right = new int[A.length - midpoint];

  • [Major] MergeArray 不应重新分配目标数组。必须在result 中执行合并,以便更新调用者的对象。

  • [Major] 在合并循环中,您必须在尝试读取 L[i]R[j] 之前测试索引值,否则您可能会退出边界异常。

这是修改后的版本:

package com.company;
public class MergeSort_Array {
    // Method created to print Input Array
    public static void printInputArray(int inputArray[]) {
        for (int i : inputArray) { //for-each loop
            System.out.print(i + " ");
        }
        System.out.println();
    }

    //Function created to sort and merge Input Array:
    public static void SortArray(int[] A) {
        if (A.length >= 2) {
            int midpoint = A.length / 2;
            int[] left = new int[midpoint];
            int[] right = new int[A.length - midpoint];

            //Copying values from super Array to left Array:
            for (int i = 0; i < midpoint; i++) {
                left[i] = A[i];
            }
            //Copying elements from super Array to right Array:
            for (int j = 0; j < right.length; j++) {
                right[j] = A[midpoint + j];
            }
            //using Recursion
            SortArray(left);
            SortArray(right);
            MergeArray(A, left, right);
        }
    }

    // Creating a Function to merge left and right arrays.
    public static void MergeArray(int[] result, int[] L, int[] R) {
        for (int i = 0, j = 0, k = 0; k < result.length; k++) {
            if (j >= R.length || (i < L.length && L[i] < R[j])) {
                result[k] = L[i++];
            } else {
                result[k] = R[j++];
            }
        }
    }

    public static void main(String[] args) {
        int[] inputArray = { 2, 5, 4, 1, 7, 9, 6 };
        printInputArray(inputArray);
        SortArray(inputArray);
        printInputArray(inputArray);
    }
}

【讨论】:

    【解决方案2】:

    每次您调用SortArray 时,它本身都会调用SortArray 两次。没有结束条件:每个调用都会尝试调用SortArray 两次。

    这意味着对SortArray 的调用永远无法完成,因为您在每个调用中都无限递归。

    必须有一些基本情况,它不再调用自己。对于合并排序,一旦数组足够小,通常会切换到其他算法,但为了简单起见,您甚至可以退回到最简单的排序基本情况:任何短于 2 个元素的数组总是被排序并且不需要做任何其他事情来进行排序。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-11-11
      • 1970-01-01
      • 1970-01-01
      • 2015-09-10
      • 2019-02-23
      • 1970-01-01
      • 1970-01-01
      • 2010-11-19
      相关资源
      最近更新 更多