汉诺塔(Tower of Hanoi),又称河内塔,是一个源于印度古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。(ps:复制粘贴,引用自百度百科)
分析问题:假设有n层塔(对其进行编号为1,2,3....n),并且对三根柱子进行编号为a,b,c。如果要把其全部从a移动到c,那么如果把上面的n-1层作为整体来看,我们只需把上面的n-1层移动到b,然后第n层移动到c,再把n-1层移动到c即可。
如果想把n-1层从a移动到b(a->b)需要先把n-2层从a移动到c(a->c),再把第n-1层从a移动到b,最后把n-2层从c移b(c->b)。
如果想把n-2层从c移动到b(c->b)需要先把n-3层从c移到a(c->a),再把第n-2层从c移动到b,最后把n-3层从a移b(a->b)。
后面再分析就会进入循环;
如果想把n-1层从b移动到c(b->c)需要先把n-2层从b移动到a(b->a),再把第n-1层从b移动到c,最后把n-2层从a移c(a->c)。
如果想把n-2层从a移动到c(a->c)需要先把n-3层从a移动到b(a->b),再把第n-2层从a移动到c,最后把n-3层从b移到c(b->c)。
后面分析同上,也会进入循环;
因此总共有6个不同的步骤,(a->b;a->c;c->b;c->a;b->c;b->a)这六个不同的步骤进行组合迭代得到结果。
下面进行C语言代码实现。
输入为汉诺塔的层数。输入为每一层要移动到哪个柱子。
#include<stdio.h>//汉诺塔的步骤
void tower1(int x, char c1, char c2, char c3);
void tower2(int x, char c1, char c2, char c3);
void tower3(int x, char c1, char c2, char c3);
void tower4(int x, char c1, char c2, char c3);
void tower5(int x, char c1, char c2, char c3);
void tower6(int x, char c1, char c2, char c3);
void tower1(int x, char c1, char c2, char c3)//c1->c2
{
if (x >= 1)
{
tower3(x - 1, c1, c2, c3);
printf("%d->%c\n", x, c2);
tower4(x - 1, c1, c2, c3);
}
}
void tower2(int x, char c1, char c2, char c3)//c2->c3
{
if (x >= 1)
{
tower5(x - 1, c1, c2, c3);
printf("%d->%c\n", x, c3);
tower3(x - 1, c1, c2, c3);
}
}
void tower3(int x, char c1, char c2, char c3)//c1->c3
{
if (x >= 1)
{
tower1(x - 1, c1, c2, c3);
printf("%d->%c\n", x, c3);
tower2(x - 1, c1, c2, c3);
}
}
void tower4(int x, char c1, char c2, char c3)//c3->c2
{
if (x >= 1)
{
tower6(x - 1, c1, c2, c3);
printf("%d->%c\n", x, c2);
tower1(x - 1, c1, c2, c3);
}
}
void tower5(int x, char c1, char c2, char c3)//c2->c1
{
if (x >= 1)
{
tower2(x - 1, c1, c2, c3);
printf("%d->%c\n", x, c1);
tower6(x - 1, c1, c2, c3);
}
}
void tower6(int x, char c1, char c2, char c3)//c3->c1
{
if (x >= 1)
{
tower4(x - 1, c1, c2, c3);
printf("%d->%c\n", x, c1);
tower5(x - 1, c1, c2, c3);
}
}
void tower(int x, char c1, char c2, char c3)//c1->c3
{
if (x >= 1)
{
tower1(x - 1, c1, c2, c3);
printf("%d->%c\n",x,c3);
tower2(x - 1, c1, c2, c3);
}
}
int main()
{
char part1='a', part2='b', part3='c';
int n = 0;
printf("请输入汉诺塔的高度:");
scanf_s("%d", &n);
printf("移动汉诺塔的步骤:\n");
tower(n, part1, part2, part3);
return 0;
}
运行结果展示:
运行结果正确。
(ps:代码完成以后,在CSDN上有大致看了看其他的代码,发现大家的输入结果都是从一个柱子移动到另外一个柱子,并且代码很短。我这代码实现有点长了。目前我没有想到更简洁的方法。很开心的一点是,这次写的代码,一次通过了,没有调试。如有更简便的方法,恳请指教。这是第一次写C语言的博文,以后回过头来再看这篇博文肯定漏洞百出,hh。)