数据结构学习(C语言)-递归(汉诺塔实例)
一、预备知识
1、什么是递归
递归就是一个函数自己可以直接或间接调用自己。
2、递归的条件
1.递归必须得有一个明确的终止条件;
2.该函数所处理的数据规模必须在递减;
3.这个转化必须是可解的。
3、递归和循环的比较
递归:易于理解,速度慢,存储空间大;
循环:不易理解,速度快,存储空间小。
二、递归实现汉诺塔
1、什么是汉诺塔
题目背景:相传上帝创造世界的时候做了三个金刚石柱子,在一根柱子上从上往下按大小(大小都不一样)顺序摞着64片黄金圆盘。上帝命令婆罗门把圆盘按大小顺序重新摞到另一个柱子上,要求每次只能移动一个圆盘,在小圆盘上不能放置比它大的圆盘。
当n=1时
当n=2时
2、要素分析
通过题目介绍以及两个最简单的汉诺塔实例不难看出,我们要解决汉诺塔问题,至少需要四个参数:盘子个数n,三根柱子A、B和C。
3、递归思想和伪算法
递归思想
递归实际就是将一个复杂的问题一步步化简为更简单的问题。假如此时在A柱子上有n(n>1)个盘子(由上至下编号1,2,…,n),由递归的思想我们可以将这摞盘子看做两部分,第一部分是最下面的n号盘子(最大的),第二部分是上面的n-1个盘子一起。此时思路就是跟只有两个盘子是一样的,我们要做的是把第二部分先放在B柱子上(同时借助C柱子经过多次移动),然后第一部分(即n号盘子)就可以顺利移动到C柱子(目标柱子)上。而此时的情况是:A柱子上是空的,B柱子上有暂存的n-1个盘子,C柱子上得到了最大的盘子,现在我们算是完成第一轮递归,并且现在的情形和初始时很像,只是A和B柱子的身份发生了改变。然后我们对B柱子上的n-1个盘子再次进行一轮递归,得到的结果将是:A柱子上有暂存的n-2各盘子,B柱子是空的,C柱子上一共有两个最大的盘子了(n号和n-1号)。经过多次递归,最终在A柱子或B柱子上剩下最后一个盘子(即1号),当只有一个盘子时,就可以直接移动到C柱子,最终问题得到解决。
伪算法
if n==1
直接把盘子移到C柱子上;
if n>1
把A柱子上的前n-1个盘子借助C柱子移动到B柱子上;
把A柱子上n号盘子直接移到C柱子上;
问题转化为将B柱子上的n-1个盘子移到C柱子上。
4、汉诺塔实例实现
1 代码:
#include<stdio.h>
void Hanoi(int n, char A, char B, char C) {
if (n == 1)
printf_s("直接把%d号盘子从%c柱子移到%c柱子上 \n",n,A,C);
else {
Hanoi(n - 1, A, C, B);
printf_s("直接把%d号盘子从%c柱子移到%c柱子上 \n", n, A, C);
Hanoi(n - 1, B, A, C);
}
return;
}
int main(void) {
int n;
char A='A';//柱子A(初始盘子所在)
char B='B';//柱子B(辅助)
char C='C';//柱子C(目标柱子)
printf_s("请输入盘子的数目:\n");
scanf_s("%d", &n);
Hanoi(n, A, B, C);
return 0;
}
2 运行结果:
3 结果验证:
可以找一个汉诺塔小游戏进行验证是否正确。
点击这里进入7k7k汉诺塔小游戏进行结果验证