提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
一、汉诺塔是什么
汉诺塔(Tower of Hanoi),又称河内塔,是一个源于印度古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。
二、注意事项
- 初始条件: A 柱上有 64 个盘子, 盘子大小不等, 小盘在上,大盘在下。
- 完成目标:将 A 柱上的盘子最终全部移动到 C 柱。
- 限制条件:每次只允许移动 1 个盘子, 并始终保持小盘在上,大盘在下。
三、初步分析
为了方便理解, 讨论以下情形:
-
disk = 1 时,
(1)将 A 柱上的圆盘移动到C柱上即可,可标记为 A -->C -
disk = 2 时,
2.1 将 A 柱上的1个盘子移动到 B 柱,可标记为 A --> B2.2 将 A 柱上的最后一个圆盘,从 A 柱移动到 C 柱,可标记为 A–> C
2.3 将 B 柱上的圆盘,从 B 柱移动到 C 柱,可标记为 B–>C
-
disk = 3 时,
3.1 将 A 柱的 2 个盘子借助 C 柱通过一些变换可移动到 B 柱,可标记为 A --> B
3.2 将 A 柱剩余的最后 1 个盘子,从 A 柱移动到 C 柱,可标记为 A–> C
3.3 将 B 柱上 2个圆盘,通过一些变换借助 A 柱,可从 B 柱移动到 C 柱,可标记为 B–>C
以此类推,若有 n 个盘子,可先将除最后一个盘子以外的其他 n - 1 个盘子从 A 柱通过借助 C 柱达到全部放在 B 柱的目的,然后将第 n 个盘子(即最大的盘子)从 A 柱放在 C 柱,再将 B 柱上剩余的 n - 1 个盘子从 B 柱 通过借助 A 柱,最终达到放在 C 柱的目的
提示:1.由于当 A 柱只有一个盘子时,可直接放在 C 柱,因此可作为递归程序的出口
hanoi(int num , a, b, c)
num:盘子的数量
a,b,c可理解为从a经由b到达c
代码实现
#include <stdio.h>
/*
* 汉诺塔问题
*/
void move(char a, char c) {
printf("%c -> %c\n", a, c);
}
void hanoi(int num, char a, char b, char c) {
// 递归出口就是当只有一个人盘子的时候,直接移动即可
if (num == 1) {
move(a, c);
} else {
//若有 num 个盘子,只需要将 num - 1 个盘子从 A 柱通过 C 柱放在 B 柱
hanoi(num - 1, a, c, b);
//然后将第 num 个盘子(即最大的盘子)从 A 柱放在 C 柱即可
move(a, c);
// 将 num - 1 个盘子从 B 柱 通过 A 柱放在 C柱即可
hanoi(num - 1, b, a, c);
}
}
int main() {
int num;
// A, B, C 代表三个柱子
char a = 'A';
char b = 'B';
char c = 'C';
printf("please input the number of diskes: ");
// num 表示输入盘子的数量
scanf("%d", &num);
hanoi(num, a, b, c);
return 0;
}
如果想要统计具体步骤的次数,设置一个变量,每次移动加1即可