k& r QuickSort问题
我似乎无法理解 K&R(C 编程语言第二版)的 qsort
实现中的问题所在。
void qsort_1(int v[], int left, int right)
{
int i, last;
void swap(int v[], int i, int j);
if (left >= right)
return;
swap(v, left, (left + right)/2);
last = left;
for (i = left + 1; i <= right; i++)
if (v[i] < v[left])
swap(v, ++last, i);
swap(v, left, last);
qsort_1(v, left, last-1);
qsort_1(v, last+1, right);
}
这是他们的版本,我只是将其重命名为 qsort_1
,以便我可以同时使用内置版本。
int arr_len = 9;
int main() {
int a[] = { 5, 5, 4, 6, 3, 7, 8, 13, 17 };
int b[] = { 5, 5, 4, 6, 3, 7, 8, 13, 17 };
print_a(a, arr_len); // print first array
print_a(b, arr_len); // print second array
putchar('\n'); // space
qsort(b, arr_len, sizeof(int), cmpfunc); // sort second array with standard qsort
qsort_1(a, 0, arr_len); // sort first array with K&R qsort
print_a(a, arr_len); // print first array
print_a(b, arr_len); // print second array
return 0;
}
print_a
是一个用于显示数组的迷你函数,只需一个 for 循环。 qsort
是官方标准实现。
我得到的输出是:
gcc -O2 -lm -o qsort qsort.c
5 5 4 6 3 7 8 13 17
5 5 4 6 3 7 8 13 17
0 3 4 5 5 6 7 8 13
3 4 5 5 6 7 8 13 17
似乎有一个前导 0
并且每次 K&R qsort 中最后一个元素都会被删除。 ...帮助
void print_a(int a[], int len) {
for (int i = 0; i < len; i++) {
printf("%d ", a[i]);
}
printf("\n");
}
int cmpfunc (const void * a, const void * b) {
return ( *(int*)a - *(int*)b );
}
如果需要,这里有 cmpfunc
和 print_a
。
尝试用谷歌搜索这个问题,但似乎没有人遇到同样的问题。
编辑: main函数中的代码发生了变化:
int main() {
int a[] = { 5 , 5 ,4 ,6 ,3 ,7 ,8, 13, 17 };
int b[] = { 5 , 5 ,4 ,6 ,3 ,7 ,8, 13, 17 };
print_a(a, arr_len);
print_a(b, arr_len);
putchar('\n');
qsort(b, arr_len, sizeof(int), cmpfunc);
qsort_1(a, 0, **arr_len - 1**);
print_a(a, arr_len);
print_a(b, arr_len);
return 0;
}
I seem to be having a problem understanding where the issue is in the qsort
implementation by K&R (C Programming Language second edition).
void qsort_1(int v[], int left, int right)
{
int i, last;
void swap(int v[], int i, int j);
if (left >= right)
return;
swap(v, left, (left + right)/2);
last = left;
for (i = left + 1; i <= right; i++)
if (v[i] < v[left])
swap(v, ++last, i);
swap(v, left, last);
qsort_1(v, left, last-1);
qsort_1(v, last+1, right);
}
This is their version, I only renamed it to qsort_1
so that I could use the built in one at the same time.
int arr_len = 9;
int main() {
int a[] = { 5, 5, 4, 6, 3, 7, 8, 13, 17 };
int b[] = { 5, 5, 4, 6, 3, 7, 8, 13, 17 };
print_a(a, arr_len); // print first array
print_a(b, arr_len); // print second array
putchar('\n'); // space
qsort(b, arr_len, sizeof(int), cmpfunc); // sort second array with standard qsort
qsort_1(a, 0, arr_len); // sort first array with K&R qsort
print_a(a, arr_len); // print first array
print_a(b, arr_len); // print second array
return 0;
}
print_a
is a mini function for displaying an array, just one for loop.qsort
is the official standard implementation.
The output I get is:
gcc -O2 -lm -o qsort qsort.c
5 5 4 6 3 7 8 13 17
5 5 4 6 3 7 8 13 17
0 3 4 5 5 6 7 8 13
3 4 5 5 6 7 8 13 17
There seems to be a leading 0
and the last element is removed in the K&R qsort everytime. ...Help
void print_a(int a[], int len) {
for (int i = 0; i < len; i++) {
printf("%d ", a[i]);
}
printf("\n");
}
int cmpfunc (const void * a, const void * b) {
return ( *(int*)a - *(int*)b );
}
If needed, here are the cmpfunc
and print_a
.
Tried googling the problem but no one seemed to have the same issue.
EDIT:
The code changed in the main function:
int main() {
int a[] = { 5 , 5 ,4 ,6 ,3 ,7 ,8, 13, 17 };
int b[] = { 5 , 5 ,4 ,6 ,3 ,7 ,8, 13, 17 };
print_a(a, arr_len);
print_a(b, arr_len);
putchar('\n');
qsort(b, arr_len, sizeof(int), cmpfunc);
qsort_1(a, 0, **arr_len - 1**);
print_a(a, arr_len);
print_a(b, arr_len);
return 0;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如有疑问,请查看代码 您 写道。
Qsort
的作者也知道他们在做什么。因此,我们应该查看 you 撰写的第一个地方。那你真正的作者是什么。打印功能,
Qsort
比较器,基本上是main
中的所有内容。快速审查显示:print_a
肯定可以,只要基本地址和长度有效(在这种用法中,它们是有效的),所以这已经消失了。QSORT
比较器似乎正确,因为(a)起作用,并且(b)它与完全无关的函数的可疑输出无关,qsort_1
。所以出来了。仅留下
main
。在该功能中,我们可以:从中:
print_a
呼叫查看OK(基本地址和长度有效)。QSort
是无关的,显然还可以。在整个程序中只留下一行代码,可能是罪魁祸首:
检查算法,k&amp; r函数期望:
这就是问题。
arr_len
不是最后一个索引。它是序列的长度。由于C中的数组是基于0索引的数组,因此最后一个索引为arr_len-1
,而不是arr_len
。修复了这一点:
代码将正常工作。
When in doubt, look at the code you wrote.
qsort
in the standard library knew what they were doing as well.Therefore, the first places we should look at what you authored. So what did you really author. The print function, the
qsort
comparator, and basically everything inmain
. A quick review reveals:print_a
is certainly ok, provided the base address and length are valid (and they are in this usage case), so that's out.qsort
comparator seems correct, since (a) it works, and (b) it has nothing to do with questionable output from a totally unrelated function,qsort_1
. So that's out.That leaves only
main
. Within that function we have:From this:
print_a
calls check out ok (base address and length are valid).qsort
is unrelated, and obviously ok.That leave only one line of code in this entire program that could be the culprit:
Checking the algorithm, the K&R function expects:
0
. (ok)That's the problem.
arr_len
is not the last index. It is the length of the sequence. Since arrays in C are 0-index based, the last index is thereforearr_len-1
, notarr_len
.Fix that:
And the code will work as-expected.