汉诺塔问题深刻而简单的理解
汉诺塔问题(Hanio塔)的问题,本人看了很多版本,大多比较死板,理解很困难,经过自己的理解,写写感想!!
其实很简单,就是要把a塔上的移动到c塔上,见图,就是把图1移动成图2:
先假设塔座是排成一个三角形,a-->b-->c-->a,形成一个顺时针的圆盘,在移动圆盘的时候,如果是奇数次移动(第1次,第3次,第5次·······),那么就把最小的圆盘移动到顺时针方向的下一个塔座上;如果是偶数次移动(第2次,第4次,第6次······),则保持最小的圆盘不动,而在其他的两个塔座之间,将较小的圆盘移动到另一座塔座上去。(总体思想差不多就是这样,还是不懂往下看)
上面的算法应该是很简洁明了的,可以证明它是正确的,但是光看算法肯定很难理解,下面用递归的技术来解决一下这个问题,当n=1的时候,很简单,只要将a塔座上唯一的一个圆盘移动到c塔座上即可解决问题;当n>1的时候呢,需要把b塔座作为中转塔座(辅助用),此时只要将n-1个较小的圆盘按照规则从a先移动到b上,然后将剩下的最大的圆盘从塔座a直接移动到c上,最后,将n-1个剩下的圆盘按照相同的方法移动到c上,不同的只是原来是n个,现在是n-1个。由此可见,n个圆盘的移动问题就可以分解为两次n-1个圆盘的移动问题(第一次是指n-1个圆盘从a移动到b,第二次是指n-1个圆盘从b移动到c),这移动又可以递归用上述方法来做。由此可以设计出解决汉诺塔问题的递归算法:
void Hanoi(int n,char a,char b,char c)
{
if(n>0)
{
Hanoi(n-1,a,c,b);
cout<<"把"<
代码很简单,其中,hanoi(n,a,b,c)表示将塔座a上自下而上,由大到小叠放在一起的n个圆盘依移动规则移至塔座b上并且按照同样的顺序叠放,在移动的过程中,以塔座b作为中转塔座,好了,多看几遍你就会了,鄙人也是理解能力不怎么强的,但是看了几遍也就会了,也就是那么回事吧,如果有什么问题的,欢迎留言!
最后再附上整体的代码,给初学者看的,大牛直接无视^_^
C++:
#include
using namespace std;
void Hanoi(int n,char a,char b,char c)
{
if(n>0)
{
Hanoi(n-1,a,c,b);
cout<<"把"<>n;
Hanoi(n,'a','b','c');
return 0;
}
C语言版
#include
void Hanoi(int n,char a,char b,char c)
{
if(n>0)
{
Hanoi(n-1,a,c,b);
printf("把%d号从%c移动到%c\n",n,a,c);
Hanoi(n-1,b,a,c);
}
}
int main()
{
int n;
scanf("%d",&n);
Hanoi(n,'a','b','c');
return 0;
}
以上代码在code::blocks上运行通过