7-10 汉诺塔的非递归实现

文章介绍了一种使用C++和堆栈数据结构,以非递归的循环方式解决汉诺塔问题的方法。通过定义结构体Tower存储汉诺塔的状态,并模拟递归过程,将大问题分解为移动更小数量盘子的子问题,最终达到将N个盘子从起始柱a经过渡柱b移动到目标柱c的目标。
摘要由CSDN通过智能技术生成

借助堆栈以非递归(循环)方式求解汉诺塔的问题(n, a, b, c),即将N个盘子从起始柱(标记为“a”)通过借助柱(标记为“b”)移动到目标柱(标记为“c”),并保证每个移动符合汉诺塔问题的要求。

输入格式:

输入为一个正整数N,即起始柱上的盘数。

输出格式:

每个操作(移动)占一行,按柱1 -> 柱2的格式输出。

#include <stdio.h>
#include <iostream>
#include<stack>
using namespace std;
/*递归思路*/
/*
void MoveTower(int n, char s, char d, char t){//起 目 过
    if(n==1){//如果起始柱上只有1个,那么直接从起始柱位置移动到目标柱
        printf("%d: %c -> %c\n",n,s,d);
    }else{
        MoveTower(n-1,s,t,d);//否则,应该把起始柱往上的n-1个柱子搬到过渡柱
        printf("%d: %c -> %c\n",n,s,d);
        MoveTower(n-1,t,d,s);//实现完过渡阶段,将过渡柱上的柱子移动回目标柱
    }
}
*/
//而递归的特点就是先进入的函数部分是最后执行完的,因此可以用栈来模仿递归的实现

struct Tower
{
    int n;//当前Tower上的盘数
    char a;//起
    char b;//过
    char c;//目
    Tower(int n,char a,char b,char c):n(n),a(a),b(b),c(c){}
    //借用C++ 结构体可以有函数的特点使用构造函数进行赋值操作
};

void MoveTower(Tower T)
{
    stack<Tower> s;
    s.push(T);
    Tower temp = T;// 建立一个临时的结构体,来接受栈区释放出来的结构体变量
    while (!s.empty())//结束条件:栈区被释放干净,代表没有待操作事项,说明起始柱子已经完成转移
    {
        T = s.top();
        s.pop();
        if (T.n == 1)
        {
            //cout << T.a << " -> " << T.c << endl;//如果n为1,说明当前盘子是处于最顶端的,将它移动到它的目标柱
           printf("%c -> %c\n",T.a,T.c);
            continue;//说明可以执行,那么下面的部分就没有必要执行了,因为,下面操作代表含义为,执行改步骤的前提条件
        }
        //类似于递归思想,我们要做的只有三件事情
        //将起始柱子上n-1转移到过渡柱、
        //将起始柱上最后一个盘子移动到目标住上
        //将过渡柱上的n-1个盘子移动到目标柱上
        //由于栈区是先进后出,因此执行顺序相反过来
        s.push(Tower(T.n - 1, T.b,T.a,T.c));
        s.push(Tower(1, T.a, T.b, T.c));
        s.push(Tower(T.n - 1, T.a, T.c, T.b));
    }
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    int n;
    cin >> n;
    char a = 'a', b = 'b', c = 'c';
    Tower T(n, a, b, c);
    if(n>0)
    MoveTower(T);
    return 0;
}    
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值