CSDN话题挑战赛第2期
参赛话题:学习笔记

前言
作者龟龟不断向前
简介宁愿做一只不停跑的慢乌龟,也不想当一只三分钟热度的兔子。
专栏:C++初阶知识点

工具分享

  1. 刷题: 牛客网 leetcode
  2. 笔记软件:有道云笔记
  3. 画图软件:Xmind(思维导图) diagrams(流程图)

如果觉得文章对你有帮助的话,还请点赞,关注,收藏支持博主,如有不足还请指点,博主及时改正

文章目标:

  • 汉诺塔的规则
  • 分析汉诺塔的逻辑
  • 汉诺塔的代码实现
  • 汉诺塔的移动次数–宇宙毁灭

汉诺塔问题

汉诺塔背景/规则

汉诺塔问题源自印度一个古老的传说,印度教的“创造之神”梵天创造世界时做了 3 根金刚石柱,其中的一根柱子上按照从小到大的顺序摞着 64 个黄金圆盘。梵天命令一个叫婆罗门的门徒将所有的圆盘移动到另一个柱子上,移动过程中必须遵守以下规则:

  • 每次只能移动柱子最顶端的一个圆盘;
  • 每个柱子上,小圆盘永远要位于大圆盘之上;

汉诺塔问题,实际上也是一个递归问题(没学习递归的同学,可以点击链接学习)

汉诺塔解法

动画讲解递归思路

我们从圆盘个数上,从少到多,来分析一下解决方法,一下我们用n来表示圆盘个数

我们用A B C或者起始柱 辅助柱 目标柱 来表示柱子

n = 1时

n = 2

n = 3

这里并不是步遵守游戏规则,一次将两个圆盘从A般到B,而是两个圆盘的情况已经在n = 2的时候演示了

n = 4

同样的,3层的哈诺塔也已经在n = 3的时候演示。

类推:无论多少个圆盘,就能给他分解成三步,就类似于把大象装进冰箱

即无论有多少个圆盘,都可以按三步进行分解。

递归思路:有n个圆盘需要从A(起始柱)移到C(目标柱),借助B(辅助柱)

可以分解陈有n -1圆盘从A移动到B,底盘从A移动到C,n-1个圆盘从B移动到C

特别注意,进行多圆盘移动的时候,是需要辅助柱的

代码实现汉诺塔

void Hanoi(char a,char b,char c,int n){if (n == 0)//圆盘数为0,直接返回,递归的限制条件{return;}//1.将n-1个圆盘,从a移动到bHanoi(a, c, b, n - 1);//2.将1个圆盘,从a移动到cprintf("%c -> %c\n", a, c);//3.将n-1个圆盘,从b移动到cHanoi(b, a, c, n - 1);}int main(){int num = 0;printf("请输入圆盘个数\n");//有 A B C三个支柱scanf("%d", &num);Hanoi('A', 'B', 'C', num);//第一个参数是:起始柱//第三个参数是:目标柱//第二个参数是:辅助柱//第四个参数:圆盘的个数return 0;}

递归的优缺点

优点:

非常明显,这种大事化小的思维方式,可以大大缩减我们的代码量,便于理解理解整体逻辑

缺点:

  1. 与现实生活的思维方式相差较大,不容易想
  2. 递归程度太深会造成栈溢出(例如死递归)
  3. 部分题目用递归实现特别低效(例如斐波那契)

64层汉诺塔等于宇宙毁灭?

已经有人开玩笑说:等你把64层汉诺塔解完,宇宙的毁灭了。

其实这也是可能的,前提是那个人是一个永生的人。

百度百科上面查询到,28亿宇宙将灭亡,咱们也不是什么大科学家,姑且不谈其真假性,我们来计算一下人解完64层需要花多少时间。

首先我们计算一下n层汉诺塔,需要移动圆盘多少次?

咱们使用上面的程序来找找规律,当然如果你是一个数学大佬,也可以使用数学知识来计算。

n = 3–7次

n = 4–15次

![在这里插入图片描述]

找规律我们不难发现,n层汉诺塔需要移动圆盘 2的n次方减1次,如果说64层汉诺塔

那就需要移动圆盘2^64 – 1次,即1844.67亿亿

如果一个人移动一次圆盘需要1秒钟,也需要1844.67亿亿秒,很明显,宇宙大人早就去世了。

  假如你对你的校园女神表白了,而你的女神说等你解完64层汉诺塔就嫁给你,那…………这肯定是一个悲伤的故事

建议兄弟回家打开网易云。

  OK,咱们折起就讲到这里,希望大家能够听懂汉诺塔问题,咱们下期见!