【发布时间】:2011-06-05 01:42:47
【问题描述】:
我在使用 java 中的堆栈时遇到了一些问题...我正在使用 ArrayList 实现快速排序 - 我将在最后附上我的完整代码,但这里是相关位(请记住,我一直调试了几个小时,完全不知道出了什么问题,所以你看到事情以奇怪/等方式完成的地方很可能是因为我试图在那里检查错误):
显然执行了太多次的调用:
QuickSort(numArray, m+1, right);
这里失败了:
//Swap pivot and left
numArray.set(pivot, leftVal);
我得到了输出:
Starting sort number: [1] : RandomPivot [ON] : Sorting [RANDOM]
Sorted: 2496 elements.
Took: 53 milliseconds.
Starting sort number: [2] : RandomPivot [ON] : Sorting [RANDOM]
Sorted: 4988 elements.
Took: 25 milliseconds.
Starting sort number: [3] : RandomPivot [ON] : Sorting [RANDOM]
Sorted: 7478 elements.
Took: 49 milliseconds.
Starting sort number: [4] : RandomPivot [ON] : Sorting [RANDOM]
Sorted: 9953 elements.
Took: 85 milliseconds.
Starting sort number: [5] : RandomPivot [ON] : Sorting [RANDOM]
Sorted: 12416 elements.
Took: 131 milliseconds.
Starting sort number: [1] : RandomPivot [ON] : Sorting [SORTED]
Sorted: 2497 elements.
Took: 1 milliseconds.
Starting sort number: [2] : RandomPivot [ON] : Sorting [SORTED]
Sorted: 4984 elements.
Took: 1 milliseconds.
Starting sort number: [3] : RandomPivot [ON] : Sorting [SORTED]
Sorted: 7482 elements.
Took: 2 milliseconds.
Starting sort number: [4] : RandomPivot [ON] : Sorting [SORTED]
Sorted: 9950 elements.
Took: 2 milliseconds.
Starting sort number: [5] : RandomPivot [ON] : Sorting [SORTED]
Sorted: 12424 elements.
Took: 2 milliseconds.
Starting sort number: [1] : RandomPivot [ON] : Sorting [REVERSE SORTED]
Sorted: 2494 elements.
Took: 2 milliseconds.
Starting sort number: [2] : RandomPivot [ON] : Sorting [REVERSE SORTED]
Sorted: 4988 elements.
Took: 10 milliseconds.
Starting sort number: [3] : RandomPivot [ON] : Sorting [REVERSE SORTED]
Sorted: 7470 elements.
Took: 35 milliseconds.
Starting sort number: [4] : RandomPivot [ON] : Sorting [REVERSE SORTED]
Sorted: 9962 elements.
Took: 50 milliseconds.
Starting sort number: [5] : RandomPivot [ON] : Sorting [REVERSE SORTED]
Sorted: 12419 elements.
Took: 65 milliseconds.
Starting sort number: [1] : RandomPivot [OFF] : Sorting [RANDOM]
Sorted: 2497 elements.
Took: 5 milliseconds.
Starting sort number: [2] : RandomPivot [OFF] : Sorting [RANDOM]
Sorted: 4984 elements.
Took: 54 milliseconds.
Starting sort number: [3] : RandomPivot [OFF] : Sorting [RANDOM]
Sorted: 7473 elements.
Took: 47 milliseconds.
Starting sort number: [4] : RandomPivot [OFF] : Sorting [RANDOM]
Sorted: 9958 elements.
Took: 80 milliseconds.
Starting sort number: [5] : RandomPivot [OFF] : Sorting [RANDOM]
Sorted: 12419 elements.
Took: 130 milliseconds.
Starting sort number: [1] : RandomPivot [OFF] : Sorting [SORTED]
Sorted: 2498 elements.
Took: 11 milliseconds.
Starting sort number: [2] : RandomPivot [OFF] : Sorting [SORTED]
Sorted: 4991 elements.
Took: 44 milliseconds.
Starting sort number: [3] : RandomPivot [OFF] : Sorting [SORTED]
Sorted: 7474 elements.
Took: 97 milliseconds.
Starting sort number: [4] : RandomPivot [OFF] : Sorting [SORTED]
Exception in thread "main" java.lang.StackOverflowError
at java.util.ArrayList.set(Unknown Source)
at Sorter.QuickSort(Sorter.java:64)
at Sorter.QuickSort(Sorter.java:107)
at Sorter.QuickSort(Sorter.java:107)
at Sorter.QuickSort(Sorter.java:107)
at Sorter.QuickSort(Sorter.java:107)
(on and on and on and on)
测试,一旦我的 ArrayList 的大小超过了 ~7500,它总是会失败。总是在“ArrayList.set()”处失败,我对原因一无所知。正如你所看到的 - 所有其他排序类型都可以正常处理超过这个数量的数字,但是对于排序列表,我将不得不调用“m+1,right”n 次,其中 n 是列表的大小。
我试过了:
if(m-1>left && m-1<right)
QuickSort(numArray, left, m-1);
if(m+1<right && m+1>left)
QuickSort(numArray, m+1, right);
但无论哪种方式我都会遇到相同的错误,我认为如果省略它会更容易理解。
如果我能以某种方式增加堆栈大小,我也许可以推迟错误,这至少可以让我分析不同的方法。
我正在通过 Eclipse 运行此代码,如果这有什么不同的话。谢谢! (现在是完整代码)
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Random;
import java.util.Set;
import java.util.TreeSet;
public class Sorter {
//STATE:
public boolean test=false;
public boolean randomPivot=false;
Random r = new Random();
public int sortMethod=1;
public static int RANDOM=1;
public static int SORTED=2;
public static int REVERSE_SORTED=3;
public Sorter(){ }
public ArrayList<Integer> SlowSort(ArrayList<Integer> numArray){
//Add "infinity" to the end
numArray.add(Integer.MAX_VALUE);
//TIME AND RUN QUICKSORT
long startTime = System.currentTimeMillis();
numArray=QuickSort(numArray, 0, numArray.size()-2);
long stopTime = System.currentTimeMillis();
long runTime = stopTime - startTime;
//Remove "infinity" from the end
numArray.remove(numArray.size()-1);
//TODO: Printing effs it up? idk
// printArrayWithMessage("Sort Finished.", numArray);
//PRINT COMPLETION MESSAGE AND RETURN
System.out.println("Sorted: "+numArray.size()+" elements.\nTook: " + runTime+" milliseconds.\n");
return numArray;
}
public ArrayList<Integer> QuickSort(ArrayList<Integer> numArray, int left, int right){
if(left>=right){
return numArray;
}
//Correctly Initialize Pivot
int pivot=0;
if(randomPivot){
pivot = r.nextInt(right-left);
}
pivot+=left;
//Swap pivot and left
Integer temp = numArray.get(pivot);
// System.out.println(numArray.size()+" "+pivot);
int leftVal=numArray.get(left);
numArray.set(pivot, leftVal);
pivot=temp;
numArray.set(left, pivot);
Integer m=0;
//REPEAT:
while(true){
int i=left+1;
int j=right+1;
while(numArray.get(i).intValue()<pivot){
i++;
}
while(numArray.get(j).intValue()>pivot){
j--;
}
if(i<j){
//Swap i and j
if(test) printArrayWithMessage("[SWAP] (i="+i+") and (j="+j+")", numArray);
Integer a=numArray.get(i);
numArray.set(i, numArray.get(j));
numArray.set(j, a);
}
if(i>j){
//Swap pivot and j
if(test) printArrayWithMessage("[SWAP] (j="+j+") and (pivot="+left+")", numArray);
numArray.set(left, numArray.get(j));
numArray.set(j, pivot);
m=j;
break;
}
}
if(test) printArrayWithMessage("Iteration Finished... Left: "+left+" Right: "+right, numArray);
QuickSort(numArray, left, m-1);
QuickSort(numArray, m+1, right);
return numArray;
}
public void benchmark(){
for(int i=1;i<6;i++){
//CREATE BLANK DATA STRUCTURES
ArrayList<Integer> numList = new ArrayList<Integer>();
Set<Integer> doublesFilter;
if(sortMethod==RANDOM){
doublesFilter = new HashSet<Integer>();
}else{
doublesFilter = new TreeSet<Integer>();
}
//FILL ARRAYLIST WITH UNIQUE NUMBERS
for(int j=0;j<2500*i;j++){
int num=r.nextInt(1000000);
if(doublesFilter.add(num)){
if(sortMethod==RANDOM){
numList.add(num);
}
}
}
if(sortMethod==SORTED){
numList.add(0);
numList.ensureCapacity(doublesFilter.size());
numList.addAll(doublesFilter);
numList.remove(0);
}
else if(sortMethod==REVERSE_SORTED){
numList.add(0);
numList.ensureCapacity(doublesFilter.size());
numList.addAll(((TreeSet<Integer>) doublesFilter).descendingSet());
numList.remove(0);
}
System.out.println("Starting sort number: ["+i+"] : "+getMode());
numList=SlowSort(numList);
}
}
public void printArrayWithMessage(String s, ArrayList<Integer> list){
System.out.println(s);
System.out.println(list);
System.out.println();
}
public String getMode(){
String rPivot="OFF";
if(randomPivot) rPivot="ON";
String sortMode="UNDEFINED";
if(sortMethod==1)sortMode="RANDOM";
if(sortMethod==2)sortMode="SORTED";
if(sortMethod==3)sortMode="REVERSE SORTED";
return "RandomPivot ["+rPivot+"] : "+"Sorting ["+sortMode+"]";
}
}
【问题讨论】:
-
我想我会等待 DVD,但与此同时,请尝试使用调试器对其进行调试并逐步执行您的代码。您可能正在重试终止条件,例如,您正在传递一个空列表并且正在重试
-
QuickSort(numArray, m, right);也许?只是一个疯狂的猜测
标签: java eclipse stack stack-overflow quicksort