汉诺塔

来源:互联网 发布:照片怎样发到淘宝客服 编辑:程序博客网 时间:2024/05/16 16:11

汉诺塔(Towers of Hanoi)问题来自一个古老的传说:在世界刚被创建的时候有一座钻石宝塔(塔1),其上有64个金碟(如图5-4所示)。所有碟子按从大到小的次序从塔底堆放至塔顶。紧挨着这座塔有另外两个钻石宝塔(塔 2和塔3)。从世界创始之日起,婆罗门的牧师们就一直在试图把塔1上的碟子移动到塔2上去,其间借助于塔 3的帮助。由于碟子非常重,因此,每次只能移动一个碟子。另外,任何时候都不能把一个碟子放在比它小的碟子上面。按照这个传说, 当牧师们完成他们的任务之后,世界末日也就到了。

 

在汉诺塔问题中,已知 n个碟子和3座塔。初始时所有的碟子按从大到小次序从塔1的底部 堆放至顶部,我们需要把碟子都移动到塔2,每次移动一个碟子,而且任何时候都不能把大碟子放到小碟子的上面。在继续往下阅读之前,可以先尝试对n=2,3和4来解决这个问题。

 

一个非常优雅的解决办法是使用递归。为了把最大的碟子移动到塔2,必须把其余n-1个碟 子移动到塔3,然后把最大的碟子移动到塔2。接下来是把塔3上的n-1个碟子移动到塔 2,为此可以利用塔2和塔1。可以完全忽视塔2上已经有一个碟子的事实,因为这个碟子比塔3上将要移 过来的任一个碟子都大,因此,可以在它上面堆放任何碟子。


可以得到碟子的移动次数moves (n)如下:


得到的结果应为moves (n)=2n-1,函数的复杂性为 (2n )。


代码实现:

#include "stdafx.h"#include <iostream>#include <string>#include <stack>using namespace std;stack<int> s[4];//从init_T移动n个碟子到end_T,使用temp_T作为碟子的中间存储void Hanoi(int n,int init_T,int end_T,int temp_T){//停止条件:移动一个碟子if (n==1){s[init_T].pop();s[end_T].push(n);cout<<"move dish"<<n<<" frome "<<" T"<<init_T<<" to "<<" T"<<end_T<<endl;}else{//从init_T到temp_T移动n-1个碟子,使用end_T进行临时存储Hanoi(n-1,init_T,temp_T,end_T);s[init_T].pop();s[end_T].push(n);//移动最大的碟子到end_Tcout<<"move dish"<<n<<" frome "<<" T"<<init_T<<" to "<<" T"<<end_T<<endl;//从temp_T到end_T移动n-1个碟子,使用init_T进行临时存储Hanoi(n-1,temp_T,end_T,init_T);}}//初始化void InitHanoi(int n){for (int d=n; d>0; d--){s[1].push(d);//把碟子d 放到塔1上}Hanoi(n,1,2,3);for (int i=1;i<=n;i++){cout<<s[2].top()<<endl;s[2].pop();}}int main(){int n;cout<<"Enter the number of dish: ";cin>>n;cout<<"The solution for n= "<<n<<endl;InitHanoi(n);return 0;}


测试结果

     

    






原创粉丝点击