拿捏汉诺塔问题(附有动图)

简介: 相传在古印度圣庙中,有一种被称为汉诺塔(Hanoi)的游戏。该游戏是在一块铜板装置上,有三根杆(编号A、B、C),在A杆自下而上、由大到小按顺序放置64个金盘。游戏的目标:把A杆上的金盘全部移到C杆上,并仍保持原有顺序叠好。操作规则:每次只能移动一个盘子,并且在移动过程中三根杆上都始终保持大盘在下,小盘在上,操作过程中盘子可以置于A、B、C任一杆上。

一、故事背景



相传在古印度圣庙中,有一种被称为汉诺塔(Hanoi)的游戏。该游戏是在一块铜板装置上,有三根杆(编号A、B、C),在A杆自下而上、由大到小按顺序放置64个金盘。游戏的目标:把A杆上的金盘全部移到C杆上,并仍保持原有顺序叠好。操作规则:每次只能移动一个盘子,并且在移动过程中三根杆上都始终保持大盘在下,小盘在上,操作过程中盘子可以置于A、B、C任一杆上。


二、简化问题



  1. 把 A 杆上的所有盘子放在 C 杆上


  1. 规则是:


(1)盘子可以被随意移动到别的杆,但一次只能移动一个盘子
(2)最终在 C 杆上呈现的结果是:小盘在上,大盘在下


三、建立模型(动态图)



  1. 一个圈圈


image.gif


  1. 两个圈圈


image.gif


  1. 三个圈圈


090beaef771346e48adc0c2a10aa3b10.gif


  1. 四个圈圈


1217b3077db9467391e3c8461e53f64d.gif


四、代码实现



程序清单:


public class test {
    public static void main(String[] args) {
        Hanoi(1, 'A', 'B', 'C');
        System.out.println();
        Hanoi(2, 'A', 'B', 'C');
        System.out.println();
        Hanoi(3, 'A', 'B', 'C');
        System.out.println();
        Hanoi(4, 'A', 'B', 'C');
        System.out.println();
    }
    public static void Hanoi(int n, char A, char B, char C) {
        if (n == 1) {
            move(A, C);
        } else {
            Hanoi(n - 1, A, C, B);
            move(A, C);
            Hanoi(n - 1, B, A, C);
        }
    }
    public static void move(char pos1, char pos2) {
        System.out.print(pos1 + "->" + pos2 + "  ");
    }
}


输出结果:


45a24ec219e5430ba84149a780c79b52.png


五、代码分析



  1. 主函数写了四种情况,分别对应 1 - 4 个盘子
  2. move 函数表示每一次盘子从一个位置移动到另一个位置
  3. Hanoi 函数是核心,它呈现了递归思想
  4. Hanoi 函数中 if (n == 1) 这一行代码就是终止条件,而下面对应的 else 就是规律公式,用来无限趋近于这个终止条件的,当达到这个终止条件时,那么就层层返回!也就是开始递归中的 “ 归 ”!


接下来,就Hanoi 函数,我们进行分析


当 n = 1 时,也就是说此时只有一个盘子,那么只需要移动一次,直接把它放到 C 杆上就行了。


当 n = 2 时,此时有两个盘子,那么我们先得把两个圈圈中最小的圈圈从 A 杆移动到 B 杆,过渡一下,然后才能把最大的圈圈放在 C 杆上,从而实现最终目的,也就是说,此时的B杆充当了中介。


当 n = 3 时,…

当 n = 4 时,…


上面我就不再赘述了,所以我们找到了规律:


不论几个盘子,B杆始终充当了中介杆,而此时,不论怎么移动,肯定出现了这种情况:C杆已经放置了最大的那个盘子,B杆上放的是除了那个最大盘子之外的所有盘子。


如下:


n = 3 时

此时 B 杆上的盘子个数为 n - 1 = 2


image.jpeg


n = 4时

此时 B 杆上的盘子个数为 n - 1 = 3


image.jpeg


当盘子很多很多时,假设就为n


image.jpeg


此时B杆上的盘子个数为 n - 1

那么我们就把这 n - 1 个盘子想象成一个整体,直接就挪到C杆上,但是我们不关心这其中有多少步骤,不关心这些步骤又是怎么算的,因为我们可以把这个计算步骤交给计算机去算,作为程序员,我们只要设置程序让他跑就行了。


image.jpeg


所以,请注意!!!


现在我们回过头看程序清单中 Hanoi 函数,我们就不迷糊了,请看图:

当 n >= 2 时,我们先把 n - 1 个盘子先从 A 挪到 B,再从 B 挪到 C,在这个过程中,我们要有整体的思想


我们要思考的是:在某一个过程,哪些盘子充当整体?哪个杆又充当中介?


image.png


很多人的思想总是停留在一个一个盘子的挪,这种思想是非常复杂的,甚至这样想问题的出发点就是错的!因为你找不到规律不说,在盘子的数量为4个以上时,你很可能会移错步骤,一步错,那么步步错!


你可以看到我在上面的动态图演示的时候,那已经是最完美的情况了,在不会移错的情况下都那么复杂,何况移错的情况下呢?


总结



  1. 经典的汉诺塔问题在计算机中,包含了递归思想,这就要回到递归的本质,通过找到规律,从而大事化小,得出结果。


  1. 前两个博客介绍了递归的思想和例子,这篇博客用来结尾基础部分的递归,后面等学到算法的时候,再回过头看,或许思路会更加清晰。


fa3e2c5611e5421fad5d8eadbb0f8abf.jpg


Over. 谢谢观看哟~


目录
相关文章
|
Ubuntu 数据安全/隐私保护
Ubuntu创建root用户
Ubuntu创建root用户
285 1
|
存储 NoSQL 算法
图解!24张图彻底弄懂九大常见数据结构!(上)
图解!24张图彻底弄懂九大常见数据结构!
图解!24张图彻底弄懂九大常见数据结构!(上)
|
网络协议 Java
Java TCP通信详解
TCP(Transmission Control Protocol)是一种面向连接的、可靠的网络传输协议,它提供了端到端的数据传输和可靠性保证。TCP通信适用于对数据传输的可靠性和完整性要求较高的场景,如文件传输、网页浏览等。本文将详细介绍Java中如何使用TCP协议进行网络通信,包括TCP套接字、服务器和客户端的创建、数据传输等。
567 0
|
机器学习/深度学习 存储 人工智能
强化学习与深度强化学习:深入解析与代码实现
本书《强化学习与深度强化学习:深入解析与代码实现》系统地介绍了强化学习的基本概念、经典算法及其在深度学习框架下的应用。从强化学习的基础理论出发,逐步深入到Q学习、SARSA等经典算法,再到DQN、Actor-Critic等深度强化学习方法,结合Python代码示例,帮助读者理解并实践这些先进的算法。书中还探讨了强化学习在无人驾驶、游戏AI等领域的应用及面临的挑战,为读者提供了丰富的理论知识和实战经验。
709 5
|
机器学习/深度学习 人工智能 自然语言处理
Transformer图解以及相关的概念解析
前言 transformer是目前NLP甚至是整个深度学习领域不能不提到的框架,同时大部分LLM也是使用其进行训练生成模型,所以transformer几乎是目前每一个机器人开发者或者人工智能开发者不能越过的一个框架。接下来本文将从顶层往下去一步步掀开transformer的面纱。 transformer概述 Transformer模型来自论文Attention Is All You Need。 在论文中最初是为了提高机器翻译的效率,它使用了Self-Attention机制和Position Encoding去替代RNN。后来大家发现Self-Attention的效果很好,并且在其它的地
408 2
|
机器学习/深度学习 传感器 数据采集
深度学习之设备异常检测与预测性维护
基于深度学习的设备异常检测与预测性维护是一项利用深度学习技术分析设备运行数据,实时检测设备运行过程中的异常情况,并预测未来可能的故障,以便提前进行维护,防止意外停机和生产中断。
982 1
|
Java 测试技术 API
软件测试中的自动化测试框架选择与应用##
在快速迭代的软件开发周期中,选择合适的自动化测试框架对于提高软件质量和开发效率至关重要。本文探讨了当前流行的几种自动化测试框架的特点和适用场景,旨在为软件开发团队提供决策依据。 ##
|
Kubernetes Docker 容器
【Docker专栏】Docker网络配置详解:从Bridge到Overlay
【5月更文挑战第7天】本文介绍了Docker的四种网络类型:Bridge(默认,每个容器连接虚拟桥)、Host(容器共享宿主机网络命名空间)、Overlay(跨宿主机通信,适合集群环境)和Macvlan(容器直接连接物理网络)。Bridge网络适用于同主机通信,而Overlay适合多主机集群。Host网络缺乏隔离,Macvlan则让容器直接连到外部网络。理解这些网络类型有助于优化Docker容器的网络配置。
911 8
【Docker专栏】Docker网络配置详解:从Bridge到Overlay
|
JSON Linux C语言
经验大分享:ubuntu20.4安装配置geant4和root
经验大分享:ubuntu20.4安装配置geant4和root
642 0
|
Java Maven Android开发
IntelliJ IDEA 中看到 classes, sources, javadocs 三种jar的区别和各自的作用
在 intelliJ idea 里面看到 ,Project Structure——》 Libraries ——》 Sources 的路径是红色的 看图会比较好。以guava包为例来说明。 可以看到在这看整个maven项目的依赖时,发现如图的情况,这红色是什么情况,是报错吗?需要处理吗?这3个不同jar都是什么东西,各自有啥作用。
5246 0