【发布时间】:2013-12-31 21:20:09
【问题描述】:
我正在阅读《C 编程语言》这本书。在其中,它使用了自己的 qsort 实现:
/* qsort: sort v[left]...v[right] into increasing order */
void qsort(int v[], int left, int right)
{
int i, last;
void swap(int v[], int i, int j);
if (left >= right) /* do nothing if array contains */
return; /* fewer than two elements */
swap(v, left, (left + right)/2); /* move partition elem */
last = left; /* to v[0] */
for (i = left + 1; i <= right; i++) /* partition */
if (v[i] < v[left])
swap(v, ++last, i);
swap(v, left, last); /* restore partition elem */
qsort(v, left, last-1);
qsort(v, last+1, right);
}
/* swap: interchange v[i] and v[j] */
void swap(int v[], int i, int j)
{
int temp;
temp = v[i];
v[i] = v[j];
v[j] = temp;
}
我试图通过一个简单的用例来理解这一点,一个包含以下数字的数组:0123456789。
第一次调用 swap 时,它将中间的元素替换为第一个元素。在我们的例子中,0 与 4 交换,所以我们的数组现在看起来像:4123056789。
然后是令人困惑的部分。我们将 i 设置为第一个元素之后的下一个元素(记住第一个元素包含交换后的中间值)。我们的测试一直运行,直到我们达到最后一个索引。我们检查第二个元素是否小于第一个,如果是我们交换它们。在我们的例子中,i 是 1,我们使用预增量运算符将 last 设置为 1(因为 last 被初始化为 0)。所以看起来当我们在第一次循环运行中调用 swap 时,swap 函数的 i 和 j 参数值将被复制为 1。因此我们甚至没有交换任何东西。我错过了什么吗?
【问题讨论】:
-
你可以在每一步插入一些
printfs 来打印出 i 和 j 以及 v 的状态,然后你就可以跟随所有的事情了。仅仅因为它在书中并不意味着它是完美的代码。 :) -
gdb 是你的朋友...