再帰と非再帰的ハノイの塔を解きます

制限は、直接移動するには、直接、右端の一番左の列から、また右端から左に移動することはできませんが、中間経由しなければなりません。記録動作及び手順の最も最適総数が移動したときタワーN層を求める場合。
ここに画像を挿入説明
方法:
再帰
:分析:最上位から1〜N、その後の最下位に、カラムを離れた場合にN層
、「左」の列内の残りのN層は、それが全てで移動することが望ましい場合は1、存在する三つのステップ:
(1)1〜N-​​1層、左から1列目の全て。(再帰的に)
(2)N層目を左の列に移動させる
1〜N-​​1層は、右側の列に移動させる(3)すべての(再帰的)
注:左の列からの残りのN層移動すると、右に移動され、右に移動し、プロセスは上記と同じです。
2.右側にあるすべての希望で「左」の残りのN層塔場合は
、右のすべての最初の塔に左から1〜N-​​1層に(1)。(再帰的に)
(2)N番目の層は、左側の列に移動される
左右の列のすべてから(3)1〜N-1層。(再帰的に)
(4)最初の列から右のN層へ
(5)1〜N-1層、左から右への列の全て。(再帰的に)
コードは以下の通りであります:

import java.util.Scanner;
public class hannuo {
    public int process(int n,String left,String mid,String right,String from,String to){
       if(n==1){
           if(from.equals(mid) || to.equals(mid)){
               System.out.println("Move 1 from "+ from + " to "+to);
               return 1;
           }
           else{
               System.out.println("Move 1 from "+from+ " to "+mid);
               System.out.println("Move 1 from "+from+ " to "+to);
             return 2;
           }
       }
        int result=0;
       if(from.equals(mid)||to.equals(mid)) {

           String temp = (from.equals(left) || to.equals(right)) ? right : left;
           int step1 = process(n - 1, left, mid, right, from, temp);    //递归
           int step2 = 1;
           System.out.println("Move" + n + "from" + from + " to " + to);
           int step3 = process(n - 1, left, mid, right, temp, to);
           result=step1+step2+step3;
           System.out.println("移动总步数"+ result);
       }
       else{
           int step1 = process(n - 1, left, mid, right, from, to);    //递归
           int step2 = 1;
           System.out.println("Move" + n + "from" + from + " to " + mid);
           int step3=process(n-1,left,mid,right,to,from);
           int step4=1;
           System.out.println("Move"+ n +" from "+ mid +" to "+to);
           int step5=process(n-1,left,mid,right,from,to);
           result=step1+step2+step3+step4+step5;
           System.out.println("移动总步数"+ result);


       }
     return result;
    }
    public int hannuo1(int n,String left,String mid,String right){
        if(n<1){
    return 0;
        }
        return process(n,left,mid,right,left,right);
    }

    public static void main(String[] args) {
        Scanner scan=new Scanner(System.in);
        System.out.println("please input the nummber:");
        int n=scan.nextInt();
     hannuo han=new hannuo();
       han.hannuo1(n,"left","mid","right");
    }
}

結果:
ここに画像を挿入説明
2:非再帰的
私たちは自然にスタック、左、中央、および抽象スタックする正しい場所を考える非再帰的な
ここに画像を挿入説明
コードの実装を:

class State
{
    public int n;
    public String left;
    public String mid;
    public String right;
    public State(int n, String left, String mid, String right)
    {
        this.n = n;
        this.left =left;
        this.mid =mid;
        this.right =right;
    }
}
//栈
class StateStack {
    private State[] stack = new State[1000];
    //栈顶
    private int top = 0;

    //入栈
    public void push(State s) {
        stack[top++] = s;
    }

    //出栈
    public State pop() {
        if (top > 0) {
            return stack[--top];
        }
        return null;
    }
}
public class hannuota2 {

    public static void hannuota2(int n, String left,String mid, String right) {
        //创建一个栈
        StateStack s = new StateStack();
        //将开始状态进栈
        s.push(new State(n,"left", "mid","right"));
        //保存出栈元素
        State state = null;
        //出栈
        while ((state = s.pop()) != null) {
            //如果n为1,直接移动left->right
            if (state.n == 1) {
                move(state.left, state.right);
            }
            //如果n大于1,则按照递归的思路,先处理hanoi(n-1,left,right,mid),再移动left->right(等价于hanoi(1,left,mid,right) ),然后处理hanoi(n-1,mid,left,right),因为是栈,所以要逆序添加
            else {
                //栈结构先进后出,所以需要逆序进栈
                s.push(new State(state.n - 1, state.mid, state.left, state.right));
                s.push(new State(1, state.left, state.mid, state.right));
                s.push(new State(state.n - 1, state.left, state.right, state.mid));
            }
        }
    }

    public static void move(String str1, String str2) {
        System.out.println(str1 + "->" + str2);
    }


    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        System.out.println("please input the nummber:");
        int n = scan.nextInt();

        hannuota2(n, "left", "mid", "right");
    }
}


おすすめ

転載: blog.csdn.net/weixin_42373873/article/details/89923727