汉诺塔问题的程序实现(hanoi塔)

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 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; //累计移动的次数

相关文档
最新文档