私はすべての説明を読みます ここ ですが、まだ確信がありません。私はmergesortはn * nだと思います、そして私は私が間違っていることを知っていますが、どこにいるかはわかりません。これが私が思うことです:
8つの要素をソートしていて、これがアルゴリズムであると仮定します(私が正しい考えを持っていると仮定します)。
doSort(int begin, int end, int[] arr) {
if(end != begin) {
int mid = begin + (end - begin)/2;
doSort(begin,mid);
doSort(mid + 1, end);
merge(arr, begin, mid, mid + 1, end);
}
}
merge(int[] arr,int i_begin, i_end, j_begin, j_end) {
// Do the comparison and all that
}
今私の理解によると、merge()自体は複雑なO(n)を持っています。今度はdoSort()が何回呼び出され、それゆえにmerge()が呼び出されたかを見てみましょう。 doSort()は、次のインデックスに対して呼び出されます。
これは7回ですO(n)とすると、8つの要素を並べ替えます。同様に、16要素の場合、merge()は15回呼び出されます。したがって、配列をそれぞれ半分に分割しますが時間、私たちは決して他の半分を排除していません。これを、各ステップでツリーの半分を排除するBST検索と比較してください。 )そして、マージソートの場合、マージをn-1回呼び出し、マージがo(n)演算を必要とするたびに、O(n * n)を呼び出します。
どこが間違っているのですか?任意の提案をいただければ幸いです。
並べ替えは1,024個の数値を言い、2つの512要素配列の1つのマージを実行します。 2つの256要素配列の2つのマージ、2つの128要素配列の4つのマージ、8つのtims 64要素、...、2つの1要素配列の512マージを実行します。
単一の最大マージの時間(1 x 512要素)とマージの総数(1,023マージ)を確認したところ、半分のマージが1つの要素配列であり、残りのマージの半分がちょうどであることに気づかなかった2要素配列など。マージの各セットはn = 1024ステップ(1024エレメントの結果で1マージ、512エレメントの結果で2マージ、...、2エレメントの結果で512マージ)をとり、log2(n)= 10セットのマージがあります。合計10 x 1024または(n log2 n)ステップ。
マージソートの複雑さはO(nlogn)であり、O(n * n)ではありません。
マージソートは、分割統治アルゴリズムです。 3つのステップで考えてみてください。
除算ステップは、各サブ配列の中点を計算します。この各ステップは単にO(1)の時間を要します。征服ステップは、n/2(偶数)エレメントの2つのサブ配列をそれぞれ再帰的にソートします。マージステップは、O(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つのサブ配列に対してマージメソッドを呼び出します。ここでの複雑さは4 *(cn/4)= cnなどです...
現在、この木の高さは、指定されたnに対して(logn + 1)です。したがって、全体的な複雑さは(logn + 1)*(cn)です。これは、マージソートアルゴリズムのO(nlogn)です。