gpt4 book ai didi

c - Understanding ShellSort code from c K&R Book at page 62

转载 作者:太空狗 更新时间:2023-10-29 15:37:41 24 4
gpt4 key购买 nike

我试图理解 K&R 书中第 62 页的 ShellSort 代码。但有一部分我不确定。

下面是书中的原始代码:

void shellsort(int* v, int n) {
int gap, i, j, temp;
for (gap = n / 2; gap > 0; gap /= 2) {
for (i = gap; i < n; i++) {
for (j = i - gap; j >= 0 && v[j] > v[j + gap]; j -= gap) {
temp = v[j];
v[j] = v[j + gap];
v[j + gap] = temp;
}
}
}
}

我想了解为什么会有第三个循环。只有在不能的情况下才可以吗?

这是代码的更改版本(我认为也可以使用的代码):

void shellsort(int* v, int n) {
int gap, i, j, temp;
for (gap = n / 2; gap > 0; gap /= 2) {
for (i = gap; i < n; i++) {
j = i - gap;
if (v[j] > v[j + gap]) {
temp = v[j];
v[j] = v[j + gap];
v[j + gap] = temp;
}
}
}
}

当我运行代码时,它输出与第一个代码相同的内容:

输出:

12345679

但肯定有一些原因在那里使用 for 。我找不到那是什么原因。所以我认为有人可以解决这个问题?

最佳答案

如果您跟踪算法的作用,您可能会更好地了解正在发生的事情。这是您的程序的一个版本,其中包含一些额外的打印语句:

void shellsort(int* v, int n) {
int gap, i, j, temp;
for (gap = n / 2; gap > 0; gap /= 2) {
printf("enter outer loop with gap = %d\n", gap);
for (i = gap; i < n; i++) {
printf("- enter second loop with i = %d\n", i);
for (j = i - gap; j >= 0 && v[j] > v[j + gap]; j -= gap) {
temp = v[j];
v[j] = v[j + gap];
v[j + gap] = temp;
}
printf("- after innermost loop:");
print_array(v, n);
}
}
}

(我省略了print_array的定义。)

按照评论者的建议,使用数组 { 5, 4, 3, 2, 1 } 调用它,得到以下输出:

 5 4 3 2 1
enter outer loop with gap = 2
- enter second loop with i = 2
- after innermost loop: 3 4 5 2 1
- enter second loop with i = 3
- after innermost loop: 3 2 5 4 1
- enter second loop with i = 4
- after innermost loop: 1 2 3 4 5
enter outer loop with gap = 1
- enter second loop with i = 1
- after innermost loop: 1 2 3 4 5
- enter second loop with i = 2
- after innermost loop: 1 2 3 4 5
- enter second loop with i = 3
- after innermost loop: 1 2 3 4 5
- enter second loop with i = 4
- after innermost loop: 1 2 3 4 5
1 2 3 4 5

但是,如果我使用您的代码,仅使用 if 而不是最内层的 for 循环,则会发生以下情况:

 5 4 3 2 1
enter outer loop with gap = 2
- enter second loop with i = 2
- after swap: 3 4 5 2 1
- enter second loop with i = 3
- after swap: 3 2 5 4 1
- enter second loop with i = 4
- after swap: 3 2 1 4 5
enter outer loop with gap = 1
- enter second loop with i = 1
- after swap: 2 3 1 4 5
- enter second loop with i = 2
- after swap: 2 1 3 4 5
- enter second loop with i = 3
- after swap: 2 1 3 4 5
- enter second loop with i = 4
- after swap: 2 1 3 4 5
2 1 3 4 5

结果不正确,因为 1 没有传播到数组的开头。这是由于缺少内部循环。在原始版本中,在 gap = 2i = 4 处,程序比较 51 并交换他们;然后比较 31 并交换它们,以确保这三个元素 (1, 3, 5) 的相对顺序是正确的。没有内部循环,第二次交换就不会完成。在使用 gap = 1 的迭代中将有机会修复此问题,但同样 1 仅与一个元素 (3) 交换,但是不与 2 交换。

或者,对于一个更短但更晦涩的答案:Shell 排序在插入排序的变体上针对各种“间隙大小”执行循环。如果你了解插入排序,你就会知道它由两个嵌套循环组成。如果删除最内层的循环,就会破坏内部插入排序。

最后,在刚刚运行的示例中,您只是运气不好:如果输入(大部分)已排序,即使是损坏的排序算法似乎也可以运行。这些东西很难测试。

关于c - Understanding ShellSort code from c K&R Book at page 62,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41315634/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com