栈解决汉诺塔问题

Posted muzishiye

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了栈解决汉诺塔问题相关的知识,希望对你有一定的参考价值。

汉诺塔问题比较经典,这里修改--下游戏规则:

  • 现在限制不能从最左侧的塔直接移动到最右侧,也不能从最右侧直接移动到最左侧,而是必须经过中间。
  • 求当塔有N层的时候,打印最优移动过程和最优移动总步数。
  • 在走出最少步数过程中的任何时刻,四个动作中只有一个动作不违反小压大和相邻不可逆原则(相邻的两次操作不互为逆操作如:MtoR和RtoM),另外三个动作一定都会违反。
#include <iostream>
#include <stack>
using namespace std;

enum Act                 //    利用绝对值解决逆操作问题 感谢Stan提供的思路
    No = 0,
    LtoM = 1,
    MtoL = -1,
    RtoM = 2,
    MtoR = -2
;

int move(Act& reAct, Act nowAct, stack<int>& src, stack<int>& dst) 
    if (!src.empty() && (abs(reAct) != abs(nowAct)) && (dst.empty() || src.top() < dst.top())) 
        dst.push(src.top());
        src.pop();
        switch (nowAct)
        case 1:
            cout << "Move " << dst.top() << " from L to M" << endl;
            break;
        case -1:
            cout << "Move " << dst.top() << " from M to L" << endl;
            break;
        case 2:
            cout << "Move " << dst.top() << " from R to M" << endl;
            break;
        case -2:
            cout << "Move " << dst.top() << " from M to R" << endl;
            break;
        
        reAct = nowAct;
        return 1;
    
    return 0;


int solveHanoi(int l)                         //    解决从左往右移动的问题
    stack<int> lS, mS, rS;
    for (int i = l; i > 0; i--)                //    修改此处可决定源栈
    
        lS.push(i);
    
    Act record = No;
    int step = 0;
    while (rS.size() != l)                    //    修改此处可决定目的栈
    
        step += move(record, LtoM, lS, mS);
        step += move(record, MtoL, mS, lS);
        step += move(record, RtoM, rS, mS);
        step += move(record, MtoR, mS, rS);
    
    return step;


int main()

    cout << "Solve 3 Hanoi LtoR:" << endl;
    cout << "I will move " << solveHanoi(3) << " steps" << endl;
    return 0;

 

以上是关于栈解决汉诺塔问题的主要内容,如果未能解决你的问题,请参考以下文章

汉诺塔的非递归实现(栈)

递归5--汉诺塔问题的栈实现

汉诺塔问题(递归栈)

用栈模拟汉诺塔问题

栈实现递归实现汉诺塔问题

面试题 08.06. 汉诺塔问题(非递归实现汉诺塔问题)