当前位置: 首页 > news >正文

汉诺塔递归算法精讲

文章目录

  • 前言
  • 一、汉诺塔是个啥?
  • 二、手动解法
  • 三、解法抽象
  • 四、递归解法
  • 五、总结


前言

递归算法是计算机算法中的基础算法,也是非常重要的算法,从某种程度上讲,它有一点儿AI的影子。人脑是可以完成递归思路的,但是对不起,残酷的现实是,一般人脑在精力集中的情况下,能递归个三五层就就基本晕菜了。反正我是这样,你或者您可能深度多一些。当然个别领域,例如棋手,可能深度多达10层或者20层,这是凤毛麟角了。

废话少说,说说汉诺塔的递归解法思路,并给出本人朴素的解释,力图使一看就晕的小伙伴们,能看清楚。


一、汉诺塔是个啥?

尽管您或许知道这个小游戏,但是为了将问题说清楚,还是要简单介绍一下。以下内容来自 《百度百科》

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

二、手动解法

下面尝试用静态图来分析和描述一下手动解法,大家也可以参考下列链接,以期获得感性认识。
汉诺塔在线游戏
为了简便起见,我们从三个开始尝试。
如图:
在这里插入图片描述
根据题目要求,每次移动一个,而且必须是小的在上面。如果胡乱尝试,您可能好会成功,但是可能会不得要领,因此先分析,才能厘清思路。
分析:我们考虑最后一步,必然是将 1 从什么地方 移到 C 上,倒数第二步,必然是将2 从什么地方移到C上,倒数第三步必然是将3 从什么地方移到C上。因为3 最大,因此,倒数第三步时,必然是3的上面没有盘子,C的上面没有盘子。否则就违背了原则,因此,如果想办法通过什么方法变成下面的情况,倒数第三步就实现了。
如图:
在这里插入图片描述
此时就可以把 3 移到 C上,如图
在这里插入图片描述
冷静一下,你会发现,此时问题已经降级为,如何将两个盘子移到C上的问题,只是位置从A 变成了B,聪明的你,可以知道这并没有区别。所以现在的问题是 怎么将两个盘子移到到C上。这个问题就非常简单了,1->A, 2->C,1->C。 由于我们遵守小的在上面的原则,就是说每次只能取最上面的 一个 盘子,因此上面的步骤也可以用位置来表示就是
B->A, B->C, A->C, 至于上面的盘子是啥,其本身已经记住了。
OK, 三个已经完成了。

三、解法抽象

现在我们整理一下思路:
要想把3个盘子从A移到C上,必须先把3-1个盘子从A移到B上;套用上面的想法,
做进一步的思考:如果想把3-1个盘子从A移到B上,必需先把 3-1-1个盘子从A移到C上。
仔细看上面的步骤,我们进一步分析其细节,把语言可以精确的描述为:

要想把3(n)个盘子从A 移到C上,必须先把3-1(n-1)个盘子通过C移到B上;
如果想把3-1(n-1)个盘子从A移到B上,比需先把 3-1-1(n-1-1)个盘子通过B移到C上。
可以看出上述的步骤的相似性,就是有三个抽象点,第一:起点, 第二 终点, 第三是:过度点。

仿照上面的思路,我们可以得到 n个盘子的移动方法;
要想把n个盘子移到C上,必须先把n-1个盘子通过C移到B上;
采用更抽象的描述就是:
要想把n个盘子从 起点 移到 终点上,必须先把n-1个盘子通过 终点 移到 过渡点上;
我们用 From 表示起点,To 表示终点 , By 表示过渡点,那么上面的描述就是

要想把n个盘子从from 移到 to ,必须先把n-1个盘子通过 to 移到 by 上;

进一步,假设我们完成了一个过程,叫 HanoiMove, 根据上面的分析,它必须包括四个关键属性: 个数n,起点 from,过渡点 by,终点 to,我们不妨记作

HanoiMove(n,from, by, To) ,这个表示 把 n 个盘子从From 经过 by, 移到到 To,聪明的你应该看出来这不就是函数吗?为了更清楚起见,我们采用 相应的位置表示起点,过渡点和终点。

四、递归解法

根据上面的分析,我们只要逐层降级就可以完成任务了,这就用到了递归,为了说清楚,我们慢慢来。

第一步:调用 HanoiMove(n,from, by, To) ,表示将n从 From 经过 by 移到 To 上。

第二步:HanoiMove(n-1,from, by, To ) ,这个表示 将n-1个盘子,从 from 经过to移到 by 上

第三步:此时From 上面只有一个 最大号的 盘子了 ,编号n,只需 将 编号n的盘子从 From 移动到 to上就可以了。注意此时是移动一个盘子,没有递归的问题。

第四步:这个时候, n-1个盘子 在 by 上面(by成为起点了,from 是过渡点, to仍然是终点), 调用前面的过程 HanoiMove(n-1,by, from, to ) 这个表示 将n-1个盘子,从 by 经过From移到 to上

到这一步就完成了所有的盘子的搬运。

写成伪代码的函数就是:

HanoiMove(n,from, by, To){HanoiMove(n-1,from, by, To ) 输出:From->toHanoiMove(n-1,by, from, to )

}
但是这样就行了吗?
递归调用的一个关键就是结束条件,如果没有,就会一直递归下去,直到溢出错误出现。上面的伪代码中,没有结束条件,那么结束条件是什么呢?显然是n=1 的时候,就结束了。因此,加上结束条件之后的代码为:

HanoiMove(n,from, by, To){if(n==1) {输出:From->toreturn }HanoiMove(n-1,from, by, To ) 输出:From->toHanoiMove(n-1,by, from, to )

}
可以将上述伪代码,改编成某种语言运行

其C#代码如下:

       public void HanoiMove(int n, string from, string by, string to){if (n > 1){HanoiMove(n - 1, from , to, by);Console.WriteLine( String.Format("\r\n{0} {1}->{2}", n, from, to));//是盘子编号,可以不用。HanoiMove(n - 1, by, from, to);}else{Console.WriteLine( String.Format("\r\n{0} {1}->{2}", n, from, to));}}

注意:上面的输出的n 可以不用。


五、总结

对于递归调用的代码实现,一定要将过程抽象出来,反复的在头脑中进行这一过程的拟合,将具体步骤进行高度的抽象,具化成参数和表达式(输出),并设置结束条件(递归出口)。

MaraSunDB BJFWDQ 2023-02-15

`

相关文章:

汉诺塔递归算法精讲

文章目录前言一、汉诺塔是个啥?二、手动解法三、解法抽象四、递归解法五、总结前言 递归算法是计算机算法中的基础算法,也是非常重要的算法,从某种程度上讲,它有一点儿AI的影子。人脑是可以完成递归思路的,但是对不起…...

vue的$nextTick的原理

参考:https://cloud.tencent.com/developer/article/1633546 总结一下:就是$nextTick将回调函数放到微任务或者宏任务当中以延迟它地执行顺序;(总结的也比较懒👶) 重要的是理解源码中它的三个参数的意思&a…...

前端学习第一阶段——第五章CSS(下)

5-9 浮动 08-浮动导读 09-传统网页布局三种方式 10-为什么需要浮动 11-什么是浮动 12-浮动特性-脱标 13-浮动特性-浮动元素一行显示 14-浮动特性-浮动元素具有行内块特性 15-浮动元素经常搭配标准流的父元素 16-浮动布局练习1 <!DOCTYPE html> <html lang"en&quo…...

基于django搭建简单的个人博客

文章目录第一步、在Ubuntu中安装虚拟环境并进入第二步、安装blog所需要的包&#xff0c;在requirements.txt中安装mysqlclient可能会报错&#xff0c;输入下列命令后在安装即可成功第三步、创建好数据库&#xff0c;把测试数据导入第四步、修改DjangoBlog包中 settings中数据库…...

JVM解释器与JIT编译器如何并存?

[1] JVM解释器 JVM设计的初衷仅仅只是为了满足Java程序实现跨平台特性&#xff0c;因此避免采用静态编译的方式直接生成本地机器指令&#xff0c;从而诞生了实现解释器在运行时采用逐行解释字节码的执行程序。 解释器真正意义上所承担的角色就是一个运行时“翻译者”&#xff0…...

生产者消费者模型

目录 一、生产者消费者模型的概念 二、生产者消费者模型的特点 三、生产者消费者模型优点 四、基于BlockingQueue的生产者消费者模型 4.1 基本认识 4.2 模拟实现 一、生产者消费者模型的概念 生产者消费者模式就是通过一个容器来解决生产者和消费者的强耦合问题 生产者和…...

mysql索引--实例

学生表&#xff1a;Student (Sno, Sname, Ssex , Sage, Sdept) 学号&#xff0c;姓名&#xff0c;性别&#xff0c;年龄&#xff0c;所在系 Sno为主键 课程表&#xff1a;Course (Cno, Cname,) 课程号&#xff0c;课程名 Cno为主键 学生选课表&#xff1a;SC (Sno, Cno, Score)…...

浅聊一下,可中断锁(ReentrantLock)

前言 今天早上上厕所&#xff0c;上的我痔疮犯了&#xff0c;屁股一坐下去就感觉一根针在刺我&#xff0c;得的是外痔&#xff0c;之前还坚持用痔疮膏来着&#xff0c;但是感觉涂药的那个姿势以及位置我实在无法忍受&#xff0c;就把它给断了&#xff0c;到头来还是屁股糟了罪&…...

关于Arcgis林业数据处理的62个常用技巧

一、计算面积 ( 可以帮我们计算小班面积 ) 添加 AREA 字段&#xff0c;然后右键点击字段列&#xff0c;然后点击 CALCULATE VALUES; ---> 选择 ADVANCED &#xff0d;&#xff0d;》把下面的代码输入&#xff0c;然后在最下面 处写 OUTPUT 点击 OK 就 OK 了。 Dim Outp…...

一些NLP术语

一些NLP术语pre-training&#xff08;预训练&#xff09;fine-tuning&#xff08;微调&#xff09;下游任务Few-shot Learning&#xff08;少样本学习&#xff09;Prompt&#xff1f;&#xff08;自然语言提示信息&#xff09;二级标题三级标题pre-training&#xff08;预训练&…...

Session详解,学习 Session对象一篇文章就够了

目录 1 Session概述 2 Session原理 3 Session使用 3.1 获取Session 3.2 Session保存数据 3.3 Session获取数据 3.4 Session移除数据 4 Session与Request应用区别 4.1 Session和request存储数据 4.2 获取session和request中的值 4.3 session和request区别效果 5 Sess…...

Java——不同的子序列

题目链接 leetcode在线oj题——不同的子序列 题目描述 给定一个字符串 s 和一个字符串 t &#xff0c;计算在 s 的子序列中 t 出现的个数。 字符串的一个 子序列 是指&#xff0c;通过删除一些&#xff08;也可以不删除&#xff09;字符且不干扰剩余字符相对位置所组成的新…...

Git 基本操作之Git GUI界面和git命令行如何选择

1. 为啥推荐使用git命令行 我发现公司有很多的同事都喜欢使用git的GUI界面工具&#xff0c;喜欢鼠标点点点就完成了代码的提交&#xff0c;这种方式的确是比较简单便捷&#xff0c;但是却存在风险。先上一个事故给大家醒醒脑。 VScode Git 界面操作引发的惨案 上面的惨案是VS…...

Python编程 动态爱心

作者简介&#xff1a;一名在校计算机学生、每天分享Python的学习经验、和学习笔记。 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a;网络豆的主页​​​​​​ 目录 前言 一.所用库 1.random简介 2.math 简介 3.tkinter库的简介 二.实际图 三.…...

JavaScript :基础语法

位置&#xff1a; HTML 中的 Javascript 脚本代码必须位于 <script> 与 </script> 标签之间。 JavaScript 输出方式 window.alert() 弹出警告框。document.write() 将内容写到 HTML 文档中。innerHTML 写入到 HTML 元素。console.log() 写入到浏览器的控制台。 …...

buu [AFCTF2018]Single 1

题目描述&#xff1a; Jmqrida rva Lfmz (JRL) eu m uqajemf seny xl enlxdomrexn uajiderc jxoqarerexnu. Rvada mda rvdaa jxooxn rcqau xl JRLu: Paxqmdyc, Mrrmjs-Yalanja mny oekay. Paxqmdyc-urcfa JRLu vmu m jxiqfa xl giaurexnu (rmusu) en dmnza xl jmrazxdeau. Lxd …...

Linux C++ 200行完成线程池类

文章目录1、atomic使用2、volatile关键字3、条件变量4、成员函数指针使用5、线程池6、主线程先退出对子线程影响7、return、exit、pthread_exit区别8、进程和线程的区别1、atomic使用 原子操作&#xff0c;不可分割的操作&#xff0c;要么完整&#xff0c;要么不完整。 #includ…...

C语言指针剖析(初阶) 最详细!

什么是指针&#xff1f;指针和指针类型野指针指针运算指针和数组二级指针指针数组什么是指针&#xff1f;指针是内存中一个最小单元的编号&#xff0c;也就是地址。1.把内存划分为一个个的内存单元&#xff0c;一个内存单元的大小是一个字节。2.每个字节都给定唯一的编号&#…...

AcWing语法基础课笔记 第三章 C++中的循环结构

第三章 C中的循环结构 学习编程语言语法是次要的&#xff0c;思维是主要的。如何把头脑中的想法变成简洁的代码&#xff0c;至关重要。 ——闫学灿 学习循环语句只需要抓住一点——代码执行顺序&#xff01; while循环 可以简单理解为循环版的if语句。If语句是判断一次&#xf…...

A simple freeD tracking protocol implementation written in golang

可以使用的go版本freed调试代码 可以通过udp发送和接收数据 What is freeD? freeD is a very simple protocol used to exchange camera tracking data. It was originally developed by Vinten and is now supported by a wide range of hard- and software including Unreal…...

简约精美电商小程序【源码好优多】

简介 一款开源的电商系统&#xff0c;包含微信小程序和H5端&#xff0c;为大中小企业提供移动电子商务优秀的解决方案。 后台采用Thinkphp5.1框架开发&#xff0c;执行效率、扩展性、稳定性值得信赖。并且Jshop小程序商城上手难度低&#xff0c;可大量节省定制化开发周期。 功…...

全网详解 .npmrc 配置文件:比如.npmrc的优先级、命令行,如何配置.npmrc以及npm常用命令等

文章目录1. 文章引言2. 简述.npmrc3. 配置.npmrc3.1 .npmrc配置文件的优先级3.2 .npmrc设置的命令行3.3 如何设置.npmrc4. 配置发布组件5. npm常用命令6. 重要备注6.1 yarn6.2 scope命名空间6.3 镜像出错1. 文章引言 今天在某低代码平台开发项目时&#xff0c;看到如下编译配置…...

从0开始学python -31

Python3 模块-1 在前面的几个章节中我们基本上是用 python 解释器来编程&#xff0c;如果你从 Python 解释器退出再进入&#xff0c;那么你定义的所有的方法和变量就都消失了。 为此 Python 提供了一个办法&#xff0c;把这些定义存放在文件中&#xff0c;为一些脚本或者交互…...

Jenkins的使用教程

介绍&#xff1a; Jenkins是一个开源软件项目&#xff0c;是基于Java开发的一种持续集成工具&#xff0c;用于监控持续重复的工作&#xff0c;旨在提供一个开放易用的软件平台&#xff0c;使软件的持续集成变成可能。 目的: 最重要目的就是把原来分散在各个机器上繁杂的工作全部…...

1.Maven的坐标和依赖

【maven坐标】1.groupId: 通常与域名反向一一对应2.artifactId: 通常使用实际项目名称3.version: 项目当前版本号4.packaging&#xff1a;maven项目的打包方式&#xff0c;默认是jar5.classifier: 定义构建输出的一些附属构件&#xff0c;例如&#xff1a;nexus-indexer-2.0.0.…...

Jenkins 笔记

Jenkins brew install jenkins-lts brew services restart jenkins-lts brew services stop jenkins-lts b999ff5683464346b6d083f894968121 l 软件构建自动化 &#xff1a;配置完成后&#xff0c;CI系统会依照预先制定的时间表&#xff0c;或者针对某一特定事件&#xff0c;…...

Python和Java语言,哪个更适合做自动化测试?

经常有测试新手问我&#xff1a;Python和Java语言&#xff0c;哪个更适合做自动化测试&#xff1f;本来想简单的回答一下的&#xff0c;但又觉得对不起大家对小编的信任。因此&#xff0c;小编今天专门写了一篇文章来回答这个问题。欢迎各位大佬补充~1、什么是自动化测试&#…...

互联网的路由选择协议

互联网的路由选择协议 文章目录互联网的路由选择协议路由选择协议的几个概念分层次路由选择协议内部网关协议RIP协议距离向量算法RIP协议的报文格式内部网关协议OSPFOSPF的报文格式✨OSPF的特点外部网关协议BGPBGP的报文格式参考本篇主要讨论的是路由表中的路由是如何得出来的。…...

接口幂等性处理

1.Token 机制&#xff1a; a首先客户端请求服务端&#xff0c;获取一个 token&#xff0c;每一次请求都获取到一个全新的 token&#xff08;当然这个 token 会有一个超时时间&#xff09;&#xff0c;将 token 存入 redis 中&#xff0c;然后将 token 返回给客户端。 b客户端…...

数字孪生智慧机场:透视数字化时代下的航空运营

在《智慧民航建设路线图》文件中&#xff0c;民航局明确指出&#xff0c;智慧机场是实现智慧民航的四个核心抓手之一。这一战略性举措旨在推进数字化技术与航空产业的深度融合&#xff0c;为旅客提供更加智能化、便捷化、安全化的出行服务&#xff0c;进一步提升我国民航发展的…...

爱用建站平台/网络域名

给div&#xff1a;background:rgba(190,190,190,0.5);...

邯郸做企业网站设计的公司/google广告

功能1.支持行情图左右滑动2.支持行情图的惯性滑动3.支持行情图的方法和缩小4.支持 BOLL 和 MACD 技术指标(后面会继续丰富指标)5.支持主图副图动态添加&#xff0c;尺寸修改等6.支持长按滑动和长按弹框等效果图项目关键类行情图容器&#xff1a;MarketFigureChart行情图主图&am…...

做医院网站公司/线上销售平台如何推广

单播&#xff1a;单播MAC地址是从源到目的的唯一地址。 广播&#xff1a;就是一个主机向所有主机发送一个数据包。 组播&#xff1a;就是把数据发送给一组主机或者发送给感兴趣的主机。&#xff08;组播的MAC地址是以&#xff1a;01-00-5E开头的&#xff0c;组播的IP地址224.0.…...

天河区住房和建设水务局官方网站/关联词有哪些小学

整体架构图 Okhttp可以分为上层应用接口层&#xff0c;协议层&#xff0c;连接层&#xff0c;缓存层&#xff0c;I/O层&#xff0c;拦截器层。接口层就是我们上层开发人员调用的一些接口和API。连接层是核心&#xff0c;连接池以及网络请求优化都在这里面了。拦截器和缓存层是…...

wordpress 面包屑导航修改/搜索引擎营销sem包括

mysql-cluster的问题棘手发布时间:2009-12-01 15:56:29来源:红联作者:skyuun我搭建了一个3台服务器所做的mysql-cluster集群集群版本是7.09G 操作系统是RH-5.2-32使用的是RPM包安装方式服务器为 MySQL-Cluster-gpl-server和MySQL-Cluster-gpl-client和MySQL-Cluster-gpl-storag…...

wordpress加速/惠州抖音seo策划

springmvc 支持ant风格的路径表达式&#xff0c;我们先了解一下ant风格是什么个东东&#xff1f; ant匹配url有三种 ? 匹配任何单字符   * 匹配0或者任意数量的字符  ** 匹配0或者更多的目录 1.&#xff1f;只匹配一个字符&#xff0c;比如说/springmvc/?abc/index.jsp …...