汉诺塔问题

来源:互联网 发布:微信点赞软件下载 编辑:程序博客网 时间:2024/05/23 19:01

汉诺塔如下图所示:需要我们完成的事情是把盘子移动到c,规则就不赘述了。

算法思想:总体来说是利用递归完成的。

假设(1)A上只有一个盘子,我们直接移动到C即可;

(2)A上有两个盘子,我们把第二个盘子上面的所有盘子(此时只有一个,比较容易)移动到B,再把第二个盘子移动到目的地C,最后把B上的盘子移动到C;

(3)A上有3个盘子,我们先把第三个盘子上面的所有盘子利用C移动到B,再把第三个盘子移动到C,最后利用A把B上的所有盘子移动到C;

......

(n)A上有n个盘子,我们先把第n个盘子上面的所有盘子利用C移动到B,再把第n个盘子移动到C,最后把B上的n-1个盘子移动到C。


具体实现代码如下:

#include<iostream>#include<string>using namespace std;class han_nt{private:string first,last,temp;//三根柱子int num;//盘子个数int count;//移动的次数void moveone(int num_one,string first,string last);//移动一个盘子(每一次的最低端的那个盘子)void movesome(int num_some,string first,string temp,string last);//移动许多盘子(每一次的所有的盘子)public:han_nt(int n);void move();//实现移动,并输出移动的次数};han_nt::han_nt(int n){num=n;count =0;first='A';temp='B';last='C';}void han_nt::moveone(int num_one,string first,string last){cout<<"move "<<num_one<<" from "<<first<<" to "<<last<<endl;count++;}void han_nt::movesome(int num_some,string first,string temp,string last){if (num_some==1){moveone(1,first,last);}else{movesome(num_some-1,first,last,temp);moveone(num_some,first,last);movesome(num_some-1,temp,first,last);}}void han_nt::move(){movesome(num,first,temp,last);cout<<"移动次数为"<<count<<endl;}void main(){han_nt h(3);h.move();system("pause");}


分析:具体过程如下所示:

movesome(3,a,b,c)

(1)movesome(2,a,c,b)

[1]movesome(1,a,b,c)

moveone(1,a,c)//输出move 1 from a to c

[2]moveone(2,a,b)//输出move 2 from a to b

[3]movesome(1,c,a,b)

moveone(1,c,b)//输出move 1 from c to b

(2)moveone(3,a,c)//输出move 3 from a to c

(3)movesome(2,b,a,c)

[1]movesome(1,b,c,a)

moveone(1,b,a)//输出 move 1 from b to a

[2]moveone(2,b,c)//输出 move 2 from b to c

[3]movesome(1,a,b,c)

moveone(1,a,c)//输出move 1 from a to c


0 0