【问题标题】:Why "int mid = (left - right)/2 + right" will cause stack overflow?为什么“int mid = (left - right)/2 + right”会导致堆栈溢出?
【发布时间】:2019-06-09 23:46:24
【问题描述】:

我今天写了归并排序的代码,运行int mid = (left - right)/2 + right;时遇到了StackOverFlow错误。但是当我使用int mid = left + (right - left) / 2; 时,一切都很好。我很困惑,因为它们两个的数学含义是相同的(如果不是,为什么?)。

我见过这个问题,但我不确定它是否能回答这个问题。 why left+(right-left)/2 will not overflow?

这是我的代码,很抱歉之前没有上传代码。

import java.util.Arrays;

public class Solution {
    public static void main(String[] args) {
        int[] array = {3,5,1,2,4,8};
        int[] result = mergeSort(array);
        System.out.println(Arrays.toString(result));
    }

    public static int[] mergeSort(int[] array) {
        if (array == null || array.length <= 1) {
            return array;
        }
        int[] helper = new int[array.length];
        sort(array, helper, 0, array.length - 1);
        return array;
    }

    public static void sort(int[] array, int[] helper, int left, int right) {
        if (left >= right) {
            return;
        }
        int mid = (left - right)/2 + right;
        //int mid = left + (right - left) / 2;
        sort(array, helper, left, mid);
        sort(array, helper, mid + 1, right);

        combine(array, helper, left, mid, right);
    }

    public static void combine(int[] array, int[] helper, int left, int mid, int right) {
        for (int i = left; i <= right; i++) {
            helper[i] = array[i];
        }

        int leftIndex = left;
        int rightIndex = mid + 1;
        while (leftIndex <= mid && rightIndex <= right) {
            if (helper[leftIndex] <= helper[rightIndex]) {
                array[left] = helper[leftIndex];
                left++;
                leftIndex++;
            } else {
                array[left] = helper[rightIndex];
                left++;
                rightIndex++;
            }
        }

        while (leftIndex <= mid) {
            array[left] = helper[leftIndex];
            left++;
            leftIndex++;
        }
    }
}

【问题讨论】:

  • I'm very confused because the mathematical meaning of the two of them is the same. 不,不是。
  • edit您的问题并向我们展示您的方法的完整代码。不只是一行(edit你的问题,不要在cmets中放代码)
  • 澄清一下,你说的是整数溢出,而不是栈溢出。如果您收到StackOverflowError,那么您的问题出在其他地方。
  • 为什么您对链接到的问题的答案不满意?
  • 不,是StackOverflowError。这是因为负数的整数除法向零舍入。所以当你到达right = 1 + left 时,midright 相同。根据代码的 REST 如何处理这个问题,您可能会无休止地递归。现在 - 如果您显示所有代码(不仅仅是一行),有人可能会提出修复建议。

标签: java arrays stack-overflow


【解决方案1】:

当您运行此程序时,迟早,left 可能会比 right 小一 - 例如,可能是 left = 3right = 4

在这种情况下,(left - right) / 2(right - left) / 2 的计算结果都为 0,因为整数除法向零舍入。所以,如果你有

int mid = (left - right)/2 + right;
sort(array, helper, left, mid);

在您对sort(array, helper, left, right) 的调用中,您将使用完全相同的值重复调用。这会导致无限递归 - StackOverflowError

但是当你有

int mid = left + (right - left)/2;
sort(array, helper, left, mid); 

然后你用不同的值重复一个调用,所以递归有机会结束。

【讨论】:

    【解决方案2】:

    最初,您拥有left &lt; right。当然还有right - left &gt; 0,还有left + (right - left) = right(来自基本代数)。

    因此left + (right - left) / 2 &lt;= right。因此不会发生溢出,因为操作的每一步都以 right 的值为界。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-20
      • 2017-11-24
      • 2018-07-01
      • 2010-09-11
      • 1970-01-01
      • 2011-01-13
      相关资源
      最近更新 更多