递归简介
什么是递归?递归=递推+回归,类似于数学归纳法,属于分治法的应用,是数学与计算科学领域的重要思想,在离散数学、数据结构中起到了重要基础作用,是处理与问题规模无关、结构自相似性问题的必需工具。
不要对递归感到恐惧,应该把递归当做工具而非累赘。如果实在难以理解,请先复习高中学习的数学归纳法,并善用VSCode、CLion的并行堆栈和并行监视功能,这些工具都有利于学习递归。
题目描述
有3个柱子,分别为from,buffer,to;最初from柱上有N个盘子,且小盘必须只能放在大盘上,反向则不可以。注意from,buffer,to的角色是相对而言的。
若N=1,则直接将盘子从from移动到to上。(递归基)
若N!=1:
1.则将N-1个盘子先看成一个整体,目的是将N-1个盘子借助to柱移动到buffer柱上。由于柱子的角色是相对而言的,所以此时在此过程中,from柱不变,buffer柱为原to柱,to柱为原buffer柱。
2.现在已将放在第N个盘子上的N-1个盘子全部转移到buffer柱上(相对于整体目标而言),等效于回到了N=1的情况,直接将第N个盘子从from柱上移动到to柱上。
3.现在需要将在buffer柱上的N-1个盘子借助from柱移动到to柱上。同理,柱子的角色是相对而言的,在此过程中,原buffer柱变为from柱,原from柱变为buffer柱,原to柱不变。
在N-1的时候函数在不断调用自己,每次都在等待上一次操作完毕(第N个盘子在等待第N-1个盘子移动完毕,第N-1个盘子又在等待第N-2个盘子移动完毕....),这是很经典的递归思想的问题。
切记递归思想只能通过找规律实现,穷举(暴力)通常是不可行的。
代码实现
#include <stdio.h>
void Hanio(int n, char from, char buffer, char to) {
if (n == 1) {
printf("%d:%c -> %c\n", n, from, to); // 输出移动步骤
} else {
Hanio(n - 1, from, to, buffer); // 将 n-1 个圆片从 from 经由 to 移到 buffer
printf("%d:%c -> %c\n", n, from, to); // 输出移动步骤
Hanio(n - 1, buffer, from, to);// 将 n-1 个圆片从 buffer 经由 from 移到 to
}
}
int main() {
int n;
char from, to, buffer;
/*数量、ori、goal、buffer:*/
scanf("%d %c %c %c", &n, &from, &to, &buffer);// 输入汉诺塔的圆片数量和起始、目的、过渡柱
Hanio(n, from, buffer, to);// 调用汉诺塔函数
return 0;
}