汉诺塔问题

有三根杆子A,B,C。A杆上有N个(N>1)穿孔圆盘,盘的尺寸由下到上依次变小。要求按下列规则将所有圆盘移至C杆:

  1. 每次只能移动一个圆盘;
  2. 大盘不能叠在小盘上面。

递归算法

#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属性的。