递归求解汉诺塔问题

简介: 博主之前有写过关于递归问题的思维模式:[递归的思路](https://blog.csdn.net/qq_43575801/article/details/124029190?spm=1001.2014.3001.5501)下面将用这种思维模式来求解经典汉诺塔问题。

前言

博主之前有写过关于递归问题的思维模式:
递归的思路
下面将用这种思维模式来求解经典汉诺塔问题。

一、问题描述

汉诺塔(又称河内塔)问题是源于印度一个古老传说。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。
大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。
并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。
问应该如何操作?
玩法如下:

1.有三根杆子A,B,C。A杆上有若干碟子
2.每次移动一块碟子,小的只能叠在大的上面
3.把所有碟子从A杆全部移到C杆上
![在这里插入图片描述](https://ucc.alicdn.com/images/user-upload-01/cb3bcd1168a24b4c83b799951f6fe444.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAS2lsbGluZyBWaWJl,size_20,color_FFFFFF,t_70,g_se,x_16)

在这里插入图片描述

二、问题分析(两步直接解决问题):

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的时候)

在这里插入图片描述

在这里插入图片描述

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

相关文章
|
9月前
|
人工智能 Python
【够用就好003】发布人生第二款软件pc微信多开
发布人生第二款软件pc微信多开,在deepseek和豆包的帮助下封装了这个微信多开小工具。
|
弹性计算 缓存 监控
基于“日志审计应用”的 DNS 日志洞察实践
DNS 解析日志是一种记录 DNS 请求和响应的基础信息,监控 DNS 服务可以帮助用户识别网络活动并保持系统安全。日志审计服务支持采集 DNS 内网解析日志、公网权威解析日志、GTM 日志。理解 DNS 日志的字段含义,洞察 DNS 日志背后所代表的网络信息,既可以帮助发现和诊断 DNS 解析相关的问题,还可以检测和识别潜在的安全威胁。
8846 115
|
监控 JavaScript Shell
如何安装和管理 Supervisor
如何安装和管理 Supervisor
384 0
|
存储 网络协议 安全
30 道初级网络工程师面试题,涵盖 OSI 模型、TCP/IP 协议栈、IP 地址、子网掩码、VLAN、STP、DHCP、DNS、防火墙、NAT、VPN 等基础知识和技术,帮助小白们充分准备面试,顺利踏入职场
本文精选了 30 道初级网络工程师面试题,涵盖 OSI 模型、TCP/IP 协议栈、IP 地址、子网掩码、VLAN、STP、DHCP、DNS、防火墙、NAT、VPN 等基础知识和技术,帮助小白们充分准备面试,顺利踏入职场。
1500 2
|
存储 缓存 算法
详解微处理器CPU的系统结构
CPU的主要性能参数: 1. CPU的主频,即CPU内核工作的时钟频率(CPU Clock Speed)。时钟频率速度是指同步电路中时钟的基础频率,它以“若干次周期每秒”来度量,量度单位采用SI单位赫兹(Hz)。 2. 外频,是CPU外部的工作频率,是由主板提供的基准时钟频率。 3. FSB频率,是连接CPU和主板芯片组中的北桥芯片的前端总线(Front Side Bus)上的数据传输频率。 4. CPU的主频和外频间存在这样的关系:主频=外频×倍频. 指令顺序控制 控制 程序中指令的执行顺序。
968 0
详解微处理器CPU的系统结构
|
存储 SQL 关系型数据库
谈谈SQL的优化经验
谈谈SQL的优化经验
一般模式
【2月更文挑战第20天】一般模式。
162 1
|
存储 JSON API
钉钉如何获取调用「创建或更新审批表单模板」接口所需的访问凭证?
钉钉如何获取调用「创建或更新审批表单模板」接口所需的访问凭证?
251 0
|
算法 程序员 C++
LeetCode精讲(1)—— 单调栈有关习题及其变式
我们首先是要去熟悉单调栈这种结构,熟悉后,我们遇到问题的时候就只需要将原来包装的问题拆分,层层拆分后发现有用单调栈的这种需求,便可以瞬间联想到并去使用。
443 1
LeetCode精讲(1)—— 单调栈有关习题及其变式
|
缓存 JSON 移动开发
mPaaS云平台运维系列之—移动网关产品介绍
移动网关服务(Mobile Gateway Service,MGS)是mPaaS提供的连接移动客户端与服务端的组件产品。该组件简化了移动端与服务端的数据协议和通讯协议,能够显著提升开发效率和网络通讯效率。本章主要介绍产品基本概念。
2187 0
mPaaS云平台运维系列之—移动网关产品介绍