Tower of Hanoi
汉诺塔(Tower of Hanoi),又称河内塔,是一个源于印度古老传说的益智玩具。
大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序
摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另
一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动
一个圆盘。
-----摘自百度百科
What is recursion
序调用自身的编程技巧称为递归( Pecursion )。递归做为一种算法在程序设计
语言中广泛应用。一个过程或函数在其定义或说明中有直接或间接调用自身的一
种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小
的问题来求解,递归策略只需少量的程序就可描述出解题过程所需要的多次重复
计算,大大地减少了程序的代码量。递归的主要思考方式在于:把大事化小
Two necessary conditions for recursion
·存在限制条件,当满足这个限制条件的时候,递归便不再继续。
·每次递归调用之后越来越接近这个限制条件。
Tower of Hanoi game rules
游戏里有三根柱子(A柱)(B柱)(C柱),在A柱上从下往上按大小顺序排着圆盘
玩家需要做的是把圆盘从下面开始按大小顺序重新摆放在C柱上面。并且规定,在小
圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。(如图)
According to the rules, when we know that n is 1, we only need to move the disc of the A-pillar to the C-pillar.
But when n>1, we need to move the disc of the n-1 disc to the B pillar, move the largest remaining disc of the A pillar to the C pillar, and finally move the disc on the B pillar to On the C-pillar.
Code implementation to solve the Tower of Hanoi problem
We first define the values required by the Tower of Hanoi, n is a disc, a, b, and c correspond to three pillars respectively, and the hanoi function realizes the process of moving the plate.
int count = 0;//计数器(全局变量)
int main()
{
int n = 0;//盘子
char a = 'A';//起点柱
char b = 'B';//中间柱
char c = 'C';//终点柱
scanf("%d", &n);
hanoi(n, a, b, c);//实现盘子移动的操作过程
printf("移动%d个圆盘需要%d步\n",n,count);
return 0;
}
We know from the above diagram when the disc n is 1 that when n is 1, move the last disc left on the A pillar to the C pillar. I also use this as a recursive exit to prevent the recursion from being out of control. The move function is implemented Print the path when moving the disc
void move(int n,char a, char c)
{
printf("%c-->%c\n", a, c);
count++;//每输出一次路径自增一次
}
void hanoi(int n,char a,char b,char c)
{
if (n == 1)//把盘子为1作为递归的出口
{
move(n, a, c);//剩下最后一个盘子,直接移到终点去
}
When n>1, we use the C-pillar to move the n-1 discs on the A-pillar to the B-pillar
else
{
hanoi(n - 1, a, c, b);//借助c柱把a柱上的n-1个盘子移到b柱上去
move(n, a, c);//把a柱上的最后一个移到c柱子上去
hanoi(n - 1, b, a, c);//借助a柱把b柱上的n-1个盘子移到c柱上去
}
}
At this time, there is the last largest disc left on the A pillar, and then move this disc to the C pillar
Then move the n-1 discs on the B pillar to the C pillar with the aid of the A pillar, and finally move the disc from the A pillar to the C pillar.
Reference Code
int count = 0;
void move(int n,char a, char c)
{
printf("%c柱上的第%d个盘子:%c-->%c\n",a,n, a, c);
count++;
}
void hanoi(int n,char a,char b,char c)
{
if (n == 1)
{
move(n, a, c);//假设最后一个盘子,直接移到终点去
}
else
{
hanoi(n - 1, a, c, b);//借助c柱把a柱上的n-1个盘子移到b柱上去
move(n, a, c);//把a柱上的最后一个移到c柱子上去
hanoi(n - 1, b, a, c);//借助a柱把b柱上的n-1个盘子移到c柱上去
}
}
int main()
{
int n = 0;//盘子
char a = 'A';//起点柱
char b = 'B';//中间柱
char c = 'C';//终点柱
scanf("%d", &n);
hanoi(n, a, b, c);//实现盘子移动的操作过程
printf("%d个盘子总共要移动:%d次",n, count);
return 0;
}