なぜmergesort O(log n)なのですか?


27

Mergesortは分割統治アルゴリズムであり、入力が繰り返し半分になるためO(log n)です。しかし、入力がループごとに半分になったとしても、各半分の配列でスワッピングを行うために各入力項目を反復処理する必要があるため、O(n)であってはなりませんか?これは、本質的に漸近的にはO(n)です。可能であれば、例を提供し、操作を正しくカウントする方法を説明してください!まだ何もコーディングしていませんが、オンラインでアルゴリズムを調べています。また、ウィキペディアがmergesortの動作を視覚的に示すために使用しているもののgifを添付しました。

ここに画像の説明を入力してください



18
神のソートアルゴリズム(各要素がどこに属しているかを伝えるオラクルにアクセスする仮想のソートアルゴリズム)でさえ、O(n)のランタイムがあります。
フィリップ

回答:


59

O(log(n))ではなく、O(n * log(n))です。正確に推測したとおり、入力全体を反復処理する必要があり、これはO(log(n))回発生する必要があります(入力を半分にできるのはO(log(n))回のみです)。n個のアイテムをlog(n)回反復すると、O(n log(n))が得られます。

比較ソートはこれよりも速く動作できないことが証明されています。基数ソートなど、入力の特別なプロパティに依存するソートのみが、この複雑さを克服できます。通常、マージソートの一定の要因はそれほど大きくありませんが、より複雑なアルゴリズムでは時間がかかりません。


3
s / faster /低複雑度/
jk。

33

マージソートの複雑さはO(nlogn)であり、O(logn)ではありません。

マージソートは、分割統治アルゴリズムです。3つのステップの観点から考えてください-

  1. 分割ステップは、各サブアレイの中点を計算します。この各ステップは、O(1)時間だけかかります。
  2. 征服ステップは、それぞれn / 2(偶数n)個の要素の2つのサブ配列を再帰的にソートします。
  3. マージ手順は、O(n)時間かかるn個の要素をマージします。

ここで、ステップ1と3、つまりO(1)とO(n)の間では、O(n)の方が高くなっています。ステップ1と3で合計O(n)時間かかると考えてみましょう。定数cがcnであるとします。

これらのステップは何回実行されますか?

これについては、下のツリーを見てください-上から下のレベルごとに、レベル2は、それぞれ長さn / 2の2つのサブ配列でmergeメソッドを呼び出します。ここでの複雑さは2 *(cn / 2)= cnです。レベル3は、それぞれ長さn / 4の4つのサブ配列でmergeメソッドを呼び出します。ここでの複雑さは4 *(cn / 4)= cnなどです...

現在、このツリーの高さは、指定されたnに対して(logn + 1)です。したがって、全体的な複雑さは(logn + 1)*(cn)です。これは、マージソートアルゴリズムのO(nlogn)です。

n要素のソートをマージ

画像クレジット:カーンアカデミー


9

マージソートは再帰的なアルゴリズムであり、時間の複雑さは次の再帰関係として表現できます。

T(n)= 2T(n / 2)+ɵ(n)

上記の再発は、Recurrence TreeメソッドまたはMasterメソッドのいずれかを使用して解決できます。マスターメソッドのケースIIに該当し、再発の解はɵ(n log n)です。

マージソートは常に2つの半分に配列を分割し、2つの半分をマージするのに線形時間を要するため、マージソートの時間の複雑さは3つすべての場合(最悪、平均、および最高)でɵ(nLogn)です。

入力配列を2つの半分に分割し、2つの半分に対して自分自身を呼び出し、ソートされた2つの半分をマージします。merg()関数は、2つの半分をマージするために使用されます。merge(arr、l、m、r)は、arr [l..m]とarr [m + 1..r]がソートされていると想定し、ソートされた2つのサブ配列を1つにマージする主要なプロセスです。詳細については、次のC実装を参照してください。

MergeSort(arr[], l,  r)
If r > l
     1. Find the middle point to divide the array into two halves:  
             middle m = (l+r)/2
     2. Call mergeSort for first half:   
             Call mergeSort(arr, l, m)
     3. Call mergeSort for second half:
             Call mergeSort(arr, m+1, r)
     4. Merge the two halves sorted in step 2 and 3:
             Call merge(arr, l, m, r)

ここに画像の説明を入力してください

ダイアグラムを詳しく見ると、サイズが1になるまで、配列が再帰的に2つの半分に分割されていることがわかります。サイズが1になると、マージプロセスが実行され、配列が完全になるまで配列のマージが開始されます合併しました。


1
マージ部分の性質と、それがO(n log n)パフォーマンスにどのように寄与するかについて詳しく説明してください。

マージ関数の複雑さはO(n)です。2つの配列を入力として受け取り、それらを比較してnewで出力するためです。各要素を配列内の他のすべての要素と比較しているため、このマージ関数の複雑さはO(n)になります。
ニシャントセティ

1
この種の視覚化が大好きです!
spaaarky21

0

比較ベースのソートアルゴリズムには下限が𝞨(n*log(n))あります。つまり、O(log(n))時間ベースの複雑さを備えた比較ベースのソートアルゴリズムを使用することはできません。

ところで、マージソートはO(n*log(n))です。このように考えてください。

[ a1,a2,         a3,a4,         a5,a6,          a7,a8     .... an-3,an-2,     an-1, an ] 
   \ /            \  /           \ /             \  /            \  /            \  /    
    a1'            a3'            a5'             a7'            an-3'           an-1'    
      \            /                \             /                 \             /
            a1''                          a5''                       an-3''
             \                             /                         /
                          a1'''                                     /
                           \
                                              a1''''

これは逆のバイナリツリーに見えます。

入力サイズをとしますn

それぞれa_nが要素のリストを表します。最初の行のa_n要素は1つだけです。

各レベルでの平均マージコストの合計はn(コストが低いコーナーケースが存在します[1])。そして、木の高さはlog_2(n)です。

したがって、マージソートの時間の複雑さはO(n*log_2(n))です。

[1]すでに並べ替えられているリストで並べ替える場合、これが最良の場合と呼ばれます。コストはに減少しましたn/2 + n/4 + n/8 + .... + 1 = 2^log_2(n) -1 ~ O(n)。(長さnは2の累乗であると仮定します)


-2

ソートは、コンピューターサイエンスにおけるNP完全な問題です(非多項式問題)。つまり、数学的に証明されていない限り、要素のリストを並べ替えるときにO(n log n)を下回ることはできません。

ウィキペディアでこの記事を確認してください(https://en.wikipedia.org/wiki/P_versus_NP_problem

基本的にこれまで誰もそれを証明することができませんでした(P == NP)、もしあなたが最初に億万長者になり、次に第二次世界大戦IIIを開始します。最近どこでも:)


2
それはNPが意味するものではありません。BubbleSortでもPに含まれています。Pに含まれないソートを作成するために一生懸命努力する必要があります(例:BogoSort)
Caleth
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.