https://mp.csdn.net/mp_blog/creation/editor/135856751?not_checkout=1
什么是汉诺塔?
汉诺塔起源于印度的一则古老传说。 法国数学家爱德华·卢卡斯曾编写过一个印度的传说。 在世界中心贝拿勒斯(传说在印度北部)的圣庙里,有一块插着三根宝石针的黄铜板。 印度教的主神梵天在创造世界时,从下到上地在一根宝石针上串上了由大到小的64片金片,这就是汉诺塔的雏形。
如图是一个汉诺塔,玩法就是将A(起点)柱子的三个圆盘通过B(辅助点)全部移到C(终点)的柱子上
规则:
每次只能移动一个圆盘。
每次只能移动最顶端的圆盘。
只能是小的叠在大的上面。
(情况1)我这里从简单的一个圆盘开始:
如图在A(起点)柱上只有一个圆盘,目的是移到C(终点)柱上面,方法是把盘子直接从A移到C去,这是最简单的情况 。
(情况2)如果有两个圆盘又该怎么移动呢?
![]()
步骤1:我们将A(起点)的小圆盘移到B(终点)上。
步骤2:将A(起点)上的大圆盘移到C(终点)。
步骤3:将B (起点)的小圆盘移到C (终点)上。
最后完成移动。
(情况3)移动n个盘子
知道了移动两个盘子之后那怎么移动n个盘子呢?
我们可以将整体看成两部分,一部分是最底层的盘子和前n-1个盘子,这样我们就可以用移动两个盘子的思想来移动这n个盘子。
想要让A柱所有的盘子移到C柱上,首先需要让A柱最底层盘子上的n-1个盘子先移到B柱上,再将A柱的大盘子移到C柱上,最后再把B上的n-1个盘子移到C柱上。
步骤1:把前n-1个盘子整体从A(起点)经过C(辅助点)移到B(终点)上。
辅助点是帮助把n-1的圆盘移动到终点柱的柱子。
![]()
步骤2:把A(起点)上最大的盘子移到C(终点)上。
步骤3:把前n-1个盘子从B(起点)经过A(辅助点)移到C(终点)
如果忽略这n-1盘子的移动情况,这些步骤和情况2的步骤完全一样。
那如何移动这n-1个盘子呢?
其实思想还是一样,我们还是可以把其看做成两部份(第n-1个盘子和前n-2个盘子)
采用情况2的思想。
步骤1:将前n-2个盘子从B(起点)经过C(辅助点)移到A(终点)
步骤2:将第n-1个盘子从B(起点)移到C(终点)
步骤3:将前n-2个盘子从A(起点)经过B(辅助点)移到C(终点)
我们现在所做的就是把大问题转换成小问题,最开始的大问题就是将A(起点)柱上的n个盘子通过B(辅助点)移到C(终点)柱上,经过上面步骤1和步骤3 ,把问题变小将n-1个盘子从B柱(起点)通过A柱(辅助点)移到C柱(终点)上,再经过上面步骤1和步骤3 ,把问题又变小将n-2个盘子从A柱(起点)经过B柱(辅助点)到C柱(终点)上。
![]()
一直这样下去直到变成只剩一个盘子时,已经不能再细分了,经过步骤2,将最后一个圆盘直接移到C(终点),也就完成移动了。
我们先用伪代码写一遍
//假设有n个盘子,定义一个函数:
void hanoi(int n,char A,char B,char C)//函数目的是将n个盘子从A(起点)柱通过B(辅助点)柱,移到C(终点)柱。
{
if(n==1)//如果n=1,只有一个盘子(最简单的情况),限制递归的条件
{
printf("%c->%c\n", A, C);//直接将这一个盘子从A柱移到C柱
}
else//如果是n>1个盘子
{
hanoi(n-1,A,C,B);//步骤1:将n-1个盘子从A柱通过C柱移到B柱,通过调用自身。
printf("%c->%c\n", A, C);//步骤2:将第n个盘子从A柱移到C柱。
hanoi(n-1,B,A,C)步骤3:将n-1个盘子从B柱通过A柱移到C柱,调用自身。
}
}
注意:这里A,B,C和A,B,C的含义并不相同。
A代表A柱子,B代表B柱子,C代表C柱子。
void hanoi(int n,char A,char B,char C) 这里的3个形参A,B,C是固定的,这里的A表示起点,B表示辅助点,C表示终点,每一次递归A,B,C三个参数代表的柱子都在不断的改变,即使函数printf里面看似只从A到C进行输出,其实真正打印出来的各种移动情况都有,这里很容易混淆,导致看不懂代码。
代码如下
#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, C, A);
}
}
int main()
{
int n = 0;
printf("请输入你的盘子数:");
scanf("%d",&n);
char A = 'A';
char B = 'B';
char C = 'C';
hanoi(n,A,B,C);
return 0;
}
我可能阐述的不是很好,如果有写的模糊的地方,请各位大佬们指出来,让我及时改正,谢谢大家。