1.先从移动过程来看汉诺塔问题。
设递归函数Hannoi(int n,char A,char B,char C)展示把n个金盘从A柱借助B柱移动到C柱的过程,函数move(A,C)输出从A柱到C柱的过程:A→C。完成Hannoi(int n, char A,char B,char C),当n=1时,即move(A,C);当n>1时,分以下步骤执行:
(1)将A柱上面的n-1个盘子借助C柱移到 B柱上,即Hannoi(n-1,A,C,B);
(2)将A柱上第n个盘子移到C柱上,即move(A,C);
(3)将B柱上的n-1个盘子借助A柱移到 C柱上,即Hannoi(n-1,B,A,C);
递归函数Hannoi(int n, char A,char B,char C)的第一个形参是汉诺塔的层数,每次递归后,层数就少一次,直到n=1时达到递归终止条件
上代码
#include<iostream>
using namespace std;
void move(int n,char x,char y)
{
cout<<"把"<<n<<"号从"<<x<<"挪动到"<<y<<endl;
}
void Hannoi(int n,char A,char B,char C) //将n个盘子从A柱借助B柱移动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 n;
cout<<”请输入盘子的个数:”<<endl;
cin>>n;
Hannoi(n,'A','B','C');
return 0;
}
2.看对于移动次数的求解。
当n=1时,只一个盘子,故移动一次即完成;当n=2时,由于条件是一次只移动一个盘子,且不允许大盘放在小盘上面,这样就需要先把小盘从A柱移动到B柱,然后把大盘从A柱移动到C柱,最后把小盘从B柱移动到C柱,移动3次完成。假设移动n个盘子的汉诺塔问题完成需要的次数为count(n),其完成的步骤如下:
(1)将n个盘子上面的n-1个盘子借助C柱从A柱移到 B柱上,需要count(n-1)次;
(2)将A柱上第n个盘子移到C柱,花费1次;
(3)将B柱上的n-1个盘子借助A柱移到C柱,需要count(n-1)次;
因而有以下递推关系:
#include <iostream>
using namespace std;
int main()
{
int num,count=0;
cout<<"请输入需要移动的盘子数目:"<<endl;
cin>>num;
int val(int); //函数声明
if(num==0){
cout<<"输入的数字必须大于0!"<<endl;
return -1;
}
else
cout<<"需要"<<val(num)<<"次"<<endl;
return 0;
}
int val(int n){
int c;
if(n==1) c=1;
else c=2*val(n-1)+1;
return c;
}