より大きいか、またはマージソートに本当に必要なすべては、< =と1のために0です。
また、paまたはpbを実行するときにリストが空であることを示す戻り値もありません。ソースリストが空でなければpaまたはpbを定義し、ソースリストが空の場合(コピーするノードがない場合)は0を返します。
目標が最小の命令であるかどうかは、ソースコード内の命令の数またはソート中に実行された命令の数を参照してください。
-
コード内の最小の命令数は、正しい位置にlist2にノードを挿入するためにlist1との比較に基づいてlist2をローテーションします。 pbで始まり、list2サイズを1に設定します。次にrbまたはrrbを実行して、list2を次のpbを実行する場所に回転します。このコードは、リスト2を回転させる際の無限ループを避けるために、リスト2の「オフセット」を最小のノードまで追跡します。複雑さはO(n^2)です。
-
私は最速の並べ替えを考えていると、おそらく実行される命令の最小数は、ボトムアップマージソートです。
循環バッファ/リストのようにリストを回転しながらボトムアップマージソートを行います。シーケンスを使用してノードの数を生成するlist1をlist2にコピー|カウント= 0 | while(pb){rb |カウント+ = 1}。
カウントを使用して、{pa、rr}、n/2回を使用して、list2からlist1まですべての他のノードを移動します。リストの論理終わりにいつ到達するかを知るためには、各リスト上のノードの実際の数を常に追跡してください。また、各リストのランカウンターを追跡して、ランの論理終点に達したときを知ることができます。この時点で、偶数ノードがlist1上にあり、奇数ノードがlist2上にある2つのリストがあります。
実行サイズは1から始まり、各パスで倍増します。実行サイズが1の最初のパスでは、奇数ノードでも偶数ノードをマージし、サイズが2のソート済みランを作成し、ソートされたノードのペアをlist1とlist2に追加します。たとえば、list1に追加し、list1ノード< = list2ノードを使用する場合は{ra、run1count - = 1}、それ以外の場合は{pa、ra、run2count - = 1}を使用します。実行の終了に達すると、残りの実行の残りをリストの末尾に追加します。次のパスでは、リストから2ノードのソートされた実行をマージし、ソートされた4ノードの実行を各リストに交互に追加します。すべてのノードが1つのリストに終わるまで、8、16、...の実行を続けます。
だからそれだノードをカウントする1つのパス、偶数と奇数のノードを分割する一つのパス、およびはceil(LOG2(N))はマージソートを行うに渡します。リンクされたリスト操作のオーバーヘッドは小さい(回転を取り除いてノードを追加する)ので、全体的なマージはかなり速くなければなりません。
カウントパス上の命令の数が、一方(PB)で還元することができる逆LIST2するLIST1コピーであろう、{= 1 +カウント}。 list2をlist1に吐き出すと、rrrを使ってそれらを逆転させます。
複雑さはO(n log(n))です。
これらの操作では、効率的なマージソートを行うことができます。 –
リスト1の半分をリスト2に入れ、両方のリストを同時にソートしてマージする必要がありますか? – Henry
私は何らかのクイックソートやマージソートが行く方法だと思います。しかし、使用されていないノードを格納することはややこしいでしょう。 –