版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Kwansy/article/details/78628940
阅读递归函数最容易的方法不是纠缠于它的执行过程,而是相信递归函数会顺利完成它的任务。如果你的每个步骤正确无误,你的限制条件设置正确,并且每次调用之后更接近限制条件,递归函数总是能够正确地完成任务。——《C和指针》
一、游戏规则
有三个塔,第一个塔上放了若干个盘子。要将这若干个盘子借助第二个塔移动到第三个塔上面。规则只有一个,大盘子必须在小盘子上面。
二、伪算法
定义一个函数,接收4个参数,分别是:盘子的个数、起始柱子、辅助柱子、目标柱子。
函数原型
void hanoi(int n, int src, int temp, int dst);
我们的hanoi
函数将一件事分解成三件小事,而这三件小事本质上和它本身做的工作是一样的。将 n 个盘子移动到另一根柱子,和将 n-1 个盘子移动到另一根柱子,没有任何区别。当n=1时,可以直接移动。
伪算法
如果只有一个盘子
直接移动到目标柱子
否则
将 n-1 个盘子移动到辅助柱子
将最后一个盘子移动到目标柱子
将 n-1 个盘子从辅助柱子移动到目标柱子
没了,就这么简单。根本不需要管 n-1 个盘子是怎么移动的,也不需要担心大盘子会跑到小盘子上面,递归函数帮我们做好了一切。
三、代码实现
#include <stdio.h>
// 第一个参数是盘子数、第二个参数是起始柱子、然后是辅助柱子、最后一个是目标柱子
void hanoi(int n, int src, int temp, int dst);
int main() {
// 借助第二根柱子,将3个盘子从第一根柱子移动到第三根柱子
hanoi(3, 1, 2, 3);
return 0;
}
void hanoi(int n, int src, int temp, int dst) {
if (n == 1) {
printf("%d -> %d\n", src, dst);
}
else {
// 请仔细观察参数的顺序
hanoi(n - 1, src, dst, temp);
hanoi(1, src, temp, dst);
hanoi(n - 1, temp, src, dst);
}
}
四、总结
递归的两个要素:一个是必须要有出口;另一个就是通过调用自己来简化问题,使每次递归后都更接近出口。
不要尝试跟踪递归的每一步,这样只会让问题变得复杂。