【发布时间】:2016-03-19 02:37:35
【问题描述】:
我对冒泡排序伪代码中的特定行有疑问。
我不明白为什么i = (n-1)。是不是应该从最后一个元素(1和7)开始比较?
【问题讨论】:
-
这看起来是不是太明显了?这就是你问的原因吗?因为我会说是的,这正是它的意思:从数组的末尾开始,一直到开头。但它永远不会触及 i = 0。
标签: algorithm bubble-sort
我对冒泡排序伪代码中的特定行有疑问。
我不明白为什么i = (n-1)。是不是应该从最后一个元素(1和7)开始比较?
【问题讨论】:
标签: algorithm bubble-sort
没有。比较的元素具有索引j 和j+1。在内部循环的第一次迭代中,j==0,以便您比较元素 5 和 9。
花一些时间手动“运行”算法。
【讨论】:
不,您的“冒泡”排序算法总是从前面开始工作。即使外部循环向后计数,变量i 也不会用于引用数组索引,只有j 是在内部循环中定义的。相反,您的代码中的外层循环用于确定在您的内层循环中计数多高,表示我们需要执行多少次比较。
代码是这样工作的:
假设A 持有我们的数组:[5,9,2,7,1],“n”为 5,即数组的长度,并且我们的 swap 函数有效,则运行外循环:for i=(n-1) to 1。这会将i 设置为4。循环将运行4 次。我们代码中的变量i 表示要进行的比较次数。
内部循环运行:for j = 0 to (i-1) 这将 j 设置为 0。循环将运行 4 次。
我们的 if 语句被称为:if A[j] < A[j+1] 从而比较索引 0 和 1。A[0] 持有 5,A[1] 持有 9。由于 5 小于 9,因此我们的 if 语句为真。
@ 987654335@ 被调用。现在我们的数组是:[9,5,2,7,1]
我们的内循环再次运行,j=1。
我们的 if 语句比较索引 1 和 2。A[1] 持有 5,A[2] 持有 2。由于 5 不小于 9,我们的 if 语句为假。
我们的内循环再次运行,j=2。
我们的 if 语句比较索引 2 和 3。A[2] 持有 2,A[3] 持有 7。由于 2 小于 7,我们的 if 语句为真。swap(A[j],A[j+1]) 被调用。我们的数组现在显示为:[9,5,7,2,1]
我们的内循环再次运行,j=3。
我们的 if 语句比较索引 3 和 4。A[3] 持有 2,A[4] 持有 1。我们的 if 语句为假。
我们的内循环已经完成,我们现在知道我们的最后一个元素是正确。
所以我们再次运行我们的外循环。 i 现在是 3,因为我们的最后一个元素是正确的。
我们以 j=0 运行我们的内循环。它将运行到i,即 3。
A[0] 持有 9,A[1] 持有 5,我们的 if 语句为假。
下一个循环,j=1。
A[1] 持有 5,A[2] 持有 7。我们的 if 语句为真,所以我们交换它们。
我们的数组现在读取:[9,7,5,2,1]
我们的逻辑一直持续到我们确定倒数第二个元素正确。
内循环完成后,我们再次运行外循环:i 现在是 2,要进行的比较次数。
我们的内循环以 j=0 到 1 触发。
因此,我们将索引 0 与 1 以及 1 与 2 进行比较。两者都产生错误。
我们现在可以确定我们的中间元素是正确。i 现在是 1,这意味着我们进行了一次比较。
我们的内循环以 j=0 到 0 运行:
因此我们比较索引 0 和 1,因为我们的 if 语句是假的,所以我们不交换任何东西。
我们的内部循环完成。
我们现在确定我们的第二个元素是正确。
我们的外循环完成。
我们现在确定我们的整个数组是正确的。
我们的数组现在已排序:[9,7,5,2,1]
该算法在最坏的情况下也能正常工作:
http://jsfiddle.net/mw5L8qzL/
(一个空数组,一个只包含一个元素的数组)
【讨论】:
外部循环将 A[0,...,i] 范围内的最大元素“冒泡”到插槽 A[i]。因此,在下一次迭代中,您可以忘记 A[i],并将作业限制为对 A[0,...,i-1] 进行排序。 显然,当外循环的 n-1 次迭代后问题大小为 1 时,范围内只剩下一个元素,因此您就停在那里。
【讨论】: