• 汉诺塔问题_栈模拟递归


    汉诺塔问题

    有三根杆子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属性的。

  • 相关阅读:
    清空收缩数据库日志文件的方法
    JavaScript中的剪贴板的使用(clipboardData)
    location.search在客户端获取Url参数的方法
    JS之onkeypress,onkeydown,onkeyup区别
    网页中的meta标签的作用
    SQL优化条
    JS简洁经典滚动上下与左右
    结构体
    static修饰符
    Solaris内存监控 & solaris查看内存使用情况
  • 原文地址:https://www.cnblogs.com/Genesis2018/p/9079792.html
Copyright © 2020-2023  润新知