汉诺塔(递归)

题目:

1、有三根相邻的柱子,标号为A,B,C。

2、A柱子上从下到上按金字塔状叠放着n个不同大小的圆盘。

3、现在把所有盘子一个一个移动到柱子B上,并且每次移动同一根柱子上都不能出现大盘子在小盘子上方。

暴力递归思路:

从最左移动到最右步骤如下:

1.将第1到n-1号圆盘从A移动到B(想将第n号圆盘从A移动到C,需要将1到n-1的圆盘从A移动到B;因为1到n-1号盘子挡路了,要把它们移动走,n号盘子才能移动)

2.将第n号圆盘从A移动到C

3.将1到n-1号圆盘从B移动到C(想将第n-1号盘子从B移动到C,就要将第1到n-2号圆盘从B移动到A;思路同步骤1)

综上所述:

只需要6种移动即可完成汉诺塔的游戏,即A2B,A2C,B2A,B2C,C2A,C2B

代码:

public class Hanoi {

    public static void main(String[] args) {
        int n = 3;
        A2C(n);
    }

    private static void A2B(int n) {
        if (n == 1) {
            System.out.println("Move 1 from A to B");
            return;
        }

        //将1到n-1从A移动到C
        A2C(n - 1);
        //将n从A移动到B
        System.out.println(String.format("Move %s from A to B", n));
        //将1到n-1从C移动到B
        C2B(n - 1);
    }
    
    private static void A2C(int n) {
        if (n == 1) {
            System.out.println("Move 1 from A to C");
            return;
        }

        //将1到n-1从A移动到B
        A2B(n - 1);
        //将n从A移动到C
        System.out.println(String.format("Move %s from A to C", n));
        //将1到n-1从B移动到C
        B2C(n - 1);
    }
    
    private static void C2B(int n) {
        if (n == 1) {
            System.out.println("Move 1 from C to B");
            return;
        }

        //将1到n-1从C移动到A
        C2A(n - 1);
        //将n从C移动到B
        System.out.println(String.format("Move %s from C to B", n));
        //将1到n-1从A移动到B
        A2B(n - 1);
    }
    
    private static void C2A(int n) {
        if (n == 1) {
            System.out.println("Move 1 from C to A");
            return;
        }

        //将1到n-1从C移动到B
        C2B(n - 1);
        //将n从C移动到A
        System.out.println(String.format("Move %s from C to A", n));
        //将1到n-1从B移动到C
        B2C(n - 1);
    }
    
    private static void B2C(int n) {
        if (n == 1) {
            System.out.println("Move 1 from B to C");
            return;
        }

        //将1到n-1从B移动到A
        B2A(n - 1);
        //将n从B移动到C
        System.out.println(String.format("Move %s from B to C", n));
        //将1到n-1从A移动到C
        A2C(n - 1);
    }
    
    private static void B2A(int n) {
        if (n == 1) {
            System.out.println("Move 1 from B to A");
            return;
        }

        //将1到n-1从B移动到C
        B2C(n - 1);
        //将n从B移动到C
        System.out.println(String.format("Move %s from B to A", n));
        //将1到n-1从C移动到A
        C2A(n - 1);
    }
}

代码优化(抽象)

均是从from(可能是A,B,C任一一个)到to(可能是A,B,C任一一个),另一个为other(可能是A,B,C任一一个)综上所述6个函数可以抽象成如下代码

private static void move(int n, String from, String to, String other) {
        if (n == 1) {
            System.out.println(String.format("Move 1 from %s to %s", from, to));
            return;
        }

        //移动1到n-1从from点到other点(令n号圆盘可以移动到to位置)
        move(n - 1, from, other, to);
        //移动第n号圆盘到to位置
        System.out.println(String.format("Move %s from %s to %s", n, from, to));
        //移动1到n-1从other到to点
        move(n - 1, other, to, from);
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值