繁体   English   中英

我的快速排序算法中的Stackoverflow错误

[英]Stackoverflow error in my quicksort algorithm

由于在递归过程中出现堆栈溢出错误,我一直在研究这段代码几天没有运气。

问题表明我们的pivot始终是第0个元素,通过递归,我们可以通过交换或创建新数组并将它们复制到原始数组中来对数组进行排序。 我选择创建2个数组,因为我更容易理解,但是一旦我到达递归步骤,我就会得到这个错误。

我追踪算法,并意识到枢轴元素总是放在较低的数组中,可能是问题所在。

enter code here
public static void main(String[] args) {
    int[] arr = new int[] { 12, 7, 5, 8, 4, 6, 11, 15 };
    quicksort(arr);
    for (int i = 0; i < arr.length; i++) {
        System.out.print(arr[i] + " ");
    }
    System.out.println();

}



    private static int[] quicksort(int[] arr, int middle) {
    // Base case
    if (arr.length == 1) {
        return arr;
    }
    int[] upper = new int[arr.length];
    int[] lower = new int[arr.length];
    int upperIndex = 0, lowerIndex = 0;

    // Put the elements into their respective pivots
    for (int i = 0; i < arr.length; i++) {
        if (arr[i] <= middle) {
            lower[lowerIndex++] = arr[i];
        } else {
            upper[upperIndex++] = arr[i];
        }
    }

    // Recurse, and sort the pivots
    lower = quicksort(lower, lower[0]);
    upper = quicksort(upper, upper[0]);

    // Combine lower, middle, and upper back into one array
    System.arraycopy(lower, 0, arr, 0, lowerIndex);
    arr[lowerIndex + 1] = middle;
    System.arraycopy(upper, 0, arr, lowerIndex + 2, upperIndex);
    return arr;
}

结果应该是按升序排序的数组。

您的upperlower数组似乎根本没有缩小,因此arr.length == 1永远不会成立。 更容易实现是使用索引而只使用原始数组。

正如Quimby的回答中所提到的,低位和高位都设置为arr.length的大小。 代码需要使用指示实际长度的第三个参数,例如

quicksort(lower, lower[0], lowerIndex);
quicksort(upper, upper[0], upperIndex);

如果数据已经排序,则中间将结束,而不是在每个递归级别,所有数据最终都在较低的位置,上层为零元素,导致无限递归,只能通过堆栈溢出来停止。

由于您正在为快速排序使用单独的阵列,因此您可能需要考虑3路分区:

    public static void quicksort(int[] arr, int pivot, int size) {
        // Base case
        if (size < 2) {
            return;
        }

        int[] upper  = new int[size];
        int[] middle = new int[size];
        int[] lower  = new int[size];
        int upperIndex = 0, middleIndex = 0, lowerIndex = 0;

        // Put the elements into their respective arrays
        for (int i = 0; i < size; i++) {
            if (arr[i] < pivot) {
                lower[lowerIndex++] = arr[i];
            } else if (arr[i] == pivot){
                middle[middleIndex++] = arr[i];
            } else {
                upper[upperIndex++] = arr[i];
            }
        }

        // sort lower and upper
        quicksort(lower,  lower[0], lowerIndex);
        quicksort(upper,  upper[0], upperIndex);

        // Combine lower, middle, and upper back into one array
        System.arraycopy(lower,  0, arr, 0, lowerIndex);
        System.arraycopy(middle, 0, arr, lowerIndex, middleIndex);
        System.arraycopy(upper, 0, arr, lowerIndex+middleIndex, upperIndex);
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM