我正在尝试在java中编写快速排序。但是,对于非常小的输入集,获得堆栈超过流量错误。在createArray函数中,我正在接受Scanner对象的输入。
请有人帮助我。
public class quickSort {
static int[] ar;
int number;
public static void main(String args[]) {
CreatingArray ca = new CreatingArray();
ar = ca.createArray();
ca.printArray(ar);
int len = ar.length;
sort(0,(len-1));
System.out.println("");
System.out.println("Array after QuickSort:");
ca.printArray(ar);
}
public static void sort(int l,int h) {
int i=l;
int j=h;
int temp =0;
int pivot = ar[(l + (l+h)/2)];
while(i <= j) {
while(ar[i] < pivot) {
i++;
}
while(ar[j] > pivot) {
j--;
}
if (i<=j) {
temp = ar[i];
ar[i] = ar[j];
ar[j] = temp;
i++;
j--;
}
}
if(l<j){
sort(l,j);
}
if(i<h) {
sort(i,h);
}
}
}
答案 0 :(得分:2)
int pivot = ar[(l + (l+h)/2)];
这条线错了。它仅在l == 0
时获得中心点。例如,如果l == 4 && h == 7
(例如,8个元素数组的上半部分),则得到4 + (4+7)/2
9
,因此超出边界。你真的想要l + (h-l+1)/2
。
由于这个原因可能发生的第一件事是ArrayIndexOutOfBoundsException
,但是你永远不会得到它,因为你总是首先在下层分区上进行递归并遇到第二个问题。交换函数末尾的两个if
以查看此操作。
可能发生的第二件事是,因为pivot
实际上不是范围[i, j]
中的元素,所以循环开始时的元素搜索会变得疯狂。特别是,pivot
可能是一个非常小的值,小于该范围内的任何值。 i
搜索将立即终止(保留i == l
开始的方式),而j
搜索将超出i
,这意味着if
赢了也不输入,i
仍然没有改变,主循环终止。由于i
未更改,i<h
仍然为真(假设l<h
为),并且您输入的递归调用与您刚刚拥有的完全相同的参数,这意味着下一个调用将完全执行与当前的一样,以无限递归结束。
答案 1 :(得分:0)
我认为你的递归调用不会结束...用非常小的输入调试你的代码 - 比如3个数字...检查调用sort()的时间和方式......