递归专题(1)——汉诺塔

🔥近津薪荼:个人主页

🎬个人专栏:《c语言基础知识详解》《c++基础知识详解》《Linux操作系统及网络基础知识分享》《近津薪荼的算法日迹》

人不可以逃避困难,亦不可以放弃希望。

------《病隙碎笔》


1.本期知识点导图

2.上期参考代码:

本期,我们开始学习递归专题,为bfs专题做铺垫

3.本期要讲解的题目是:

汉诺塔问题

要点:

  • 一次动一个
  • 小的在上大的在下
  • 先进后出(栈)

4.解题

我们拿到一个新题,不会一下子就能想到使用递归的方法来解决,得有一个分析的过程,这个过程是最重要的,知道该使用递归解题之后,代码的书写反而非常简单。

不知道大家小时候有没有玩过汉诺塔玩具,像这种:

我们现在就来模拟一下玩玩具的过程,来寻找解题的方法。正常小朋友玩的都是5层以上的,3层对他们来说可能有点幼稚但是对大学生来说刚刚好,我们就模拟一下1到3层的叭。

4.1模拟:

通过模拟我们可以总结出汉诺塔移动的三步走规律:

  • 第一步:把a柱的前n-1个盘子,借助于c柱,放到b柱上
  • 第二步:把a柱剩下来的一个盘子放到c柱上**(无需借助)**
  • 第三步:把b柱的n-1个盘子借助于a,放到c柱上

其中第二步很好理解,n=1的时候,只需要第二步即可,无需借空柱(最底层的操作)

最后我们将会发现,只有无需借助空柱的,才是真干活的

第一第三步我们来看n=2和n=3

  • n=2的时候
  1. 先把第1个盘子放到b上
  2. 然后把a的最后一个盘子放到c
  3. 再把b放到c

这里就需要借助b才能完成任务了

  • 我们再来看n=3
  1. 我们要想办法把a柱上的n-1,也就是上边两个盘子放到b上
  2. 然后把a最后一个盘子放c上
  3. 最后再想办法把b上的两个盘子放c上

第一步和第三步都需要借助第三个闲着的柱子

4.2那我们总结一下,我们要解决的问题是:

借助b柱,将a柱的n个盘子转移到c柱上

具体怎么做:

  • 第一步:把a柱的前n-1个盘子,借助于c柱,放到b柱上
  • 第二步:把a柱剩下来的一个盘子放到c柱上
  • 第三步:把b柱的n-1个盘子借助于a,放到c柱上

聚焦于第一步(子问题),我们又需要

第一步:借助b柱,把n-2个盘子放到c上......

一直向前递推,直到n=1,无需借助空柱。

4.3至此,递归的逻辑就跃然纸上了:

将移动n个盘子,转化成移动n-1个盘子的子问题,一直往前递推,直至n=1时开始递归

5代码逻辑:

要写好一个递归的代码,最重要的是:

**1.找到重复子问题,写函数头:**借助空柱,挪动盘子

**2.关心子问题具体需要做什么,写函数体:**上边讲的三步走

**3.找到递归的出口,不能死循环:**递推到n=1开始递归

递归,把上边三个基本问题解决好,就没问题了,把一个个子问题当成" 黑盒 ",就像函数中的对应法则f一样,虽然这么说有点神秘,但是你要相信照这样写出来的递归能帮你解决问题,具体怎么解决的,别管,为什么答案是对的,因为我们的逻辑是对滴!

要是实在想知道细节,可以自己画个递归图看看。(但是不要死磕,记住,递归一定是在宏观的角度去学的)

画递推图还是挺麻烦的,由于这是递归的第一道题,我给大家简单画了一个3层汉诺塔,以后不会再画咯

递归的过程图

黑线是递推过程,蓝线是递归过程

下期要讲解的题目是:

合并两个有序链表

下期见:

相关推荐
张李浩15 分钟前
Leetcode 054螺旋矩阵 采用方向数组解决
算法·leetcode·矩阵
big_rabbit050229 分钟前
[算法][力扣101]对称二叉树
数据结构·算法·leetcode
red_redemption30 分钟前
自由学习记录(135)
学习
美好的事情能不能发生在我身上1 小时前
Hot100中的:贪心专题
java·数据结构·算法
myloveasuka1 小时前
Java与C++多态访问成员变量/方法 对比
java·开发语言·c++
2301_821700531 小时前
C++编译期多态实现
开发语言·c++·算法
奥地利落榜美术生灬1 小时前
c++ 锁相关(mutex 等)
开发语言·c++
xixihaha13241 小时前
C++与FPGA协同设计
开发语言·c++·算法
小小怪7502 小时前
C++中的函数式编程
开发语言·c++·算法
金山几座2 小时前
C#学习记录-事件
开发语言·学习·c#