问题描述
我是编码初学者,这是我的快速排序的 C 程序。但似乎有些错误,因为对于数组 {6,76,32,18,9,90,43,45,3,1}
,输出结果为 {1,6,90}
。我不知道为什么45
比43
来得早?
#include <stdio.h>
void swap(int *a,int *b) {
int temp = *a;
*a = *b;
*b = temp;
}
int partition(int list[],int l,int r) {
int pi = l;
int too_big = l + 1;
int too_small = r;
while (too_big < too_small) {
while (list[too_big] <= list[pi] && too_big < r)
too_big++;
while (list[too_small] > list[pi] && too_small > l)
too_small--;
if (too_big < too_small)
swap(&list[too_big],&list[too_small]);
}
swap(&list[pi],&list[too_small]);
return too_small;
}
void qsort(int list[],int r) {
if (l < r) {
int pi = partition(list,l,r);
qsort(list,pi - 1);
qsort(list,pi + 1,r);
}
}
解决方法
您可以通过在从 partition
返回之前打印分区数组来调试您的函数。对于您的示例,您会得到:
3 1 6 18 9 90 43 45 32 76
^^
1 3 . . . . . . . .
^^
. . . 9 18 90 43 45 32 76
^^
. . . . . 76 43 45 32 90
^^
. . . . . 32 43 45 76 .
^^
. . . . . 32 43 45 . .
^^
. . . . . . 45 43 . .
^^
(^^
标记枢轴。)您会看到 45
和 43
交换了,但它们不应该交换,因为它们已经按顺序排列了。
当您在最后无条件地将枢轴交换到位以及对包含两个元素的数组进行分区时,就会发生错误交换。在这种情况下,不会进入主循环,您可能将 too_small
放在不属于左分区的元素上。
交换前检查交换是否干扰分区。