大家好,我是老郝。本文就汉诺塔问题向大家阐述递归的思想。
【问题描述】
有三根柱子,最左边的柱子上从大到小放着很多的圆盘,要求把圆盘一个一个的放到最右边的柱子上并且只能小盘子压在大盘子上。(据说古代阿三要他们的和尚把64个圆盘从左到右放一遍,看到最后你就知道阿三多么的无聊……)
![b32fec1f6d7b8c4af9c9d5493a2cba85.gif](https://i-blog.csdnimg.cn/blog_migrate/6e0e4ddc1d7b74a045a17e2c966b5933.gif)
这是4个盘子的示意
先用数学归纳法看一下移动盘子次数:
一个盘子 f(1) = 1
两个盘子 f(2) = 3
三个盘子 f(3) = 7
……
f(k+1)=2*f(k)+1 ===> f(n)=2^n-1
阿三每秒移动一个盘子而且不出错的情况下需要:
18446744073709551615秒 > 5845.54亿年
三哥无敌般存在!
不看三哥,看代码
![57675709ff6ec35b2998aeac4eb9d172.png](https://i-blog.csdnimg.cn/blog_migrate/296cca91be24e45afb12c3405be1d9d7.jpeg)
两个函数,show函数用来输出每次移动的结果;move函数为主递归函数用来求解,下面主要分析move函数。
每个递归函数都必须有退出的条件判断
这是递归算法必须具备的,否则就会出现无穷递归导致内存溢出。退出条件可以放在函数头部或者尾部,主要看设计者的思路了,一般情况下建议放在函数头部。
![a7952ff654b711ed42e420d8cc3355d3.png](https://i-blog.csdnimg.cn/blog_migrate/4f1ec5e3dc78af7eaf3b4859e25b36ac.jpeg)
退出递归的条件判断
函数自己调用自己实现递归
递归最大的特点就是函数自己调用自己,由于函数每次执行都是在内存中开辟新的空间,所以每次函数调用都不会丢失或者覆盖原来函数的值。
Move函数中将不同的局部变量作为入参传给调用的自身,直到n == 1为止。