选择排序CLRS - 推理的正确性

时间:2016-03-24 12:01:10

标签: algorithm selection-sort big-theta clrs

我是一名自学成才的计算机科学专业的学生。 现在我正在阅读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.

在写这篇文章之前,我读了许多假设的解决方案,但没有人等于我的。所以我想知道我的推理是否错误。

我希望我能以良好的形式写下所有细节。

1 个答案:

答案 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条件总是为真),那么它应该执行相同的次数第二次循环测试。所以我不遵循你的推理。至于求和,要找到迭代次数,您需要加上以下内容:

  • j = 1:执行(n-1)次
  • j = 2:执行(n-2)次
  • j = 3:执行(n-3)次
  • ...
  • j = n:执行1次

所以你需要加起来:(n-1)+(n-2)+(n-3)+ ... + 1 = n(n-1)/ 2

解决方案

  1. 内部for循环执行完全 C(n,2)= n(n-1)/ 2次。该循环产生所有对(i,j),使得1 <= i <1。 j&lt; = n - 来自组合学的 n-choose-2 或C(n,2)。
  2. if语句体(new_index=j)最多执行 n(n-1)/ 2次 - 我们不确切知道多少因为我们不知道是什么A中的值是 - 所以我们不知道A[j] < A[i]多少次。它可以执行零次(考虑数组排序时的情况)。但是,我们通过假设条件始终为真来找到上限。在这种最坏的情况下,if语句的主体执行与内部for循环相同的次数 - 从前一个项目符号点开始是n(n-1)/ 2
  3. 通过类似的推理,另一个if语句体(执行交换的那个)最多执行 n次。
  4. 总的来说,该算法恰好执行具有Θ(1)工作的内部for循环迭代的n(n-1)/ 2次迭代 - 并且恰好n次迭代的if语句在Θ(1)时间内执行交换。这给出了时间复杂度Θ(n ^ 2)。