汉诺塔——递归算法(c语言实现)

每日一题

 

 


汉诺塔 问题 :

 

     1.有三根杆(编号A、B、C)
     2. 在A杆自下而上、由大到小按顺序放置n个金盘
     3.把A杆上的金盘全部移到C杆上,并仍保持原有顺序叠好。

操作规则:每次只能移动一个盘子,并且在移动过程中三根杆上都始终保持大盘在下,
小盘在上,操作过程中盘子可以置于A、B、C任一杆上。

a665619da214449cb465650169878618.png


 

提示:以下是本篇文章正文内容,下面案例可供参考

一、递归算法

递归算法是算法中很常用的一种方法,是一种逆行思维,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。

大事化小,由小引大。

通俗的讲:就是找规律(类似数学归纳法)

二、解决汉诺塔问题

1.找规律,确定思路


(1)  当 n = 3 时   (详细步骤)

0.            A(1.2.3),B(),    C()

1.A->C     A(2.3),  B(),    C(1)

2.A->B     A(3),    B(2),   C(1)

3.C->B     A(3),    B(1.2), C()

4.A->C     A(),      B(1.2), C(3)

5.B->A     A(1),    B(2),    C(3)

6.B->C     A(1),    B(),      C(2.3)

7.A->C     A(),      B(),      C(1.2.3)

 

可以发现:可分为两步 1~~~4和4~~7

所以总结可得:

汉诺塔解题步骤:

第一步:

                  把 n-1 个模块从塔 1 移动到塔 2
                  把第 n 个模块从塔 1 移动到塔 3
第二步:
                  把 n-1 个模块从塔 2 移动到塔 3

 所以求 n = 4 时

如下:

3d7163bf99d04d15b199ffd2297ef812.png

 

 

2.代码实现

代码如下(示例):

 

#include <stdio.h>
int count;
void move(char A, char C, int n)
{
	printf("把第%d个圆盘从%c->%c\n", n, A, C);
	count++;
}

void Hanno(char A, char B, char C, int n)
{
	if (n == 1)
	{
		move(A, C, n);
	}
	else
	{
		//将n-1个圆盘从A柱借助于C柱移动到B柱上
		Hanno(A, C, B, n - 1);
		//将A柱子最后一个圆盘移动到C柱上
		move(A, C, n);
		//将n-1个圆盘从B柱借助于A柱移动到C柱上
		Hanno(B, A, C, n - 1);
	}
}

int main()
{
	int n = 0;
	printf("输入A柱子上的圆盘个数:");
	scanf("%d", &n);
	//将n个圆盘从A柱借助于B柱移动到C柱上
	Hanno('A', 'B', 'C', n);
	printf("一共移动了%d次圆盘",count);
	return 0;
}

运行结果 

输入A柱子上的圆盘个数:3
把第1个圆盘从A--->C
把第2个圆盘从A--->B
把第1个圆盘从C--->B
把第3个圆盘从A--->C
把第1个圆盘从B--->A
把第2个圆盘从B--->C
把第1个圆盘从A--->C
一共移动了7次圆盘
--------------------------------

 输入A柱子上的圆盘个数:4
把第1个圆盘从A--->B
把第2个圆盘从A--->C
把第1个圆盘从B--->C
把第3个圆盘从A--->B
把第1个圆盘从C--->A
把第2个圆盘从C--->B
把第1个圆盘从A--->B
把第4个圆盘从A--->C
把第1个圆盘从B--->C
把第2个圆盘从B--->A
把第1个圆盘从C--->A
把第3个圆盘从B--->C
把第1个圆盘从A--->B
把第2个圆盘从A--->C
把第1个圆盘从B--->C
一共移动了15次圆盘


总结

真的很难,自己总结一下,方便自己看也分享给各位

 

 

  • 32
    点赞
  • 126
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值