
ハノイの塔
怠zyな人だけが 、有名なハブレのエデュアルドリュックのゲームについて書いていない 。 すべてのカバーが引きちぎられており、アルゴリズムについて他に何かを追加することはできなくなっているようです。 しかし、このトピックにはリソースが隠されています。 特に今日は、このパズルを完全に並べ替えるためのアルゴリズムを作り直します。 (なぜ?ただの楽しみのため。金曜日は可能です。)
この投稿は、プログラミングの第一人者であるAndrei Mrrl Astrelinの記憶に捧げられています。AndreiMrrl Astrelinは、かつてこのアルゴリズムを簡単かつわかりやすく説明してくれました。 以下の擬似コードは、彼の著者のテキストです。

古典的なパズルでは、最初のポールのディスクが最初に注文されます。 しかし、私たちはそれらがどんな順序でつながれることを許します。
さらに、ディスクサイズは一意であると想定されます。 この制限に固執せず、繰り返しは許可しません。
これら2つの自由のみを許可すると、パズルの初期条件は配列(ディスクは数字)として解釈され、タスクはこの配列をソートする必要があるという事実に要約されます。
私たちが(ほとんど)変更しない残りの条件:
- 2つの補助極(空の配列のペア)があります。
- ディスクは一度に1つずつ転送できます。
- 小さいものだけを大きいものに置きます(同じディスクサイズを許可しているため、移動したディスクを同じサイズの他のディスクの上に置くこともできます)。
- ポータブルディスクと最上位のディスクのみを比較する権利があります(つまり、3つのアレイはすべてスタックです)。
私たちのタスク:古典的な再帰パズルアルゴリズムを使用する...
def hanoi(n, source, helper, target): if n > 0: hanoi(n - 1, source, target, helper) if source: target.append(source.pop()) hanoi(n - 1, helper, source, target)
...そしてソートに変換します!
実際、最初の無秩序とディスクのサイズの繰り返しを許可したという事実から、これから根本的に何も変わっていません。 概して、問題は同じ古典的な再帰的な方法で解決できます。 理解する最も重要なことは、すべてのディスクの動きがいくつかの段階に分割されていることです。各段階は古典的なミニチュアハノイです。
つまり、各段階で、使用可能なすべてのディスクではなく、古い条件を満たすディスクの全体のみを考慮します。 この小さなセットをクラシックでソートしたので、システムの一般的な状態をクラシックパズルに近づけます。 次に、古典に対応するディスクのセットを再度取得し、よく知られたアルゴリズムを再度適用します。 そして、このセットは前のステップよりも大きくなります! そして、すべての極のすべての円盤が突然古典的な状態と異なるようになるまで繰り返します。
(入力時にディスクが順序付けられていないという事実により)最初に違反したシステムは、各反復で自己修復します。
繰り返しの解決に関しては、これはまったく問題ではありません。 連続する同一のディスクのため、単純に1つのディスクとして移動します。
アルゴリズム
列をA 、 B 、 Cと呼びます(先頭のAは空ではありません)。
操作を紹介します。
A- > C ()-1つのディスクをAからCにシフトします。
top(A) 、 top(C) -上部ディスクAまたはCのサイズ 列が空の場合、このサイズはMaxIntです。
B- > C ( K )-サイズがKより小さいすべてのディスクをBからCにシフトします(上部のディスクAとCが Kより小さくない場合、これを行うことができます)。
swap ()-列BとCを再配置します(または名前を変更します-ドライブの場所は気にしません)。
while ( A ) -Aが空になるまでループします。
その後、次のアルゴリズムが機能します。
// A "" while(A) { K = top(A); //-"" while(top(C) < K){ B->C(top(C)); swap(); } A->C(); } // . - "" while(C) { B->C(top(C)); swap(); }
© Mrrl
難易度
最悪の場合、ソートは古典的なアルゴリズムの時間を複雑にする傾向がありますが、単純でエレガントではありますが、同時に非効率的です。 最高と平均については、想像できません。
メモリに関しては、再帰が使用される場合、コストは対応するものになると言えます。
実装
Pythonで独自のバージョンを作成していません(後で作成します)。 ただし、以下の「リンク」セクションでは、さまざまな言語での実装を確認できるリンクをいくつか掲載しました。 Javaで特に興味深いオプション。 著者は、パズルを解くためのよく知られた再帰的手法を基礎としてはおらず、最短のパスツリーを構築しました。 おそらく、「ハノイの塔」のスタイルで並べ替えを記述する場合、これが最も効果的なソリューションです。
アルゴリズムの特徴
役職 | ハノイの塔ソート | |
---|---|---|
アイデアの著者 | エドワード・リュック | |
クラス | 挿入ソート | |
比較 | あります | |
時間の複雑さ | 最高 | ? |
平均的 | ? | |
最悪の | O( 2 n ) |
参照資料

実装: C 、 Java vs C ++ vs Python 、 Python 。
シリーズ記事:
AlgoLabアプリケーションでは、このソートが利用可能になりました。 挿入によるソートのクラスに属しますが、アルゴリズムの贅沢さのため、「その他のソート」セクションに配置されます。 また、制限もあります-ソートされた配列の数値は1〜5のみです(ディスクのレンダリングが難しいため)。 他の番号はこれらに置き換えられます。
配列のサイズにも制限があります-20以下の要素。 これは純粋にあなた自身の利益のために行われました-大きすぎる配列をとると、非常に古い年齢に並べ替えなければならないことがあります。
![]()
この記事は、 スマートシティライティングを専門的に開発 し、Pythonサイトを管理しているEDISON Softwareの支援を受けて作成されました。