时间复杂度类似于冒泡排序

时间:2013-10-08 04:14:42

标签: algorithm sorting time-complexity

分析以下排序算法:

      for (int i = 0; i < SIZE; i++)
      {
        if (list[i] > list[i + 1])
       {
           swap list[i] with list[i + 1];
           i = 0;
       }
     }

我想确定时间复杂度,在更糟糕的情况下...我不明白它是如何O(n ^ 3)

3 个答案:

答案 0 :(得分:1)

好的..这里...... 在最坏的情况下,我们可以说我们有一个完全翻转的阵列..

9 8 7 6 5 4 3 2 1 0

每次交换时,我都会重置为0.

让我们开始翻转9 8:我们现在有8 9 7 6 5 4 3 2 1 0并且i被设置回零。

现在循环运行到2并且我们再次翻转..:8 7 9 6 5 4 3 2 1 0我再次重置..但是为了得到7到第一个位置我们有另一个翻转为8和7。 :7 8 9 6 5 4 3 2 1 0

所以循环次数如下:

T(1)= O(1) T(2)= O(1 + 2) T(3)= O(1 + 2 + 3) T(4)= O(1 + 2 + 3 + 4)等等..

最后对于第n个项,在这种情况下最大的是T(n)= O(n(n-1)/ 2)。

但是对于整个事情,你需要总结所有这些条款 其中可以用(T(n))=((n ^ 2)的求和)=(n ^ 3)

的总和来定义

<强>加成 可以这样想:对于每个元素,你需要去它并把它带回来..但当你把它带回来时它只是一个空间。我希望这更清楚一点。

另一个编辑 如果上述任何一点没有意义。可以这样想:你必须将0带到数组的前面。你最初走到零9步并把它放在1之前。但之后你被神奇地运送(i = 0)到数组的开头。所以现在你必须走8步到零,然后把它放在两个位置。扎普!你回到了数组的开始。你必须采取多少步骤才能使每次达到零,以便它在正面。 9 + 8 + 7 + 6 + 5 + ..这是重复的最后一个项,因此受阵列长度的平方限制。这有意义吗?现在为平均每个元素执行此操作,你正在做O(n)工作..对吗?这意味着将所有条款相加起来..而且我们有O(n ^ 3)。

如果事情有帮助或没有意义,请评论。

答案 1 :(得分:1)

显然,for循环本身就是O(n)。问题是,它可以运行多少次?

每次进行交换时,循环都会重新开始。你会做多少次交换?您将从每个元素的起始位置开始交换,直到它到达排序输出中的正确位置。对于反向排序的输入,将平均为n / 2次,或再次为O(n)。但这是每个元素,给另一个O(n)。这就是你如何到达O(n ^ 3)。

答案 2 :(得分:1)

我对n = 10和n = 100进行了分析。比较的数量似乎是O(n 3 )这是有道理的,因为我将n设置为0的平均值所以它在你的for循环的n 2 *(n / 2)比较和递增操作的某处,但是交换的数量似乎只有O(n 2 )因为显然不再需要交换来整理整个列表。最好的情况仍然是n-1比较和0交换。

对于最佳情况测试,我使用已排序的n个元素数组:[0 ... n-1]。

对于最坏情况测试,我使用n个元素的反向排序数组:[n-1 ... 0]

def analyzeSlowSort(A):
    comparison_count = swap_count = i = 0
    while i < len(A) - 1:
        comparison_count += 1
        if A[i] > A[i+1]:
            A[i], A[i+1] = A[i+1], A[i]
            swap_count += 1
            i = 0
        i += 1
    return comparison_count, swap_count

n = 10
# Best case
print analyzeSlowSort(range(n)) # ->(9, 0)
# Worst case
print analyzeSlowSort(range(n, 0, -1)) # ->(129, 37)
n = 100
# Best case
print analyzeSlowSort(range(n)) # ->(99, 0)
# Worst case
print analyzeSlowSort(range(n, 0, -1)) # ->(161799, 4852)

显然,就比较而言,这是一种非常低效的排序算法。 :)