using namespace std; i" />
当前位置:文档之家› 汉诺塔问题的三种实现

汉诺塔问题的三种实现

// test_project.cpp : 定义控制台应用程序的入口点。

//汉诺塔问题的////递归实现/*#include "stdafx.h"#include<iostream>using namespace std;int count=0;//记录移动到了多少步void Move(int n,char From,char To);void Hannoi(int n,char From, char Pass ,char To); //把圆盘从From,经过pass,移动到Toint main(){int n_count=0;cout<<"请输入圆盘个数:";cin>>n_count;Hannoi(n_count,'A','B','C');}void Move(int n,char From,char To){count++;cout<<"第"<<count<<"步:"<<"将第"<<n<<"个圆盘从"<<From<<"移动到"<<To<<endl;}void Hannoi(int n,char From,char Pass,char To){if(n==1)Move(1,From,To);//哈哈,注意这里的From,已经不等于第一次调用Hannoi的from了,好好体会else{Hannoi(n-1,From,To,Pass);Move(n,From,To);Hannoi(n-1,Pass,From,To);}}*///非递归实现//非递归实现的算法描述,要通过画图理解/*后来一位美国学者发现一种出人意料的简单方法,只要轮流进行两步操作就可以了。

首先把三根柱子按顺序排成品字型,把所有的圆盘按从大到小的顺序放在柱子A上,根据圆盘的数量确定柱子的排放顺序:若n为偶数,按顺时针方向依次摆放A B C;若n为奇数,按顺时针方向依次摆放A C B。

()按顺时针方向把圆盘从现在的柱子移动到下一根柱子,即当n为偶数时,若圆盘在柱子A,则把它移动到B;若圆盘在柱子B,则把它移动到C;若圆盘在柱子C,则把它移动到A。

()接着,把另外两根柱子上可以移动的圆盘移动到新的柱子上。

即把非空柱子上的圆盘移动到空柱子上,当两根柱子都非空时,移动较小的圆盘。

这一步没有明确规定移动哪个圆盘,你可能以为会有多种可能性,其实不然,可实施的行动是唯一的。

()反复进行()()操作,最后就能按规定完成汉诺塔的移动。

所以结果非常简单,就是按照移动规则向一个方向移动金片:如阶汉诺塔的移动:A→C,A→B,C→B,A→C,B→A,B→C,A→C汉诺塔问题也是程序设计中的经典递归问题,下面我们将给出递归和非递归的不同实现源代码。

*//*#include "stdafx.h"#include<iostream>#include<cmath>using namespace std;const int MAX=64;//圆盘的个数最多为//表示每根柱子的信息struct st{int s[MAX];int top;char name;int Top()//取栈顶元素{return s[top];}int Pop()//出栈{return s[top--];}void Push(int x)//入栈{s[++top]=x;}};void My_Initial(st ta[],long n);//给结构数组设置初始值void Hannoi(st ta[],long Mov_count);int main(){int n;cout<<"请输入圆盘个数:"<<endl;cin>>n; //输入圆盘的个数st ta[3];//三根柱子的信息用数据结构数组存储My_Initial(ta,n);//初始化结构数组long Mov_count=pow((double)2,n)-1;//移动的次数为^n-1Hannoi(ta,Mov_count);return 0;}void My_Initial(st ta[],long n){ta[0].name='A';ta[0].top=n-1;//开始时圆盘从大到小顺序放在柱子A上for(int i=0;i<n;i++)ta[0].s[i]=n-i;//柱子B,C上开始没有圆盘ta[1].top=ta[2].top=0;for(int i=0;i<n;i++)ta[1].s[i] = ta[2].s[i] = 0;//若n为偶数,按顺时针方向依次摆放A B Cif(n%2==0){ta[1].name='B';ta[2].name='C';}else//若n为奇数,按顺时针方向依次摆放A C B {ta[1].name='C';ta[2].name='B';}}void Hannoi(st ta[],long Mov_count){int k=0;//累计移动的次数int i=0;int ch;while(k<Mov_count){//按顺时针方向把圆盘从现在的柱子移动到下//一根柱子ch=ta[i%3].Pop();ta[(i+1)%3].Push(ch);cout<<++k<<" :"<<"Move disk "<<ch<<" from "<<ta[i%3].name<<" to "<<ta[(i+1)%3].name<<endl;i++;//把另外两根柱子上可以移动的圆盘移动到新的柱子上if(k<Mov_count){if (ta[(i+1)%3].Top() == 0 ||ta[(i-1)%3].Top() > 0 &&ta[(i+1)%3].Top() > ta[(i-1)%3].Top()) {ch = ta[(i-1)%3].Pop();ta[(i+1)%3].Push(ch);cout << ++k << ": " << "Move disk "<< ch << " from " << ta[(i-1)%3].name << " to " << ta[(i+1)%3].name << endl;}else{ch = ta[(i+1)%3].Pop();ta[(i-1)%3].Push(ch);cout << ++k << ": " << "Move disk "<< ch << " from " << ta[(i+1)%3].name<< " to " << ta[(i-1)%3].name << endl;}}}}*///栈实现/*#include "stdafx.h"#include<iostream>#include<stack>using namespace std;int count=0;//用于记录是第几次操作struct My_Hanoi{char a;//起始柱char b;//中间柱char c;//目标柱int n;My_Hanoi(char a1,char b1 ,char c1 ,int n1) :a(a1),b(b1),c(c1),n(n1){}};void HanoiS(char a,char b,char c ,int n); void main()cout<<"请输入圆盘个数:";int n;cin>>n;HanoiS('A','B','C',n);}void HanoiS(char a,char b,char c ,int n){stack<My_Hanoi> s;My_Hanoi tmp(a,b,c,0);s.push(My_Hanoi(a,b,c,n));while(!s.empty()){tmp=s.top();s.pop();if(tmp.n>1){//注意了先操作的后进栈s.push(My_Hanoi(tmp.b,tmp.a,tmp.c,n-1));s.push(My_Hanoi(tmp.a,tmp.b,tmp.c,1));s.push(My_Hanoi(tmp.a,tmp.c,tmp.b,n-1));}else{count++;cout<<"第"<<count<<"步:"<<"圆盘从"<<tmp.a<<"移动到"<<tmp.c<<endl;}}}*/。

相关主题