什么是汉诺塔
汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。
规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。
(图源网络)
举些栗子
只有一层汉诺塔圆盘时
当有2层汉诺塔圆盘时
游戏规则
每次只能移动一个长方形,并且大的长方形不能在小的长方形之上。
解题步骤
第一步:
把n-1个模块,从塔1移动到塔2
把第n个模块,从塔1移动到塔3
第二步:
把n-1个模块,从塔2移动到塔3
把汉诺塔n层看成两部分,分别为前n-1层和第n层。
当只有2层汉诺塔圆盘时,移动顺序为
A --> B;
A --> C;
B --> C;
所以我们得出游戏原理
原理
要解决n层汉诺塔
必须解决n-1层汉诺塔
…
必须解决1层汉诺塔(塔1—>塔3)
代码
根据以上信息,有如下代码
#include <stdio.h>
void Hanoi(int n, char A, char B, char C)
{
if (n == 1)
printf("塔%c --> 塔%c\n", A, C);
else
{
Hanoi(n - 1, A, C, B);
printf("塔%c --> 塔%c\n", A, C);
Hanoi(n - 1, B, A, C);
}
}
int main()
{
int n;
char A = 'A';
char B = 'B';
char C = 'C';
printf("请输入汉诺塔圆盘个数>:");
scanf("%d", &n);
Hanoi(n, A, B, C);
return 0;
}
优化后的代码
#include <stdio.h>
int cnt;
void Hanoi(int n, char A, char B, char C)
{
if (n == 1)
printf("step %d: 塔%c --> 塔%c\n", cnt++, A, C);
else
{
Hanoi(n - 1, A, C, B);
printf("step %d: 塔%c --> 塔%c\n", cnt++, A, C);
Hanoi(n - 1, B, A, C);
}
}
int main()
{
int n;
cnt = 1;
printf("请输入汉诺塔圆盘数量>:");
scanf("%d", &n);
Hanoi(n, 'A', 'B', 'C'); //圆盘数量 塔A, 塔B, 塔C
return 0;
}
注意,这里cnt是全局变量。
景禹解法
#include <stdio.h>
//第一要素:明确你这个函数想要干什么
// 函数功能:将 n 个盘子从 x 借助 y 移动到 z
void move(int n, char x, char y, char z)
{
//第二要素:寻找递归结束条件,当n=1时,直接将盘子从x移动到z
if( 1 == n )
{
printf("%c-->%c\n", x, z);
}
else
{
//第三要素:找出函数的等价关系式,并不考虑具体的移动过程,仅考虑完成任务
move(n-1, x, z, y); // 将 n-1 个盘子从x借助z移到y上
printf("%c-->%c\n", x, z);// 将第n个盘子从x移到z上
move(n-1, y, x, z); // 将 n-1 个盘子从y借助x移到z上
}
}
int main()
{
int n;
printf("请输入汉诺塔的层数: ");
scanf("%d", &n);
printf("移动的步骤如下: \n");
move(n, 'X', 'Y', 'Z');
return 0;
}