QuickSort中递归调用partitionStep导致的stackoverflow异常
Stackoverflow exception caused by recursive call of partitionStep in QuickSort
我尝试为 int[]
实现快速排序算法。我对分区步骤进行了正确编码,但后来我想递归调用分区步骤方法来对数组进行排序,不幸的是,我将错误的索引传递给递归调用,我得到了 Whosebug 异常。
我基于: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);
}
}
根本问题是你的递归没有退出条件。您的 partition
方法中没有单个 return 语句。当您的 while 循环退出时,它只会再次调用 partition
方法。但是代码里面没什么好说的,"stop making recursive calls into 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
您缺少用于检查 i
是否小于或等于 j
的 if 语句...
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 );
}
}
}
此外,如果您正在进行深度递归调用,您可能需要考虑使用 -Xss 参数来扩大堆栈大小。您可以在这里找到完整的答案:How to increase the Java stack size?
我知道您的代码有问题,而不是堆栈的实际大小,但是一旦您修复了代码,这可能会很有用。
我尝试为 int[]
实现快速排序算法。我对分区步骤进行了正确编码,但后来我想递归调用分区步骤方法来对数组进行排序,不幸的是,我将错误的索引传递给递归调用,我得到了 Whosebug 异常。
我基于: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);
}
}
根本问题是你的递归没有退出条件。您的 partition
方法中没有单个 return 语句。当您的 while 循环退出时,它只会再次调用 partition
方法。但是代码里面没什么好说的,"stop making recursive calls into 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
您缺少用于检查 i
是否小于或等于 j
的 if 语句...
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 );
}
}
}
此外,如果您正在进行深度递归调用,您可能需要考虑使用 -Xss 参数来扩大堆栈大小。您可以在这里找到完整的答案:How to increase the Java stack size?
我知道您的代码有问题,而不是堆栈的实际大小,但是一旦您修复了代码,这可能会很有用。