在QuickSort中递归调用partitionStep导致的Stackoverflow异常

时间:2015-03-13 01:17:50

标签: java recursion quicksort

我尝试为int[]实施快速排序算法。我正确地编写了分区步骤,但后来我想以递归方式调用分区步骤方法来对数组进行排序,不幸的是我将错误的索引传递给递归调用,我得到了StackOverflow异常。

我的基础是:https://www.youtube.com/watch?v=y_G9BkAm6B8

public class Quicksort {

    public static void partition(int[] t, int i, int j) {

        int start = i, end = j;
        int pivot = t[(i + j) / 2]; // select the pivot as the middle value
        System.out.println("pivot: " + pivot);
        int temp;
        while (i < j) {
            while (t[i] < pivot) { // looking for value greater or equal to the
                                    // pivot
                i++;
            }
            while (t[j] > pivot) { // looking for value lower or equal to the
                                    // pivot
                j--;
            }
            System.out.println("i = " + i + " j = " + j + " swaps " + t[i] + " with " + t[j]);
            temp = t[i]; // swap
            t[i] = t[j];
            t[j] = temp;
            i++; // move to the next element
            j--; // move to the prev element
            display(t);
        }
        // I CALL THEM WRONG
        partition(t, start, j); // partition for the left part of the array
        partition(t, i, end); // partiion for the right part of the array
    }

    public static void display(int[] t) {
        for (int el : t)
            System.out.print(el + " ");
        System.out.println();
    }

    public static void main(String[] args) {
        int[] t = { 6, 4, 1, 32, 5, 7, 8, 6, 9, 1 };
        display(t);
        partition(t, 0, t.length - 1);
    }
}

3 个答案:

答案 0 :(得分:4)

根本问题是你的递归没有退出条件。您的partition方法中没有单个return语句。当你的while循环退出时,它将再次调用partition方法。但是代码中没有任何内容可以说“停止对分区进行递归调用”。因此,堆栈溢出。

我想你至少要在分区函数的顶部说这个。这应该可以清除堆栈溢出。

public static void partition(int[] t, int i, int j) {
    if (i >= j)  {
        return;
    }

我也不确定,但不应该这一行:

partition(t, j, end); //partiion for the right part of the array

真的是这个:

partition(t, i+1, end); //partiion for the right part of the array

答案 1 :(得分:2)

你错过了if语句来检查i之后是否小于或等于j ...

public class QuickSort {

public static void display(int[] arr){
    for(int i = 0; i < arr.length; i++) {
        System.out.println( arr[i] );

    }
}

public static void main( String[] args ) {
    int[] data = new int[]{ 5, 10, 1, 9, 4, 8, 3, 6, 2, 6,7 };
    System.out.println("Unsorted array : " );
    display( data );
    quickSort( data, 0, data.length - 1 );
    System.out.println( "Sorted array: " );
    display( data );
}

public static void quickSort( int[] arr, int left, int right ) {
    int i = left;
    int j = right;
    int temp;
    int pivot = arr[( left + right ) / 2];
    while( i <= j ) {
        while( arr[i] < pivot ) {
            i++;
        }
        while( arr[j] > pivot ) {
            j--;
        }
        // You forgot to test here...
        if( i <= j ) {
            temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
            i++;
            j--;
        }
    }
    if( left < j ) {
        quickSort( arr, left, j );
    }
    if( i < right ) {
        quickSort( arr, i, right );
    }
}

}

答案 2 :(得分:0)

此外,如果您正在进行深度递归调用,您可能希望使用-Xss参数来扩大堆栈大小。您可以在此处找到完整的答案:How to increase the Java stack size?

我知道您的代码存在问题,而不是堆栈的实际大小,但是一旦您修复了代码,这可能会很有用。