汉诺塔问题—C语言实现

一、题目描述

相传在古印度圣庙中,有一种被称为汉诺塔(Hanoi)的游戏。该游戏是在一块铜板装置上,有三根杆(编号A、B、C),在A杆自下而上、由大到小按顺序放置64个金盘(如下图)。游戏的目标:把A杆上的金盘全部移到C杆上,并仍保持原有顺序叠好。操作规则:每次只能移动一个盘子,并且在移动过程中三根杆上都始终保持大盘在下,小盘在上,操作过程中盘子可以置于A、B、C任一杆上上。(摘自360百科)

二、求解思路

1、看到这个问题,我们可以总结出三点有用的信息 a.只能移动最顶端的盘子 b.一次只能移动一个盘子 c.移动过程一定保持大圆盘在下小圆盘在上

2、共有A、B、C三个杆子 如果只有一个盘子,直接将目标盘子从A<--->C 如果有两个盘子,将1从A<--->B,将2从A<--->C 如果是三个盘子呢??经过思考我们不难得出第1步将A<----->C,第2步将A<----->B,第3步将C<----->B,第4步将A<----->C,第5步将B<----->A,第6步将B<----->C,第7步将A<----->C

从这里我们好像看到了递归的影子,递归的思想就是“将大事化小”,我们移动三个盘子的时候,是以C为媒介将1,2两个盘子移到B上,再将3号盘子由A移向C。所以我们每次只要分离出最大的盘子,再将最大的盘子移动到目标杆。

假如有n个盘子,我们应该把n-1个盘子移走,那么如何做呢?我们应该把以C为过渡柱将n-1个盘子暂时放在B柱子上,再将第n个盘子从A<---->C,接下来又是同样的算法,暂存在B柱子上的n-1个盘子以C柱为媒介暂存n-2个盘子在A柱子上,再将B柱子上的最大的盘子移动到C柱子上。

递归的两个条件:

①限制条件:n=1时不再递归

②每次移动时当前最大的盘子已经移到目标杆子上去了,数量就减一,越来越接近这个限制条件

三、附上代码

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int i = 0;
void move(int n, char from, char to)
{
	i++;
	printf("第%d步将%d号盘子%c<----->%c
",i, n, from, to);
}

Hanoi(int n, char A, char B, char C)
{
	if (n == 1)
	{
		move(n, A, C);
	}
	else
	{
		Hanoi(n - 1, A, C, B);
		move(n, A, C);
		Hanoi(n - 1, B, A, C);
	}
}

int main()
{
	int n = 0;
	scanf("%d", &n);
	Hanoi(n, A, B, C);
	printf("共%d步
", i);
	return 0; 
}

递归还是很晦涩,我只是讨论了前几种情况,寻找其中的规律。继续学习理解再来补充。如果写的有错误或者有什么建议可以告诉我谢谢,及时修正。。

(* ̄︶ ̄)

经验分享 程序员 微信小程序 职场和发展