快速排序示例中的错误(K&R C 书)?
Posted
技术标签:
【中文标题】快速排序示例中的错误(K&R C 书)?【英文标题】:Bug in quicksort example (K&R C book)? 【发布时间】:2011-09-23 03:17:18 【问题描述】:这种快速排序应该将“v[left]...v[right] 排序为升序”;从 K&R 的 The C Programming Language (Second Edition) 复制(没有 cmets):
void qsort(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(v, left, last-1);
qsort(v, last+1, right);
我认为这里有一个错误
(left + right) / 2
假设左 = INT_MAX - 1,右 = INT_MAX。由于整数溢出,这不会导致未定义的行为吗?
【问题讨论】:
它可能是在假设数组在运行时不会那么大的情况下进行编程的。 :) 这是一个很好的假设,因为您的快速排序程序没有内存空间 另见:googleresearch.blogspot.com/2006/06/… @functionptr 你能回答这个问题吗? ***.com/questions/24534487/quick-sort-programmed-in-c 【参考方案1】:K&R 在使用无符号和有符号参数时总是有点草率。我想使用只有 16 KB 内存的 PDP 会产生副作用。那是前一阵子修好的。目前qsort的定义是
void qsort(
void *base,
size_t num,
size_t width,
int (__cdecl *compare )(const void *, const void *)
);
注意使用 size_t 而不是 int。当然还有 void* base 因为你不知道你在排序什么类型。
【讨论】:
__cdecl
疣不是标准定义的一部分。
我确定这是真的,当时他们可能只有 一个 调用约定。以 two 下划线开头的关键字要少得多。让供应商让它变得复杂。必然如此,标准的有点sux。【参考方案2】:
是的,你是对的,虽然它可能只是为了简单起见才这样写——毕竟这是一个示例,而不是生产代码。
【讨论】:
【参考方案3】:您不会想象一个包含 INT_MAX
个元素的数组,是吗?
【讨论】:
假设为 32 位整数,这还不到 8 GB 的地址空间。在现代硬件上不仅仅是可行的。 :) 我们可能不得不原谅 K&R 没有考虑将内存从 kB 增加到 GB。并且“640k 应该对每个人都足够了”? @Bo 有 16 位的平台int
s,你知道,我很确定其中一些有超过 64Kb 的内存。 int
!= intptr_t
.【参考方案4】:
是的,你是对的。您可以使用left - (left - right) / 2
来避免溢出。
【讨论】:
@Jerry / Paul:由于(right - left) == - (left - right)
,与此答案的表述相同。
@caf:啊,我没有这么想,但你是对的。我撤销我原来的评论,并为我的迟钝道歉。以上是关于快速排序示例中的错误(K&R C 书)?的主要内容,如果未能解决你的问题,请参考以下文章