汉诺塔问题是我们在学习函数递归时常遇见的一类问题,那么如何用简单易懂的思路来解决汉诺塔问题呢?下面我会为大家进行讲解
目录
汉诺塔是什么?
汉诺塔(Tower of Hanoi),又称河内塔,是一个源于印度古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。
汉诺塔的来源
法国数学家爱德华·卢卡斯曾编写过一个印度的古老传说:在世界中心贝拿勒斯(在印度北部)的圣庙里,一块黄铜板上插着三根宝石针。印度教的主神梵天在创造世界的时候,在其中一根针上从下到上地穿好了由大到小的64片金片,这就是所谓的汉诺塔。不论白天黑夜,总有一个僧侣在按照下面的法则移动这些金片:一次只移动一片,不管在哪根针上,小片必须在大片上面。僧侣们预言,当所有的金片都从梵天穿好的那根针上移到另外一根针上时,世界就将在一声霹雳中消灭,而梵塔、庙宇和众生也都将同归于尽。
用C语言实现汉诺塔
汉诺塔问题分析思路:
首先,我们先来看一下汉诺塔问题的题目:
现有三个柱子A、B、C,其中有N个圆盘安从小到大的顺序在A柱上,要求将圆盘按从小到大的顺序借助B柱移动到C柱中。
对于N个处于A柱上的圆盘,我们可以用的从特殊到一般思想将题目简单化,如先思考当N=1的情况,便于我们对题目进行更深一步的分析
当 N = 1 时:
由图可知,当 N = 1 时,我们只须将A中圆盘直接移动到C盘上即可即(A-->C)
那么当 N = 2 时,又该怎样移动圆盘呢?
当 N = 2 时
我们可以先将最上面的圆盘先移到B中,再将底部圆盘移到C中,最后将B柱中的圆盘移到C中,此过程示意图如下
将顶部圆盘移到B柱中
将底部圆盘移到C柱中
将B中圆盘移动到C柱中,完成整个汉诺塔过程
在此过程中,我们可以将顶部圆盘的移动过程看作为借助B柱移动到C柱
而底部圆盘的移动过程看作直接从A柱移动到C柱
当 N = 3 时
那么当N = 3 时,我们又该如何解决汉诺塔问题呢?同样的方式,我们借助图像来进行理解
当 N = 3 时,我们可以适当运用整体思想,将底部圆盘看作一个个体,将除底部圆盘的之外的圆盘看作第二个圆盘,那么移动过程可用下图表示
那么,当我们有N个圆盘时也可以运用上述思路来进行解决
我们令底部圆盘为第N个圆盘,其余圆盘为N-1个,先将N-1个进行移动,再移动底部圆盘,移动N-1个圆盘后再对这N-1个圆盘进行同样的拆分,最终实现了汉诺塔问题
在C语言中,我们可以用函数递归来实现上述思路
用代码实现汉诺塔问题
#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;
}
总结
对于类似于汉诺塔问题的一类题目,我们都可以用从特殊到一般的思想来解决,然后在编写C语言代码的时候用函数的递归来实现这一算法,许多问题便迎刃而解了