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 汉诺塔内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 详解Java Web如何限制访问的IP的两种方法

    详解Java Web如何限制访问的IP的两种方法

    这篇文章主要介绍了详解Java Web如何限制访问的IP的两种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-10-10
  • Spring mvc Controller和RestFul原理解析

    Spring mvc Controller和RestFul原理解析

    这篇文章主要介绍了Spring mvc Controller和RestFul原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-03-03
  • Java面向对象之包装类的用途与实际使用

    Java面向对象之包装类的用途与实际使用

    所谓包装类,就是能够直接将简单类型的变量表示为一个类,在执行变量类型的相互转换时,我们会大量使用这些包装类,本文我们来深入探索一下Java包装类的相关内容,需要的朋友可以参考下
    2022-03-03
  • Java实现调用MySQL存储过程详解

    Java实现调用MySQL存储过程详解

    相信大家都知道存储过程是在大型数据库系统中,一组为了完成特定功能的SQL语句集。存储过程是数据库中的一个重要对象,任何一个设计良好的数据库应用程序都应该用到存储过程。Java调用mysql存储过程,实现如下,有需要的朋友们可以参考借鉴,下面来一起看看吧。
    2016-11-11
  • java类比C++的STL库详解

    java类比C++的STL库详解

    这篇文章主要介绍了java类比C++的STL库详解,标准模板库,是C++标准库的重要组成部分,中文可译为标准模板库或者泛型库,其包含有大量的模板类和模板函数,STL 是一些容器、算法和其他一些组件的集合,需要的朋友可以参考下
    2023-08-08
  • Java实现LRU缓存的实例详解

    Java实现LRU缓存的实例详解

    这篇文章主要介绍了Java实现LRU缓存的实例详解的相关资料,这里提供实例帮助大家理解掌握这部分内容,需要的朋友可以参考下
    2017-08-08
  • Java面试题冲刺第十一天--集合框架篇(2)

    Java面试题冲刺第十一天--集合框架篇(2)

    这篇文章主要为大家分享了最有价值的两道集合框架的面试题,涵盖内容全面,包括数据结构和算法相关的题目、经典面试编程题等,感兴趣的小伙伴们可以参考一下
    2021-07-07
  • 实例分析java开启线程的方法

    实例分析java开启线程的方法

    在本文里我们通过实例给大家讲解了JAVA开启线程的方法和相关知识点,需要的朋友们跟着学习下。
    2019-03-03
  • spring boot整合shiro安全框架过程解析

    spring boot整合shiro安全框架过程解析

    这篇文章主要介绍了spring boot整合shiro安全框架过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-11-11
  • 基于SpringBoot+vue实现前后端数据加解密

    基于SpringBoot+vue实现前后端数据加解密

    这篇文章主要给大家介绍了基于SpringBoot+vue实现前后端数据加解密,文中有详细的示例代码,具有一定的参考价值,感兴趣的小伙伴可以自己动手试一试
    2023-08-08

最新评论