我编写了快速排序算法,在大多数示例中都给出了正确答案(可能不是全部)。
帖子底部的代码给出了输出:
7 3 5 8 3 1
pivot: 5
i = 0 j = 5 swaps 7 with 1
1 3 5 8 3 7
i = 2 j = 4 swaps 5 with 3
1 3 3 8 5 7 //BUT the pivot was 5 why there is 5 on the right from 8?
pivot: 3
i = 1 j = 2 swaps 3 with 3
1 3 3 8 5 7
pivot: 1
i = 0 j = 0 swaps 1 with 1
1 3 3 8 5 7
pivot: 3
i = 2 j = 2 swaps 3 with 3
1 3 3 8 5 7
pivot: 5
i = 3 j = 4 swaps 8 with 5
1 3 3 5 8 7
pivot: 8
i = 4 j = 5 swaps 8 with 7
1 3 3 5 7 8 //FINALLY CORRECT RESULT
这最终是正确的结果,但在输出的开始出现异常。在第一次合并之后,我们有1 3 3 8 5 7
,但是枢轴是5.最后,数组排序正确。我找不到会使算法失败的数组。
我的代码在哪里犯了错误?
public class Quicksort {
public static void partition(int[] t, int i, int j) {
if (i >= j) {
return;
}
int start = i, end = j;
int pivot = t[(i + j) / 2]; // select the pivot as the middle value
System.out.println("pivot: " + pivot);
int temp;
while (i < j) {
while (t[i] < pivot) { // looking for value greater or equal to the pivot
i++;
}
while (t[j] > pivot) { // looking for value lower or equal to the pivot
j--;
}
System.out.println("i = " + i + " j = " + j + " swaps " + t[i] + " with " + t[j]);
if (i <= j) {
temp = t[i]; // swap
t[i] = t[j];
t[j] = temp;
i++; // move to the next element
j--; // move to the prev element
}
display(t);
}
partition(t, start, j); // partition for the left part of the array
partition(t, i, end); // partiion for the right part of the array
}
public static void display(int[] t) {
for (int el : t)
System.out.print(el + " ");
System.out.println();
}
public static void main(String[] args) {
int[] t = { 7, 3, 5, 8, 3, 1 };
display(t);
partition(t, 0, t.length - 1);
}
}
答案 0 :(得分:1)
您的排序算法基本上是正确的。
我相信我们可以证明您的分区步骤会导致:
all elements in the left part <= pivot
和
all elements if the right part >= pivot
。
然后单独排序就足够了。确认小阵列,并有感应证明。
要获得像[< pivot, = pivot, > pivot]
这样的“正确”分区,您需要确保正确维护不变量。
您可能需要三个指针,而不是您正在使用的两个指针。请参阅Dutch National Flag problem。
不过,你应该调用你的递归方法sort
而不是分区。 while循环是分区步骤。