关于汉诺塔问题

首先,我们要了解什么是汉诺塔问题。

汉诺塔问题源于古印度的一种游戏,而这种游戏是指在一块铜板装置上,有三根杆(编号A、B、C),在A杆自下而上、由大到小按顺序放置64个金盘。而我们游戏的目标则是:把A杆上的金盘全部移到C杆上,并仍保持原有顺序叠好。

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

如图所示:

关于汉诺塔问题_第1张图片

64个金盘数量太多,我们可以先从1个金盘开始研究。

如果A柱上只有一个金盘,那我们的移动顺序应该是:A ——> C。移动了1次。

如果A柱上有两个金盘,我们的移动顺序是:A ——>B , A ——>C , B——>C。移动了3次。

如果A柱上有三个金盘,我们的移动顺序是:A——>C , A——>B , C——>B , A——>C , B——>A , B——>C , A——>C。移动了7次。

由此我们可以得知,如果存在64个盘子,我们需要移动的次数是2的64次方减1。这是一个极大的数字,同时使用计算机计算也是占据了极大的时间。所以,研究这个问题,我们可以采取,递归的方法。

如果存在n个金盘,那么,存在的普遍规律是:要先将n-1个金盘放在B上面,再将最后一个金盘放在C上面

如果n==1,那么这个金盘就直接放到C柱上面。如果n!=1,那么将这些!=1的金盘先转移到B柱上面去。

所以存在以下代码:

#define _CRT_SECURE_NO_WARNINGS 1
#include
//汉诺塔问题
//pos1:起始位置
//pos2:中转位置
//pos3:目的位置
//n:盘子的个数
void move(char pos1, char pos2)
{
	printf("%c—>%c  ", pos1, pos2);//打印盘子的移动方式

}
void Hannouta(int n, char pos1, char pos2, char pos3)
{
	if (n == 1)
	{
		move(pos1, pos3);
	}
	else
	{
		Hannouta(n - 1, pos1, pos3,pos2);
		move(pos1, pos3);
		Hannouta(n - 1, pos2, pos1, pos3);
	}
}
int main()
{
	int n = 0;
	scanf("%d", &n);
	Hannouta(n, 'A', 'B', 'C');
	printf("\n");
	return 0;
}

其中,Hannouta是汉诺塔问题的解决函数,move是打印汉诺塔问题中盘子的移动方式的函数。

在代码中 pos1代表起始位置 pos2代表中转位置 pos3代表目的位置  n则是盘子的个数。

在Hannouta函数中,我们首先判断盘子的个数是不是1,如果是1直接调用move函数,将其从A柱(pos1)转移到C柱(pos3)。如果,盘子的个数不是1,那么将其n-1个盘子再进行Hannouta函数(进行递归),同时,将这n-1个盘子从A柱(pos1)通过C柱(pos3)转移到中转柱B柱(pos2)上去。将这n-1个盘子转移完后,if语句成立执行move(pos1,pos3),执行完这段语句后,根据递归再开始执行else中的语句。

从而达成汉诺塔游戏的目的。

(以上内容基于本人自己的理解,若有看不懂的地方可以私信联系,本人将尽其所能的为各位读者讲解)

你可能感兴趣的:(初识C语言,c语言)