汉诺塔问题的程序实现(hanoi塔)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
问题重述:
有三根柱A、B、C,在柱A上有N块盘片,所有盘片都是大的在下面,小片能放在大片上面。现要将A上的N块盘片移到C柱上,每次只能移动一片,而且在同一根柱子上必须保持上面的盘片比下面的盘片小,输入任意的N,输出移动方法。
(注意:这是一个古老的传说,传说是如果把64个盘子由A柱移到了C柱的话,那么世界末日就到了,事实上如果要把64个盘子从A柱移到C柱的话,即使用计算机运算,也要计算数亿年,所以这个预言未必不是真实。)
【分析】
我们可以这样考虑,当n=1时,我们只要直接将A柱的盘子移到C柱,当n>1时,我们可以先把n-1个盘子由A柱通过C柱移到B柱,此时就可以把A柱剩下的最后一个盘子直接移到C柱,这样接下来只要把n-1个盘子通过A柱移到C 柱即可,如果就构成了递归的思路,我们可以定义个移动过程mov(n,a,b,c)表示将n个盘子从a通过b移到c
1.只要求输出搬运的次数
#include
using namespace std;
int m=0;
void move()
{
m++;
}
void I(int n)
{
if(n==1)
move();
else
{
I(n-1);
move();
I(n-1);
}
}
int main()
{
I(3);
cout< cout<<"输出完毕!"< return 0; } 更加简单的方法! #include using namespace std; int fact(int n) { if(n==1) return(1); else return((2*fact(n-1)+1)); } int main() { cout< } 2.不仅要求输出搬运的次数,而且要输出每个步骤的详细搬运 #include using namespace std; int m=0; void Move(int n,char x,char y) { cout<<"把"< m++; } void Hannoi(int n,char a,char b,char c) { if(n==1) Move(1,a,c); else { Hannoi(n-1,a,c,b); Move(n,a,c); Hannoi(n-1,b,a,c); } } int main() { int i; cout<<"请输入圆盘数"< cin>>i; Hannoi(3,'a','b','c'); cout<<"总的搬运次数"< cout<<"输出完毕!"< return 0; }} 另外一种不利用递归的解法(很抱歉,我自己也没调出来,实在太复杂了) #include using namespace std; //圆盘的个数最多为64 const int MAX = 1; //用来表示每根柱子的信息 struct st{ int s[MAX]; //柱子上的圆盘存储情况 int top; //栈顶,用来最上面的圆盘 char name; //柱子的名字,可以是A,B,C 中的一个 int Top()//取栈顶元素 { return s[top]; } int Pop()//出栈 { return s[top--]; } void Push(int x)//入栈 { s[++top] = x; } } ; long Pow(int x, int y); //计算x^y void Creat(st ta[], int n); //给结构数组设置初值 void Hannuota(st ta[], long max); //移动汉诺塔的主要函数 int main(void) { int n; cin >> n; //输入圆盘的个数 st ta[3]; //三根柱子的信息用结构数组存储 Creat(ta, n); //给结构数组设置初值 long max = Pow(2, n) - 1;//动的次数应等于2^n - 1 Hannuota(ta, max);//移动汉诺塔的主要函数 system("pause"); return 0; } void Creat(st ta[], int n) { ta[0].name = 'A'; ta[0].top = n-1; //把所有的圆盘按从大到小的顺序放在柱子A 上 for (int i=0; i ta[0].s[i] = n - i; //柱子B,C 上开始没有没有圆盘 ta[1].top = ta[2].top = 0; for (int j=0; j ta[1].s[j] = ta[2].s[j] = 0; //若n 为偶数,按顺时针方向依次摆放A B C if (n%2 == 0) { ta[1].name = 'B'; ta[2].name = 'C'; } else //若n 为奇数,按顺时针方向依次摆放A C B { ta[1].name = 'C'; ta[2].name = 'B'; } } long Pow(int x, int y) { long sum = 1; for (int i=0; i sum *= x; return sum; } void Hannuota(st ta[], long max) { int k = 0; //累计移动的次数