我试图将QuickSort算法作为大学的家庭作业,但我只是不明白我的代码中哪里有错误。我认为这是一个合乎逻辑的错误,我认为我错误地交换了我的枢轴。我真的可以使用一些帮助,谢谢你提前。有代码:
public class QuickSort {
private int [] array;
public QuickSort(int [] array){
this.array = array;
}
public void sort(){
partition(0, array.length - 1);
}
public void partition(int start, int end){
if (end - start < 2){
return;
}
int pivot_index = end;
int i = start;
int j = end - 1;
while (i < j){
//both elements are not in the right place
if(array[i] > array[pivot_index] && array[j] <= array[pivot_index]){
swap(array, i, j);
i++;
j--;
}
//the element on the left is not in place
else if (array[i] > array[pivot_index] && array[j] > array[pivot_index]){
j--;
}
//the element on the right is not in place
else if (array[i] < array[pivot_index] && array[j] < array[pivot_index]){
i++;
}
//both elements are in place
else {
i++;
j--;
}
}
if (array[i] > array[pivot_index]){
swap(array, pivot_index, i);
pivot_index = i;
}
partition(start, pivot_index - 1);
partition(pivot_index + 1, end);
}
private static void swap(int [] tab, int index1, int index2){
int temp = tab[index1];
tab[index1] = tab[index2];
tab[index2] = temp;
}
}
答案 0 :(得分:2)
解决方案一
想法是遍历数组以检查当前元素是否小于最后一个元素(枢轴),如果是,则交换第一个不是(index是lastSmaller + 1)。
private void partition(int start, int end) {
if (start >= end) {
return;
}
int lastSmallest = start - 1;
for (int i = start; i < end; i++) {
if (array[i] < array[end])
swap(++lastSmallest, i);
}
swap(++lastSmallest, end);
partition(start, lastSmallest - 1);
partition(lastSmallest + 1, end);
}
解决方案二
我认为这是你想要实现的。遍历数组,跳过左右两侧的所有元素。将两者交换在错误的位置。
private void partition(int start, int end) {
if (end <= start) {
return;
}
int k = end;
int i = start;
int j = end - 1;
while (i < j) {
// left is in place
while (i < j && array[i] < array[k]) {
i++;
}
// right is in place
while (i < j && array[j] >= array[k]) {
j--;
}
// both are not good
if (i < j) {
// swap
int temp = array[i];
array[i] = array[j];
array[j] = temp;
i++;
j--;
}
}
// swap left and pivot
if (array[i] >= array[k]) {
int temp = array[i];
array[i] = array[k];
array[k] = temp;
}
partition(start, i - 1);
partition(i + 1, end);
}
您的解决方案不起作用的原因是当您发现两者都不到位时,您可以交换它们并继续对数组的其余部分进行分区。但是,您无法保证已交换的内容不违反规则。因此,您需要首先跳过两侧的所有元素然后交换。