汉诺塔问题

文章详细阐述了如何使用递归算法解决汉诺塔问题,通过分解为移动n-1个圆盘、移动第n个圆盘以及再次移动n-1个圆盘到目标柱子这三个子问题。递归函数hanoi接受盘子数、源柱子、目标柱子和辅助柱子作为参数,当n=1时直接移动,否则递归调用自身。同时,文章指出了递归的时间复杂度为指数级别,以及在递归过程中涉及的空间复杂度问题。
摘要由CSDN通过智能技术生成
#include <stdio.h>
void move(char A, int n, char C)
{
	printf("%d,%c,%c\n", n, A, C);
}
void Hanoi(int n, char A, char B, char C)\\将n个圆盘从A柱移至C柱
{
	if (n == 1)
		move(A, 1, C);
	else
	{
		Hanoi(n - 1, A, C, B);\\将n-1个圆盘从A移至B,C为工具柱
		printf("The first A,B,C address is %ld %ld %ld\n", &A, &B, &C);
		move(A, n, C);\\将序号为n的圆盘从A移至C
		Hanoi(n - 1, B, A, C);\\将n-1个圆盘从B移至C,A为工具柱
		printf("The next A,B,C address is %ld %ld %ld\n", &A, &B, &C);
	}
}
int main()
{
	printf("The first test.\n");
	Hanoi(2, 'A', 'B', 'C');
	printf("The next test.\n");
	Hanoi(3, 'A', 'B', 'C');
	return 0;
}

想成整体问题,1.先移n-1,2.再移n,3.最后将n-1移到n上



自上向下:逐渐求精,函数调用,把大问题分解成小问题。
递归与分治:基础与归纳,把原问题分解成子问题,但仍与原来一样。
要跨层分析:向下考虑。

 


 递归实现汉诺塔问题(Hanoi):


定义了一个 hanoi() 函数,该函数有四个参数:将要移动的盘子数 paraN,源柱子 paraSource,目标柱子 paraDestination 和辅助移动的柱子 paraTransit。

如果盘子数为零,直接返回;
否则,先将 paraN-1 个盘子从源柱子移到辅助移动的柱子;
将第 paraN 个盘子从源柱子移到目标柱子,然后再将 paraN-1 个盘子从辅助移动的柱子移到目标柱子。
在移动每一个盘子时,都会打印一条提示信息,说明将它从哪个柱子移到哪个柱子printf("%c -> %c\r\n", paraSource, paraDestination);
 


分析

1.自顶向下,逐渐求精

这个问题可以分解为3个子问题,即将 n-1 个圆盘从源柱子移动到辅助移动的柱子,将第 n 个圆盘从源柱子移动到目标柱子,再将 n-1 个圆盘从辅助移动的柱子移动到目标柱子。由此不断向下细分下去。

2.函数调用、递归和分治

void hanoi(int paraN, char paraSource, char paraDestination, char paraTransit)

检查n的值:
如果n=1时,将圆盘直接从源柱子移动到目标柱子,
否则分为3个子问题,递归调用该函数

3.形参与实参

void hanoi(int paraN, char paraSource, char paraDestination, char paraTransit)

上面的函数里的参数都是形参,调用完了以后会释放。
实参是在调用时提供的具体数值

4.有意义、规范的标识符
使用有意义、规范的标识符可以使代码可读性更高,意义更加明确,更加专业。也是日后作为程序员的基本素养。

5.时间复杂度
移动次数表达式为2的n次方-1,时间复杂度也是指数级别的。这也是递归的一个缺点,即在调用层数过多时,时间复杂度会很高。

6.递归栈
递归和栈有着密不可分的关系。
在递归调用的过程中,每次调用都会将函数的参数、局部变量、返回地址等信息压入push函数调用栈中,当递归调用结束时,又会从栈中弹出pop这些信息,恢复到之前的调用状态。
递归是栈的一种应用场景,它常常被用于解决具有递归结构的问题。

7.空间复杂度
在递归调用的过程中,每次调用都会将函数的参数、局部变量、返回地址等信息压入push函数调用栈中,当递归调用结束时,又会从栈中弹出pop这些信息,所以递归栈的深度等于递归调用的层数,因此空间复杂度为 O(n)
 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值