本期介绍🍖
主要介绍:汉诺塔是什么,汉诺塔的规律,如何用C语言来实现汉诺塔👀。
1. 什么是汉诺塔
汉诺塔(Tower of Hanoi),又称河内塔。源自印度古老传说的一个游戏,大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。
若每次移动需要1s的时间,那么请问婆罗门需要多久才能把这64片黄金圆盘从一根石柱上移动到另一个石柱上?
若只有1个圆盘时,需要移动1次;若有2个圆盘时,需要移动3次;若有3个圆盘时,需要移动7次……不难看出,汉诺塔步数的数学规律为2的n次方减1(n为柱子上的圆盘个数)。所以若有64个圆盘那将会移动2^64-1次(即:18,446,744,073,709,551,615次),若每次移动需要1s时间,则需要将近5849亿年的时间才能够做到。可见大梵天有多恨婆罗门,这绝对是在坑人啊!!!
2. 游戏规则
假设有A、B、C三根柱子,其中A柱上有n个圆盘,这些圆盘从上至下越来越大,最终要实现把这n个圆盘从A柱借助B柱移动到C柱上。移动规则如下:
- 每次只能移动1个圆盘
- 移动过程中大的圆盘不能放在小的圆盘上面
- 在移动的过程中圆盘可以放置在任意一根柱子上
题目:要求用递归实现汉诺塔,打印圆盘每一次的移动。
3. 递归实现汉诺塔
举例分析:
1.汉诺塔有1个圆盘
移动步骤:A->C
2.汉诺塔有2个圆盘
移动步骤:A->B A->C B->C
3.汉诺塔有3个圆盘
移动步骤:A->C A->B C->B A->C B->A B->C A->C
通过上面3个案例,会发现汉诺塔的移动一定离不开这三个步骤:
- 将(n-1)个圆盘从A柱(起始位置)移动到B柱(借助位置)
- 将A柱(起始位置)上剩余的最后一个圆盘移动到C柱(目的位置)
- 将B柱(借助位置)上的(n-1)个圆盘移动到C柱(目的位置)
假设现在A柱上拥有n个圆盘,需要将这n个圆盘借助B柱,移动到C柱上。解题思路:可以将(n-1)个圆盘从A柱移动到B柱上,然后将A柱上最后一个圆盘移动到C柱上,最后再把B柱上的(n-1)个圆盘移动到C柱上。这样就把移动n个圆盘的问题,转化为了移动(n-1)和(n-2)个圆盘的问题,如下图所示。这样一层层的递推,直到问题转化为了移动1个圆盘,从(起始位置)移动到(目的位置)。
#include<stdio.h>
void move(char A, char C, int n)
{
printf("把第%d个圆盘从%c--->%c\n", n, A, C);
}
void HanoiTower(char A, char B, char C, int n)
{
if (n == 1)
{
move(A, C, n);
}
else
{
//将n-1个圆盘从A柱借助于C柱移动到B柱上
HanoiTower(A, C, B, n - 1);
//将A柱子最后一个圆盘移动到C柱上
move(A, C, n);
//将n-1个圆盘从B柱借助于A柱移动到C柱上
HanoiTower(B, A, C, n - 1);
}
}
int main()
{
int n = 0;
printf("输入A柱子上的圆盘个数:");
scanf("%d", &n);
//将n个圆盘从A柱借助于B柱移动到C柱上
HanoiTower('A', 'B', 'C', n);
return 0;
}
若想知道一共移动了多少次圆盘,只需要在move()函数中加一个全局变量来统计个数就行。
这份博客👍如果对你有帮助,给博主一个免费的点赞以示鼓励欢迎各位🔎点赞👍评论收藏⭐️,谢谢!!!
如果有什么疑问或不同的见解,欢迎评论区留言欧👀。