Java用递归方法解决汉诺塔问题详解

 更新时间:2022年04月14日 10:39:38   作者:Killing Vibe  
汉诺塔问题是一个经典的问题。汉诺塔(Hanoi Tower),又称河内塔,源于印度一个古老传说。本文将用Java递归方法求解这一问题,感兴趣的可以学习一下

前言

博主之前有写过关于递归问题的思维模式:

递归的思路

下面将用这种思维模式来求解经典汉诺塔问题。

一、问题描述

汉诺塔(又称河内塔)问题是源于印度一个古老传说。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。

大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。

并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。

问应该如何操作?

玩法如下:

1.有三根杆子A,B,C。A杆上有若干碟子

2.每次移动一块碟子,小的只能叠在大的上面

3.把所有碟子从A杆全部移到C杆上

在这里插入图片描述

在这里插入图片描述

二、问题分析

(两步直接解决问题)

1.第一步(先思考终止条件)

考虑n=1的情况:

在这里插入图片描述

只需要把这个块从A移到C即可。

在这里插入图片描述

2.第二步(宏观看待整个问题)

当n>=2时,把如图蓝色框框想象成上面的n-1个块(我把它称为一堆块),红色框框表示的是最下面的一块(命名为底块),这样问题可以简化为如图所示的三步。

在这里插入图片描述

第一步:先把上面的一堆块 从A(起始柱子)移动到B(目标柱子)上,在这个过程中,C(辅助柱子)起到中转的作用(因为题目要求移动的过程中,小盘子要保证在大盘子上面)

第二步:把最下面的红色大块直接从A(起始柱子)移动到C(目标柱子)。这里注意,这一步的目标柱子和第一步的不一样。

第三步:把上面的一堆块从B(起始柱子)移动到C(目标柱子)上,A(辅助柱子)起到中转的作用。

三、解决方案

那么问题就很简单了,递归的代码就分为两部分:终止条件和递归逻辑。

上一篇博客讲到,我们思考递归问题的时候,可以直接把这个大问题拆解成很多个子问题,想象这个功能别人已经写好了(就是这个递归函数),我们做不到的功能直接调用这个递归函数就可以(注意逻辑)。

public class Recursion {
    public static void main(String[] args) {
        int n = 3;
        hanoiTower(n,'A','B','C');
    }

    /**
     * 传入n个盘子,编号从1..n,我就能按照汉诺塔的规则,从目标盘子A -> C ,B是辅助盘
     * @param nDisks
     * @param A 起始柱子
     * @param B 辅助柱子
     * @param C 目标柱子
     */
    public static void hanoiTower(int nDisks,char A,char B,char C) {
        // 边界
        if (nDisks == 1) {
            // 直接一步到位,用不到B,A上的这一个盘子从A -> C
            move(nDisks,A,C);
            return;
        }
        // n >= 2,核心步骤1,先把顶上的 n -1个小盘子从A -> B,C作为辅助
        hanoiTower(nDisks - 1,A,C,B);
        // 核心步骤2.此时A上就剩下第n个盘子,一步到位将最大的这个盘子一次移动到C
        move(nDisks,A,C);
        // 核心步骤3.此时再把B上的这n-1个盘子从B -> C,A作为辅助
        hanoiTower(nDisks - 1,B,A,C);
    }

    /**
     * 将编号为n的盘子从sourceTower移动到destTower
     * @param nDisks
     * @param sourceTower
     * @param destTower
     */
    public static void move(int nDisks, char sourceTower, char destTower) {
        System.out.println("编号为"+nDisks+"的盘子正在从"+sourceTower+"->"+destTower);
    }

四、示例

n=3的时候

在这里插入图片描述

在这里插入图片描述

以上就是用宏观思维去进行递归求解汉诺塔的方法,希望大家多多支持哟(●ˇ∀ˇ●)

到此这篇关于Java用递归方法解决汉诺塔问题详解的文章就介绍到这了,更多相关Java 汉诺塔内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Android开发简单计算器实现代码

    Android开发简单计算器实现代码

    这篇文章主要介绍了Android开发简单计算器实现,本文放置了完整的Android开发电脑,通过部署项目可以直接按到效果,希望本篇文章可以对你有所帮助
    2021-06-06
  • 新手初学Java流程控制

    新手初学Java流程控制

    这篇文章主要介绍了JAVA流程控制语句的的相关资料,文中讲解非常细致,代码帮助大家更好的理解和学习,感兴趣的朋友可以了解下,希望可以帮到你
    2021-07-07
  • RocketMQ之Consumer整体介绍启动源码分析

    RocketMQ之Consumer整体介绍启动源码分析

    这篇文章主要为大家介绍了RocketMQ源码分析之Consumer整体介绍启动分析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-05-05
  • MyBatis中基于别名typeAliases的设置

    MyBatis中基于别名typeAliases的设置

    这篇文章主要介绍了MyBatis中基于别名typeAliases的设置,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-07-07
  • mybatis使用foreach标签进行嵌套插入

    mybatis使用foreach标签进行嵌套插入

    数据库插入操作常见于多层架构设计中,本文提供了一个具体的实现方案,涉及三层实体类结构,第一层实体类负责基本数据结构的定义,第二层和第三层实体类则提供更详细的业务逻辑处理,同时,文章还介绍了相应的mapper接口和配置文件设置
    2024-09-09
  • Netty中的心跳检测机制详解

    Netty中的心跳检测机制详解

    这篇文章主要介绍了Netty中的心跳检测机制详解,Netty 是 基于 TCP 协议开发的,在四层协议 TCP 协议的实现中也提供了 keepalive 报文用来探测对端是否可用,TCP 层将在定时时间到后发送相应的 KeepAlive 探针以确定连接可用性,需要的朋友可以参考下
    2023-12-12
  • 使用SpringBoot整合ssm项目的实例详解

    使用SpringBoot整合ssm项目的实例详解

    Spring Boot 现在已经成为 Java 开发领域的一颗璀璨明珠,它本身是包容万象的,可以跟各种技术集成。这篇文章主要介绍了使用SpringBoot整合ssm项目,需要的朋友可以参考下
    2018-11-11
  • Java中的位运算符全解

    Java中的位运算符全解

    这篇文章主要为大家详细介绍了Java中的位运算符,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-03-03
  • Spring boot 无法注入service问题

    Spring boot 无法注入service问题

    这篇文章主要介绍了Spring boot 无法注入service问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-10-10
  • SpringBoot使用Thymeleaf自定义标签的实例代码

    SpringBoot使用Thymeleaf自定义标签的实例代码

    这篇文章主要介绍了SpringBoot使用Thymeleaf自定义标签的实例代码,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-09-09

最新评论