我是一名自学成才的计算机科学专业的学生。 现在我正在阅读CLRS,我做了2.2-2练习,这是关于选择排序。
第一个数组下标是1.
我写的伪代码是:
FOR i=1 to A.length - 1
FOR j=i+1 to A.length
IF A[j] < A[i]
new_index=j
IF new_index > i
tmp = A[i]
A[i] = A[new_index]
A[new_index] = A[i]
我的理由是:
第一次循环测试执行n次(1,2,3 ... n)。当我变成n时,循环停止。因此第5行执行(n-1)次,依此类推。
然后我认为执行第二次循环测试(n ^ 2 + n - 2)/ 2次。当初始j = 2时,假定:2,3,4,5 ...(n + 1),循环测试执行n次,当j = 3时执行循环测试(n - 1)次,所以上。所以当j = n时,循环测试执行2次。
出于这个原因,执行第二个循环测试: 2 + 3 + 4 + 5 + ... + n = [(n-1)*(n + 2)] / 2 =(n ^ 2 + n - 2)/ 2。 因此执行第二个循环的内部if:1 + 2 + 3 + 4 + ... +(n-1)= [(n-1)* n] / 2.
在写这篇文章之前,我读了许多假设的解决方案,但没有人等于我的。所以我想知道我的推理是否错误。
我希望我能以良好的形式写下所有细节。
答案 0 :(得分:1)
伪代码是正确的,你的分析是正确的,但你的解决方案在推理中有一些错误。
然后我认为第二次循环测试是执行(n ^ 2 + n - 2)/ 2次
执行n(n-1)/ 2次。请参阅下面的解决方案。
当初始j = 2时,它假设:2,3,4,5 ... (n + 1),循环测试执行 n 次,
记住代码是:FOR j=i+1 to A.length
,所以当内部for循环从j = 2开始时,它会上升到j = A.length,即它上升到j = n。换句话说,它为j = 2,3,4,...,n重复执行,因此总共 n - 1次,而不是 n次!
由于这个原因,执行第二次循环测试:2 + 3 + 4 + 5 + ... + n = [(n-1)*(n + 2)] / 2 =(n ^ 2 + n - 2)/ 2.因此执行第二个循环的内部if:1 + 2 + 3 + 4 + ... +(n-1)= [(n-1)* n] / 2.
假设第二个循环的if语句的主体总是执行(if条件总是为真),那么它应该执行相同的次数第二次循环测试。所以我不遵循你的推理。至于求和,要找到迭代次数,您需要加上以下内容:
所以你需要加起来:(n-1)+(n-2)+(n-3)+ ... + 1 = n(n-1)/ 2
new_index=j
)最多执行 n(n-1)/ 2次 - 我们不确切知道多少因为我们不知道是什么A
中的值是 - 所以我们不知道A[j] < A[i]
多少次。它可以执行零次(考虑数组排序时的情况)。但是,我们通过假设条件始终为真来找到上限。在这种最坏的情况下,if语句的主体执行与内部for循环相同的次数 - 从前一个项目符号点开始是n(n-1)/ 2 总的来说,该算法恰好执行具有Θ(1)工作的内部for循环迭代的n(n-1)/ 2次迭代 - 并且恰好n次迭代的if语句在Θ(1)时间内执行交换。这给出了时间复杂度Θ(n ^ 2)。