递归函数可以单独工作,但是一起导致堆栈溢出错误

时间:2018-04-25 19:46:40

标签: java recursion stack-overflow quicksort

在处理Dutch National Flag Problem时,我想出了以下代码,希望实现我自己的quicksort变体:

static void sort(int[] nums) {
    dutchSort(nums,0,nums.length);
}

// sorts nums[left..right)
static void dutchSort(int[] nums, int left, int right) {
    // recursion base case
    if (left >= right) return;

    int pivot = nums[left];

    // smaller - index of the last element smaller than pivot value
    // equal - index of the last element equal to pivot value
    // larger - index of the first element larger than pivot value
    int smaller = left-1, equal = left, larger = right, temp;

    // before sorting is completed, 'equal' is the current index,
    // much like 'i' in a for-loop
    while (equal < larger) {
        if (nums[equal] < pivot) {
            temp = nums[equal];
            nums[equal] = nums[++smaller];
            nums[smaller] = temp;
        } else if (nums[equal] == pivot) {
            equal++;
        } else {
            temp = nums[equal];
            nums[equal] = nums[--larger];
            nums[larger] = temp;
        }
    }

    // recursively sort smaller subarray
    dutchSort(nums, 0, smaller+1);

    // recursively sort larger subarray
    dutchSort(nums, equal, nums.length);
}

结果排序数组理想情况下应包含3个子数组:(i)所有小于pivot的值,(ii)所有值等于pivot,(iii)所有大于pivot的值。然后递归地对子阵列(i)和(iii)进行排序,直到对大小为1的子阵列的基本情况进行排序。我认为我的代码正确地做到了这一点,但我并不是100%肯定。 while循环中的逻辑以及递归调用中leftright使用的值也是正确的。

但是,dutchSort函数dutchSort(nums, 0, smaller+1);dutchSort(nums, equal, nums.length);末尾的两次递归调用会导致堆栈溢出错误。

当我注释掉两个或一个递归函数时,程序终止并生成一个正确排序(或部分排序)的数组。

示例输入(两个递归函数已注释掉),并包含print的{​​{1}}语句:

smaller

输出:

[2,0,1,0,0,2]

虽然没有实际排序,但这仍然是正确的输出,因为枢轴左边的所有值都是较小的值。理想情况下,两个递归函数将处理适当的子数组。在这种情况下,只需要对较小的子阵列smaller = 3 [0, 1, 0, 0, 2, 2] 进行排序。请注意[0,1,0,0]正确显示索引[0..3]中的子数组需要进行排序。

使用输入smaller = 3重新启动程序,再次使用递归函数注释掉,我正确地得到:

[0,1,0,0]

所以看起来排序逻辑是正确的;原始数组已正确排序,并且手动排序相应的子数组也可以正常工作。但是当所有内容都未被注释和组合时,就会出现一个导致堆栈溢出的循环。

请帮我弄清楚这种行为的原因。

谢谢:)

1 个答案:

答案 0 :(得分:3)

我认为您的第一次递归调用应使用left作为第二个参数:

dutchSort(nums, left, smaller+1)

而不是

dutchSort(nums, 0, smaller+1)