2021-09-14

数据结构学习(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汉诺塔小游戏进行结果验证

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Evekkan

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值