汉诺塔问题
有三根杆子A,B,C。A杆上有N个(N>1)穿孔圆盘,盘的尺寸由下到上依次变小。要求按下列规则将所有圆盘移至C杆:
- 每次只能移动一个圆盘;
- 大盘不能叠在小盘上面。
递归算法
#include<iostream>
using namespace std;
void Hanoi(int n, char src, char mid, char dest) {
// 将src座上的n个盒子,以mid座为中转,移动到dest座
if(n==1) { // 只需移动一个盘子
cout<<src<<"->"<<dest<<endl; // 直接将盒子从src移动到dest即可
return; // 递归终止
}
Hanoi(n-1, src, dest, mid); // 先将n-1个盘子从src移动到mid
cout<<src<<"->"<<dest<<endl; // 再将一个盘子从src移动到dest
Hanoi(n-1, mid, src, dest); // 最后将n-1个盘子从mid移动到dest
return;
}
int main(){
int n;
cin>>n; // 输入盘子数目
Hanoi(n, 'A', 'B', 'C');
return 0;
}
用栈模拟递归
#include<iostream>
#include<stack>
using namespace std;
struct Problem {
int n;
char src, mid, dest;
Problem(int nn, char s, char m, char d):n(nn),src(s),mid(m),dest(d) {}
};
// 一个Problem变量代表一个子问题,将src上的n个盘子,以mid为中介,移动到dest
stack<Problem> stk; // 用来模拟的栈
// 若有n个盘子,则栈的高度不超过n*3
int main() {
int n;
cin>>n; // 输入盘子数目
stk.push(Problem(n, 'A', 'B', 'C')); // 初始化了第一个
while( !stk.empty() ) { // 只要还有,就继续处理
Problem curPrb = stk.top(); // 取最上面的,即当前问题
stk.pop(); // 丢弃最上面的
if(curPrb.n == 1)
cout<<curPrb.src<<"->"<<curPrb.dest<<endl;
else { // 分解子问题
// 先把分解得到的第3个子问题放入栈中
stk.push(Problem(curPrb.n-1, curPrb.mid, curPrb.src, curPrb.dest));
// 再把第2个子问题放入栈中
stk.push(Problem(1, curPrb.src, curPrb.mid, curPrb.dest));
// 最后放第1个子问题,后放入栈的子问题先被处理
stk.push(Problem(curPrb.n-1, curPrb.src, curPrb.dest, curPrb.mid));
}
}
return 0;
}
注:
C++语言继承了C语言的struct,并且加以扩充。在C语言中struct是只能定义数据成员,而不能定义成员函数的。而在C++中,struct类似于class,在其中既可以定义数据成员,又可以定义成员函数。
在C++中,struct与class基本是通用的,唯一不同的是如果使用class关键字,类中定义的成员变量或成员函数默认都是private属性的,而采用struct关键字,结构体中定义的成员变量或成员函数默认都是public属性的。