• ベストアンサー

ハノイの塔

ハノイの塔の解き方がわかりません。解き方と理解のコツなどを教えてください。

質問者が選んだベストアンサー

  • ベストアンサー
noname#113783
noname#113783
回答No.3

ハノイとハノイの再帰プログラムの解き方(わかりやすい)です。まずソースコード。 #include<stdio.h> void Hanoi(int n,char *from,char *work,char *dest) { if(n>=2) Hanoi(n-1,from,dest,work); printf("%d を %s から %s へ\n",n,from,dest); if(n>=2) Hanoi(n-1,work,from,dest); } void main(void) { Hanoi(4,"A","B","C"); } ↑これ実行してみてください。では説明しますね。 まずハノイの塔のとき方。ルールは知ってますね?棒A,B,Cがあるとして、Aにある4つの輪をCに移すとします。輪は小さい順に1,2,3,4という名前を付けます。輪全てをCに移すには、4をCに移せないといけません。そうするためには、4の上に輪がなく、Cの上にも何も詰まれていない状態でないといけません。つまり、4以外の輪(1,2,3)がBに乗っていないといけません。なので、”なんとかして”、輪1,2,3をBに移します。輪1,2,3をBに移すには、輪3を棒A(4をCに移したので空っぽ)に移さなくてはいけません。その為には”なんとかして”輪1,2を棒Aに移します。・・・ループしていますね。そして、1回目はAにある輪の1番下以外をBに移しましたが、次はBに置かれた輪の1番下以外をAに移しています。Aに置かれている輪をBに移したいときと、Bに置かれている輪をAに移したいときは、交互に来ます(何故なんて考えないでください)。では、いつCに移すのか?それは後で説明します。 ここからソースの説明です。関数Hanoiの引数は、 int n   =移したい輪の本数 char *from =移したい輪が乗っている棒の名前 char *work =輪を移すために、一番下の輪以外の輪を1時的に置いとく輪 char *dest =最終的に輪を移したい棒 です。関数Hanoiは、指定した本数の輪を指定した棒に全て移してくれる関数なのです。これをmain関数から呼び出せば、移したい輪が移したい棒移ってくれます。ソースの説明です。 Hanoi(n-1,from,dest,work);  ifの部分は後回しです。関数Hanoiは輪いくつかを棒へ移したいけど、一番下の輪が移したい棒に行くためには、その上の輪をworkに移さないといけません。なので、A(from)にある1番下以外の棒(上からn-1本の輪)、をB(work)に移したいので、A(from)をfromとして送り出し、B(work)をdectとして送り出します。これで、↑のHanoi関数が帰ってきた暁にはAにある1番下の棒をCに移せます。そのソースが、 printf("%d を %s から %s へ\n",n,from,dest);  これ。これで1番下の棒が置かれていたfromからdectに移せました。nには移したい輪の最大本数が入っています。1番下の輪のナンバー=輪の最大本数=n。さっきのHanoi関数が1番下以外の輪を移してくれるなら、このprintfは1番下の輪を移してくれるのです。では次。 Hanoi(n-1,work,from,dest);  さっきのHanoi関数で一番下以外の棒がfromからworkに移っているので、今度はworkをfromにして、空いたfromをworkにして移します。 これを繰り返せばハノイの塔攻略完了です。あとはif文ですね。 if(n>=2) 2以下の場合は実行するな、と。もし1だった場合実行してまうと、「n(1)-1」本の棒を移せ、といっていることになってしまいます。Hanoi関数はprintfで1番下に置いてある輪を移すので、残り本数1になったらprintfがdestに1を乗せてくれます。なのでifを実行してはいけません。 これで説明は終わりです。ソースコードはリンクに書いてあるものを使いました。そのサイトも分かりやすく説明してくれます。図にするなら下のような感じです。 http://mb1.net4u.org/bbs/mi-koxxx/img/3.jpg 読んでくださってありがとうございました。

参考URL:
http://www13.plala.or.jp/kymats/study/C++/Hanoi/Hanoi.html

その他の回答 (4)

noname#113783
noname#113783
回答No.5

#3です。たびたび失礼いたします。 画像のリンクを張ったつもりでしたが、直リンクにしたら失敗してしまいました。画像は↓です。 http://mb1.net4u.org/bbs/mi-koxxx/image/3jpg.html 縮んでるみたいな画像になっていますが、それは元々です。

noname#113783
noname#113783
回答No.4

さっきのハノイの説明で、一番最初のハノイのとき方のときに、一番した以外を移した後に、一番下の輪をCに移すのを忘れていました。よかったら付け加えながら読んでみてください。

  • tadys
  • ベストアンサー率40% (856/2135)
回答No.2

ハノイの塔には再起を使わない解き方もあります。 1.一番小さい札を順に一つ移動する。 2.一番小さい札でないものを一つ移動する。   (どれが移動できるかは自動的に決まる。) 3.1、2を移動が完成するまで繰り返す。

  • php504
  • ベストアンサー率42% (926/2160)
回答No.1

Cの再帰プログラムの例としてネット上にいっぱい情報があります 「ハノイの塔 C言語」で検索をしてはどうでしょう Googleで検索した上3つをリンクしておきます http://www13.plala.or.jp/kymats/study/C++/Hanoi/Hanoi.html http://w3-denki.maizuru-ct.ac.jp/siryou/text/jyoho3/kouki1/hanoi/frame.htm http://www.u-gakugei.ac.jp/~miyadera/LECTURE/ElecBook2/ptech06.htm

関連するQ&A