Search code examples
javaarraysstack-overflow

Why "int mid = (left - right)/2 + right" will cause stack overflow?


I wrote the code of merge sort today, and I meet a StackOverFlow error when I run int mid = (left - right)/2 + right;. But when I use int mid = left + (right - left) / 2; everything is fine. I'm very confused because the mathematical meaning of the two of them is the same(if it's not, why?).

I have seen this question but I'm not sure it answers this problem. why left+(right-left)/2 will not overflow?

Here's my code,I am sorry that I did not upload the code before.

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++;
        }
    }
}

Solution

  • As you run this, sooner or later, it's likely that left will be one less than right - for example, maybe left = 3 and right = 4.

    In that case, (left - right) / 2 and (right - left) / 2 both evaluate to 0, since integer division rounds towards zero. So, if you have

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

    within your call to sort(array, helper, left, right), then you're repeating a call with the exact same values. This causes infinite recursion - a StackOverflowError.

    But when you have

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

    then you're repeating a call with different values, so the recursion has a chance to end.