web-dev-qa-db-ja.com

なぜバブルソートO(n ^ 2)なのですか?

for (int front = 1; front < intArray.length; front++)
{
    for (int i = 0; i  < intArray.length - front; i++)
    {
        if (intArray[i] > intArray[i + 1])
        {
            int temp = intArray[i];
            intArray[i] = intArray[i + 1];
            intArray[i + 1] = temp;
        }
    }
}

内部ループは反復しています: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)でないのですか?

17
ordinary

外側のループがn回繰り返され、内側のループもn回繰り返されることは正しいですが、作業を二重にカウントしています。トップレベルのループの各反復で行われた作業を合計することによって行われた総作業を数えると、最初の反復がn回、2回目がn-1回、3回目がn-2と続きます。トップレベルのループの反復には、n - i仕事。

あるいは、内側のループによって実行された作業量に、そのループが実行された合計回数を掛けることによって、実行された作業を数えることができます。内側のループはO(n)反復ごとに機能し、外側のループはO(n)反復に対して実行されるため、合計の作業はO(ん2)。

これら2つの戦略を組み合わせようとすると、エラーが発生します。外側のループが最初にn、次にn-1、次にn-2のように機能することは事実です。ただし、合計を取得するためにこの作業にnを掛けることはありません。これにより、各反復がn回カウントされます。代わりに、それらを合計することができます。

お役に立てれば!

22
templatetypedef

あなたの内側のループは、あなたが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)

6
GL770

内部ループはn回繰り返されます(最悪の場合):

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

外側のループはn回繰り返されます。

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

したがって、O(n ^ 2)

1
NominSim

基本的にNを計算する方法...

  • 各行:+1
  • 各ループ* N

    したがって、最初のループに番号を追加し始めると、N + 1が得られ、続けていくと、最終的にN * NまたはN ^ 2が得られます。それは一般的にNと比較して取るに足りないので、その数を取り除く。

ほぼNは、1,2,3 ... Nのようなループ内のすべてのアイテムの表現です。したがって、それは単にループを繰り返す回数ではなく、単に数値を表しているだけです。

1
Travis Pessetto
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)
1
winuxguy

これは、変数swappedだけを使用して最初の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();
}
0
Giang Nguyễn