2^m-1
まず、一般性を失うことなく、バイナリツリーに要素1、2、3、...があると仮定できることに注意してください。したがって、これからは、これらの番号があると想定します。
1 2 3 4 5
次に、私の試みは、ソートされた配列(つまり)をソートされた二分木を表す配列に変換する関数です。
要素を持つソートされた二分木で(2^m)-1
は、ツリーの「下部」がすべての不均一な数で構成されていることが常にありますm=3
。
4
2 6
1 3 5 7
これは、対応する配列で、最後の数がすべて不均等な数であることを意味します。
4 2 6 1 3 5 7
-------
^
uneven numbers!
2^(m-1)
したがって、対応する配列の最後の数がすべて不均等な数であることを確認することにより、二分木の最後の「行」を構築できます。したがって、最後の行に対して行う必要があるのは、インデックスが不均一な位置にあるすべての要素を最後の行に移動する関数を作成することだけです。
それで、今のところ、入力としてソートされた配列が与えられた場合に、最後の行を正しく確立するルーチンがあると仮定しましょう。
次に、配列全体のルーチンを呼び出して、他のすべての要素を並べ替えたまま、最後の行を作成できます。このルーチンを配列に適用する1 2 3 4 5 6 7
と、次のような状況になります。
2 4 6 1 3 5 7
-------
^
correct!
最初のラウンドの後、2 4 6
残りの要素を変更せずに、バイナリツリーの最後から2番目の「行」を構成する残りのサブ配列(つまり)にルーチンを適用すると、次のようになります。
now correct as well!
v
---
4 2 6 1 3 5 7
-------
^
correct from run before
したがって、私たちがしなければならないのは、最後の行(つまり配列の後半)を正しくインストールする関数を作成することだけです!
これは、が配列の入力サイズであるO(n log n)
場合に実行できます。n
したがって、配列を最後から最初までトラバースし、最後の行(つまり配列の後半)が正しくなるように不均一な位置を交換します。これはインプレースで行うことができます。その後、配列の前半をソートします(ヒープソートなどを使用)。したがって、このサブルーチンの実行時間全体はO(n log n)
です。
n
したがって、合計サイズの配列の実行時間は次のようになります。
O(n log n) + O(n/2 log n/2) + O(n/4 log n/4) + ...
これはと同じO(n log n)
です。このすべてが完全にインプレースで機能するように、ヒープソートなどのインプレースソートアルゴリズムを使用する必要があることに注意してください。
これ以上詳しく説明できず申し訳ありませんが、ご理解いただけると思います。