为什么冒泡排序O(n ^ 2)?

时间:2012-07-13 20:16:27

标签: algorithm sorting complexity-theory big-o bubble-sort

int currentMinIndex = 0;

for (int front = 0; front < intArray.length; front++)
{
    currentMinIndex = front;

    for (int i = front; i < intArray.length; i++)
    {
        if (intArray[i] < intArray[currentMinIndex])
        {
            currentMinIndex = i;
        }
    }

    int tmp = intArray[front];
    intArray[front] = intArray[currentMinIndex];
    intArray[currentMinIndex] = tmp;
}

内循环迭代:n +(n-1)+(n-2)+(n-3)+ ... + 1次。

外循环迭代:n次。

所以你得到n *(数字1到n的总和)

不是n *(n *(n + 1)/ 2)= n *((n ^ 2)+ n / 2)

哪个是(n ^ 3)+(n ^ 2)/ 2 = O(n ^ 3)?

我很肯定我做错了。为什么不是O(n ^ 3)?

7 个答案:

答案 0 :(得分:22)

你是正确的,外循环迭代n次,内循环迭代n次,但你重复计算工作。如果通过对顶层循环的每次迭代中完成的工作求和来计算总工作量,那么第一次迭代就可以工作,第二次是n - 1,第三次是n - 2,等等,因为第i次迭代顶级循环的迭代使内循环正在进行n - i工作。

或者,您可以通过将内循环完成的工作量乘以循环运行的总次数来计算完成的工作量。内循环在每次迭代时执行O(n)工作,外循环运行O(n)次迭代,因此总工作为O(n 2 )。

您尝试将这两种策略结合起来会出错。确实,外循环第一次运行,然后是n - 1,然后是n - 2,等等。但是,你不要将这个工作乘以n来得到总数。这将计算每次迭代n次。相反,你可以将它们加在一起。

希望这有帮助!

答案 1 :(得分:6)

你的内循环正在迭代,正如你所说的n +(n-1)+(n-2)+(n-3)+ ... + 1次。所以它是O(n +(n-1)+(n-2)+(n-3)+ ... + 1)= O(n(n + 1)/ 2)= O(n ^ 2)

答案 2 :(得分:1)

内循环迭代n次(在最坏的情况下):

for(int i = front; i < intArray.length; i++)

外部循环迭代n次:

for(int front = 0; front < intArray.length; front++)

因此O(n ^ 2)

答案 3 :(得分:1)

你基本上如何计算N ...

  • 每一行:+1
  • 每个循环* N

    所以你开始添加数字到你的第一个循环现在你有N + 1,你继续前进,你最终得到N * N或N ^ 2的时间加上一些数字。与N相比,拉出数字通常是微不足道的。

几乎N是循环中所有项目的表示,如1,2,3 ... N.所以它只是表示一个数字而不是循环的次数,循环。

答案 4 :(得分:1)

k=1(sigma k)n = n(n+1)/2
because:
  s = 1 +  2    + ... + (n-1) + n
  s = n + (n-1) + ... + 2     + 1
+)
===================================
  2s = n*(n+1)
   s = n(n+1)/2
in bubble sort, 
(n-1) + (n-2) + ... + 1 + 0 times compares 
which means, k=0(sigma k)n-1
, k=0(sigma k)n-1 equals [k=1(sigma k)n] - n
therefore, n(n+1)/2 - n = n(n-1)/2
which is 1/2(n^2-n) => O(1/2(n^2-n))
in big O notation, we remove constant, so
O(n^2-n)
n^2 is larger than n
O(n^2)

答案 5 :(得分:0)

这是另一个加快气泡排序的版本,当我们仅使用变量交换来尽早终止第一个for循环时。您可以获得更好的时间复杂度。

#include <stdio.h>
#include <stdbool.h>
#define MAX 10

int list[MAX] = {1,8,4,6,0,3,5,2,7,9};

void display(){
   int i;
   printf("[");

   for(i = 0; i < MAX; i++){
      printf("%d ",list[i]);
   }

   printf("]\n");
}

void bubbleSort() {
   int temp;
   int i,j;

   bool swapped = false;       

   // 1st loop
   for(i = 0; i < MAX-1; i++) { 
      swapped = false;

      // 2nd loop
      for(j = 0; j < MAX-1-i; j++) {
         printf("     Compare: [ %d, %d ] ", list[j],list[j+1]);

         if(list[j] > list[j+1]) {
            temp = list[j];
            list[j] = list[j+1];
            list[j+1] = temp;

            swapped = true;
         }

      }

      if(!swapped) {
         break;
      }

      printf("Loop number %d#: ",(i+1)); 
      display();                     
   }

}

main(){
   printf("Before: ");
   display();
   printf("\n");

   bubbleSort();
   printf("\nAfter: ");
   display();
}

答案 6 :(得分:-1)

只是为了有一些Python版本的冒泡排序...

def bubble_sort(input):
    n = len(input)
    iterations = 0
    for i in xrange(n, 1, -1):
        for j in range(0, i - 1):
            iterations += 1
            if input[j] > input[j+1]:
                input[j],input[j+1] = input[j+1],input[j]

    print iterations
    return input

迭代被添加到内部循环中以计算总迭代次数。与冒泡排序无关。

传递5个元素的数组,导致15次迭代而不是25.此外,当预先排序时,它也会导致15次迭代。但复杂性还必须考虑到比较和交换。