Java 快速排序算法抛出StackOverflowException
对于家庭作业,我必须编写一个快速排序算法的实现,并使用它以某种随机顺序对一个包含100k个数字的列表进行排序 在赋值的第一部分中,我必须使用数组的第一项作为枢轴元素。这确实会返回一个排序列表。然而,对于任务的第二部分,我必须使用最后一项作为轴心,这导致StackOverflowException。当我在一个包含8条记录的较小集合中尝试时,它确实可以正常工作。我一直在看我的代码,但我不知道我在哪里犯了错误。任何帮助都将不胜感激。我的代码如下:Java 快速排序算法抛出StackOverflowException,java,algorithm,Java,Algorithm,对于家庭作业,我必须编写一个快速排序算法的实现,并使用它以某种随机顺序对一个包含100k个数字的列表进行排序 在赋值的第一部分中,我必须使用数组的第一项作为枢轴元素。这确实会返回一个排序列表。然而,对于任务的第二部分,我必须使用最后一项作为轴心,这导致StackOverflowException。当我在一个包含8条记录的较小集合中尝试时,它确实可以正常工作。我一直在看我的代码,但我不知道我在哪里犯了错误。任何帮助都将不胜感激。我的代码如下: public class QuickSort {
public class QuickSort {
private QuickSortStrategyEnum quickSortStrategy;
public QuickSort(QuickSortStrategyEnum quickSortStrategy) {
this.quickSortStrategy = quickSortStrategy;
}
public List<Integer> sortIntegerArray(List<Integer> arrayList, int left, int right) {
if ( left >= right ) {
return arrayList;
}
int i = partition(arrayList, left, right);
if (i <= right) {
int pivotNew = partition(arrayList, i, right);
int pivotIndex = arrayList.indexOf(pivotNew);
arrayList = sortIntegerArray(arrayList, left , pivotIndex - 1);
arrayList = sortIntegerArray(arrayList, pivotIndex + 1, right);
}
return arrayList;
}
private int partition(List<Integer> arrayList, int left, int right) {
int pivot = getPivot(arrayList, left, right);
int i = left + 1;
for (int j = i; j <= right; j++) {
if (arrayList.get(j) < pivot) {
Collections.swap(arrayList, j, i);
i++;
}
}
Collections.swap(arrayList, left, i - 1);
return i;
}
private int getPivot(List<Integer> arrayList, int left, int right) {
int pivot = 0;
switch (quickSortStrategy) {
case FIRST:
pivot = arrayList.get(left);
break;
case LAST:
pivot = arrayList.get(right);
break;
}
return pivot;
}
}
公共类快速排序{
私有QuickSortStrategyEnum quickSortStrategy;
公共快速排序(快速排序策略枚举快速排序策略){
this.quickSortStrategy=quickSortStrategy;
}
公共列表排序规则(列表数组列表,左整数,右整数){
如果(左>=右){
返回数组列表;
}
int i=分区(arrayList,左,右);
if(i提示:如果right==left+1
,会发生什么情况?这两行看起来可疑:
int pivotNew = partition(arrayList, i, right);
int pivotIndex = arrayList.indexOf(pivotNew);
查看分区返回的内容,并将其与如何使用其结果进行比较。以及David Harkness指出的事实,分区逻辑存在问题。请尝试:(删除David Harkness指出的内容后)
private int partition(列表arrayList,int left,int right){
int pivot=getPivot(arrayList,左,右);
int i=左-1;
对于(int j=left;j 如果(arrayList.get(j)+1在调试器中单步执行代码会很有用。;)除了分区
做大量繁忙的工作之外,我看不出这种情况有什么问题。不过,我只是在头脑中单步执行。:)知道什么方法/行引发异常会有帮助。嗯,你就在这里,现在解决了这个问题。:)不幸的是,我还没有足够的分数来投票给你。。如果左是第一个元素(0),你将索引I
-1,这将导致集合.swap(arrayList,j,I);
抛出一个IndexOutOfBoundsException
。在桑德的代码中,行是int i=left+1;
。这是一个复制粘贴错误吗?啊,你说得对:)在真正理解这个过程之前,我很快就开始尝试编写一个解决方案。现在我知道它是如何工作的,并且可以继续使用这个解决方案。我不能放弃你u不幸的是,我没有得到足够的分数,但非常感谢!@JessevanAssen注意到,在调用Collections.swap(arrayList,j,I)之前,我增加了I。我已经测试了我的代码,它可以工作了
private int partition(List<Integer> arrayList, int left, int right) {
int pivot = getPivot(arrayList, left, right);
int i = left - 1;
for (int j = left; j < right; j++) {
if (arrayList.get(j) <= pivot) {
i++;
Collections.swap(arrayList, j, i);
}
}
Collections.swap(arrayList, i+1, right);
return i+1;
}