了解 bash 脚本

了解 bash 脚本

我有点难以理解书中的以下脚本:

values=(39 5 36 12 9 3 2 30 4 18 22 1 28 25)
numvalues=${#values[@]}

for (( i=0; i < numvalues; i++ )); do 
    lowest=$i

    for (( j=i; j < numvalues; j++ )); do
        if [ ${values[j]} -le ${values[$lowest]} ]; then
            lowest=$j
        fi
    done

    temp=${values[i]}
    values[i]=${values[lowest]}
    values[lowest]=$temp
done

for (( i=0; i < numvalues; i++ )); do
    echo -ne "${values[$i]}\t"
done

echo

该脚本对数组中的数字执行选择排序,并最终按正确的数字顺序对它们进行排序。据书中所述:

外部的 i for 循环用于循环整个数组并指向当前的“头”(我们在其中放置需要交换的任何值)。变量 low 被设置为此索引。

我理解这部分,我猜第一次迭代的最低值将是索引 0,值 39。

我很难理解内部 j 循环是如何工作的。书上说:

它将剩余元素与最低值进行比较;如果值小于最低值,则设置为该元素的索引。

我无法理解 的值j与 的值有什么不同i。在我看来,如果j=i,在第一次迭代 0 上,那么j也等于 0。我想这必须在第二次和后续迭代中改变。我知道 的值j必须与 的值不同i,因为这是[ ${values[j]} -le ${values[$lowest]} ]脚本部分正在计算的值。

这是否因为内部 for 循环的j=i后续部分而起作用?j++如果j=i,并且在第二次迭代中如果i=1,这是否意味着j++等于 2?

新评论:

进一步思考这个脚本。我可以看到 j=i+1 在内循环中如何工作。在第一次迭代中,i 为 0,j 为 1,因此这将比较第一个和第二个元素的值。在进一步的迭代中,i=1 和 j=2、i=2 和 j=3 等等……。

然而,在编写的脚本中我不太明白它是如何工作的。第一次迭代时 i=0 且 j=0。因此数组中的第一个值与其自身进行比较。当然,在第二次迭代中 i=1 且 j=2,因此这将比较第二个和第三个值。我看不到索引 0 与索引 1 是如何比较的。 39 与 5 进行比较。当然,第二次迭代会跳过这一点,因为它将 5 与 36 进行比较。

答案1

在我看来,如果 j=i,即第一次迭代 0,那么 j 也等于 0。

正确的是,对于内部循环的每次第一次迭代,j将等于i

我想这必须在第二次和后续迭代中改变。

也是正确的(对于内循环)。对于内部循环的第一次迭代,将具有外部循环的该迭代中保留的j任何值。i

我知道 的值j必须与 的值不同i,因为这是[ ${values[j]} -le ${values[$lowest]} ]脚本部分正在计算的值。

从(内循环的)第二次迭代开始。

如果j=i,并且在第二次迭代中如果i=1,这是否意味着 j++等于 2?

对于内部循环1的第二次迭代也是正确的。

现在,对于内部循环的每次第一次迭代,ijlowest都是相同的。为什么?lowest已经设置为i.在迭代开始时j设置为,随后的测试将设置为,即,因为它正在比较相同的元素。因此,该内部循环的第一次迭代是毫无意义的,它可以毫无问题地开始。然而,这并不是一个错误,只是没有必要。ilowestjii+1

1从技术上讲,j++将是1,而不是两个,因为++在变量之后,称为 a后增量运算符,在对表达式计算变量后增加值。j将是 2表达式已被求值。

答案2

那个内部循环for (( j=i; j < ...似乎有问题,相比之下“算法”(第四版,Sedgewick & Wayne)使用:

for (int j = i+1; j < ...

对于他们的选择排序示例。

相关内容