我一直在阅读所有关于SO的QuickSort问题,但我无法解决这个具体问题。通过引用其他问题并将我的错误与他们的错误进行比较,我得到了一个特定点,即使在调试模式下,我也找不到答案。
我一再超出界限-1,所以我添加了一个条件检查
if(pivot > 0)
并且停止了溢出,但由于我使用0作为我的分区,它分区一次然后终止。第一个分区是正确的,但是如果我将该数字更改为包含0,那么我将再次获得无限递归。如果我完全接受了这条线路,我会得到索引超出界限的错误,这些错误似乎无法解决。
这是我到目前为止的地方:
public class QuickSort {
int[] array;
public static void main(String[] args) {
QuickSort qs = new QuickSort();
qs.array = new int[] {35, 82, 2, 24, 57, 17};
qs.quickSort(qs.array, 0, qs.array.length - 1);
for(int i = 0; i < qs.array.length; i++) {
System.out.println(qs.array[i]);
}
}
public void quickSort(int[] array, int left, int right) {
if(array.length == 1) {
return;
}
if(left < right) {
int pivot = partition(array, left, right);
quickSort(array, left, pivot - 1);
quickSort(array, pivot + 1, right);
}
}
public int partition(int[] array, int left, int right) {
if(array.length == 1) {
return right;
}
int pivot = array[0];
int pivotIndex = 0;
int leftPointer = left - 1;
int rightPointer = right + 1;
while(pivotIndex < right) {
if(leftPointer > rightPointer) {
break;
}
leftPointer++;
while(leftPointer < array.length - 1 && array[leftPointer] <= pivot) {
leftPointer++;
}
rightPointer--;
while(rightPointer > leftPointer && array[rightPointer] > pivot) {
rightPointer--;
}
if(leftPointer < rightPointer) {
int temp = array[leftPointer];
array[leftPointer] = array[rightPointer];
array[rightPointer] = temp;
} else {
int temp = array[rightPointer];
array[rightPointer] = array[pivotIndex];
array[pivotIndex] = temp;
}
}
return rightPointer;
}
编辑:经过几次更改后,我现在可以让它始终返回一个没有溢出的数组,但它仍然只分区一次。
答案 0 :(得分:0)
我认为你应该改变
if(leftPointer > rightPointer) {
break;
}
到
if(leftPointer >= rightPointer) {
break;
}
在while循环中。
此外,我认为你应该在更改之后将leftPointer与rightPointer进行比较,
// move to @@@@ to perform compare after possible change
// if(leftPointer > rightPointer) break;
//leftPointer++;
while(leftPointer < array.length - 1 && array[leftPointer] <= pivot) leftPointer++;
//rightPointer--;
while(rightPointer > leftPointer && array[rightPointer] > pivot) rightPointer--;
//@@@@
if(leftPointer > rightPointer) break;
答案 1 :(得分:0)
每当数组长度不为1时,您将从分区返回“0”,并将其设置为数据透视表。在这种情况下,if(pivot >= 0)
将始终被点击,如果您使用if(pivot > 0)
,它将会迭代一次,我认为这是问题所在。如果这是正确的,那么纠正从分区返回(到“左”?)应该可以解决问题。
答案 2 :(得分:0)
我很确定我现在修好了。你想在之前增加分区方法中的左右指针(在“检查”之外)。按如下方式更改分区方法:
public static int partition(int[] array, int left, int right) {
if(array.length == 1)
return right;
int pivot = array[0];
int pivotIndex = 0;
int leftPointer = left; // Remove the +1
int rightPointer = right; // Remove the +1
while(pivotIndex < right) {
if(leftPointer > rightPointer) {
break;
}
//leftPointer++;
while((leftPointer < array.length - 1) && (array[leftPointer] <= pivot)) {
leftPointer++;
}
//rightPointer--;
while((rightPointer > leftPointer) && (array[rightPointer] > pivot)) {
rightPointer--;
}
if(leftPointer < rightPointer) {
int temp = array[leftPointer];
array[leftPointer] = array[rightPointer];
array[rightPointer] = temp;
}
else {
int temp = array[rightPointer];
array[rightPointer] = array[pivotIndex];
array[pivotIndex] = temp;
}
}
return rightPointer;
}