再帰は理解 - ハノイ問題の塔

ハノイの問題の塔

ハノイの問題解決の塔は、再帰の巧妙な使用を考えることができます。

次の抜粋はほとんど私の見解は非常に明確な答えに手の込んだ知っています:

この問題を解決するためのプログラムを使用し、我々は最初の移動関数を定義:移動(携帯電話番号、カラム、トランジットカラム、ゴールポストを開始する)は、
例えば、移動(2、A、B、 C)は、 Aピラーから二つの皿を表します( CピラーとBピラー(ピラートランジット)(ターゲット列)によって)カラムを開始します。
コラム、これらの3つの概念の転送列の先頭について、列は理解して状態の間にターゲットを移動するために使用することができ、

理解することができるはず図の下を参照してください:
列の三つの状態、列の先頭に、中央の列がありますが、ライブ開始目標列が意味すべての料理列の状態の先頭に配置され、列転送が意味することは、一時的に中間状態nを格納することですプレートカラム(3は3-1である)-1、
ターゲット列は最後の列に移動するプレートを指します。カラム、トランジット列を開始すると、ターゲット列は静的ではなく、さまざまなレベルに応じて変化するであろうことに留意すべきです。(一時的に言葉を理解することができないがある場合は最初に読んで、あなたは理解して戻ることができるようになります)。

その後、我々は、皿を移動するには、状況のポイントについて説明します。

I.

場合だけ一方のプレートのみ時間のプレート(移動(1、A、B、C)を呼び出します)、

  • 限りプレートは、ターゲット、および中間の状態であることができるカラムの列の先頭から直接移動するように(すなわち、カラムを介して通過せずに)、プロセスは、ワードプリントによって表される移動動作を移動させることができる(「A ---> C」) ;

シナリオ2

この場合、3つのステップを(移動(2、A、B、C)を呼び出す)は、2枚のプレートが存在する場合

  • STEP1。最大プレートに加え、プレートをBAから移動さ---> B(カラムスタート--->トランジット列)に移動(1、A、C、B)を呼び出すのと同じ]
  • STEP2。最大プレートは---> C(カラムスタート--->ターゲット列)[(1、A、B、C)の移動を呼び出すのと同じ] CAから移動されます
  • STEP3。CB ---> C(トランジット列--->ターゲットカラム)を移動しBから皿の最大プレートに加えて、[(1、B、A、C)の移動を呼び出すのと同じ]私は多くのため希望どちらの場合は、我々は何の疑いもすべきではない、確かです。

その後、我々は3例を見て

三つの例

三つのプレート((3、A、B、C)を移動するために呼び出す)同じ三つのステップケースが存在する場合

  • STEP1。上の2つのプレートが完了するようにプレートをB(から移動される最大プレートに加えて、対象とBピラー、このステップは、トランジットピラーの列A、Cの開始であるため、この時点でそれを注意---> Bタスク)A ---> C(カラムは--->トランジット列を開始)A ---> B(開始カラム[移動(1、B、C)を呼び出すのと同じ]から移動(1、C、Aを呼び出すことに相当)C ---> B(カラム通過--->ターゲット列[移動(1、A、C、B)を呼び出すのと同じ] --->ターゲット列)、 B)]
  • STEP2。最大プレートがA-(このステップは---> C最大板Aから順に、ターゲット用のCピラー、トランジットピラーの列A、Bの開始であるため、現時点では)Cから移動し - > C(カラム開始--->ターゲット列)に移動(1、A、B、C)、即ち、直接実行プリント( 'A ---> C')を呼び出すのと同じ]
  • STEP3。最大トレイプレートに加えは、STEP2の列の転送を完了するように、トランジットピラー用のA、この工程のこの時点で、列Bの開始であることを目標のためのCピラーを注意BからC(に移動しましたBの二つのプレート--->タスクC)B --->(カラム開始--->トランジットカラム)[移動する(呼び出すのと同じ1、B、C、A)、B] --->動きを呼び出すのと同じC(カラム開始--->ターゲット列)[同等移動を呼び出す(1、B、A、C)] A ---> C(カラム通過--->ターゲット列)[(1、 、B、C)]

三つは、状況が理解し、突然そう簡単ではないかもしれませんが、我々は例の形式と3つのSTEP1のSTEP3、今のような全体の全体状況の二つの形式を見つけることができるはず記述しますか?そして、分析のレベルは、カラム、トランジットコラムを始め、同じではありません注意することは、列は同じ目標ではありません。

トランジットがCであるためSTEP1列に、トランジットSTEP3の列は、3列のケース全体が通過B.ためのものです

我々は以前に二つの機能が移動呼び出される場合を決定した(2、A、B、 C)、 ---> B A ---> CB Aと同等である ---> C 三段階三の偶発STEP1である---> CのA ---> B C ---> B 上記変換状況IIに従って、同一の二つの形態の場合と3つのステップを、、、及びこの関数は3つのステップに変換することができること移動(2、C、 B) 3つのSTEP3同様の場合、それは変換関数動きになるだろう(2、B、 C)
と、ここで、ダイレクトプリント(「で三のSTEP2 ---> C「)の代わりに移動(1、A、B、 C) 全体の3例がそのように表現することができるように。

  1. 移動(2、A、C、B)// STEP1。
  2. 最大プレートに加え、プレートBprint( 'A ---> C')// STEP2から移動されます。
  3. 最大移動Cmove(2、B、A、C)// STEP3からプレート。
  4. プレートの最大板がB及びCから移動されることに加えて、我々は、状況は3つの呼び出しの関数である知っている、(3、A、B、C)を移動

したがって、上記の3つの行は機能が実際に移動すると等価である(3、A、B、C)。

ここで手がかりを見つけることができる必要があり、4(4層)関数呼び出しの場合は、移動(4、A、B、C)であり、

  1. これはその移動(3、A、C、B)// STEP1擬似コードを示します。
  2. 最大プレートに加え、プレートBprint( 'A ---> C')// STEP2から移動されます。
  3. 最大移動Cmove(3、B、A、C)// STEP3からプレート。
  4. 最大プレートに加えて、BからCプレートに移動させ

ほとんど疑いはこのパートナーシップは、すべてのステップの具体的なステップ4あなた自身の状況を記述して、変換を行うことができ、限られたスペースはもはやここに記載されているがありません。

結論

実際には、それがあると結論することができる:N(N> 1)HANOR機能の動きを呼び出す層のための(N、Aは、B、C)が再帰的にこの問題を解決するため、この機能が実行されます

  1. ムーブ(N-1、A、C、B)// STEP1。

  2. 最大プレートに加え、プレートBprint( 'A ---> C')// STEP2から移動されます。

  3. 最大移動Cmove(N-1、B、A、C)// STEP3からプレート。

  4. 最大プレートに加えて、BからCプレートに移動させ

コード

上記を理解した上で、その後の後、我々は、Python実装の問題を解決するためにコードを書いてみることができます。

def move(n,A,B,C):
    if n==1:             # 1个盘子,直接打印出移动动作
        print(A,'--->',C)
    else:                # n > 1时,用抽象出的3步来移动
        move(n-1,A,C,B) #step1.  把除了最大的盘子之外的盘子从A移到B
        print(A,'--->',C)  #step2.  把最大的盘子从A移到C
        move(n-1,B,A,C)#step3.  把除了最大的盘子之外的盘子从B移到C

そう、ここでは読み、私はほとんどの人が7788の中心部にあることを理解すべきであることを推測するベンチャー企業

ここでは、Javaコードの実装です

public class Hanoi {
    
    public static int move(int n,char A,char B,char C) {
        // 如果是移动过一个盘子
        if(n == 1) {
            System.out.println(A+"-->"+C);
            return 1;
        }else {
            // 一个以上的盘子
            int r1 = move(n-1,A,C,B);
            System.out.println(A+"-->"+C);
            int r2 = move(n-1,B,A,C);
            return r1+r2+1;
        }
    }
    
    
    public static void main(String[] args) {
        int count = 6;
        int result = Hanoi.move(count, 'A', 'B','C');
        System.out.println("total numbers of moves:"+result);
    }
}

おすすめ

転載: www.cnblogs.com/watertreestar/p/11780240.html