《数据结构、算法与应用C++语言描述》-栈的应用-汉诺塔问题

完整项目见链接:链接

汉诺塔问题

汉诺塔(Towers of Hanoi)问题来自大梵天创世的一个古老传说。在创世之日,有一座钻石宝塔(塔1),其上有64个金碟(如图 8-5所示),所有碟子从大到小从塔底堆到塔顶,旁边还有另外两座钻石宝塔(塔2和塔3)。从创世之日起,婆罗门一直试图把塔1上的碟子移到塔2上去,不过要借助塔3。由于碟子非常重,所以一次只能移动一个碟子。另外,任何时候大碟子都不能压在小碟子上面。根据这个传说,等到婆罗门把盘子搬完了,世界末日也就到了。

求解策略

一个简洁的解决方法是递归。为了把最大的碟子移到塔 2 的底部,必须把其余 n-1 个碟子移到塔 3,然后把最大的碟子移到塔2。接下来是把塔 3 上的 n-1 个碟子移到塔2。为此可以利用塔2和塔1。可以完全忽略塔2上已有的一个碟子,因为这个碟子比塔3上将要移过来的所有碟子都大,在它顶上可以堆放任何一个碟子。

代码

#include <iostream>
#include <vector>
using namespace std;
/*使用数组模拟栈*/
/*汉诺塔问题全局变量*/
vector<int> tower[4];//全局变量,tower[1:3]表示三个塔
/*汉诺塔问题*/
/*使用数组存储也是为了实现可视化*/
void HanoiShowState()
{
    cout << "tower[1] = ";
    for(int& data : tower[1])
        cout << data << " ";
    cout << endl;
    cout << "tower[2] = ";
    for(int& data : tower[2])
        cout << data << " ";
    cout << endl;
    cout << "tower[3] = ";
    for(int& data : tower[3])
        cout << data << " ";
    cout << endl;
}

void moveAndShow(int n, int x, int y, int z)
{
    if (n > 0)
    {
        moveAndShow(n - 1, x, z, y);/*首先把x上的盘子搬到z上*/
        int d = tower[x][tower[x].size() - 1];
        tower[x].pop_back();
        tower[y].push_back(d);
        cout << "Move dish " << d << " from tower " << x << " to top of tower " << y << endl;
        HanoiShowState();
        moveAndShow(n - 1, z, y, x);/*把z上的盘子搬到y上*/
    }
}

void towersOfHanoiStack(int n, int x, int y, int z)
{
    for (int i = n; i > 0; i--)
        tower[1].push_back(i);//初始状态碟子全部在塔1上
    moveAndShow(n, x, y, z);
}



// 若n为偶数,则中位数为(a[n/2]+a[n/2-1])/2,若n为奇数,则中位数为a[n/2]
int main()
{
    towersOfHanoiStack(2, 1, 2, 3);
    return 0;
}

运行结果

Move dish 1 from tower 1 to top of tower 3
tower[1] = 2
tower[2] =
tower[3] = 1
Move dish 2 from tower 1 to top of tower 2
tower[1] =
tower[2] = 2
tower[3] = 1
Move dish 1 from tower 3 to top of tower 2
tower[1] =
tower[2] = 2 1
tower[3] =

Process finished with exit code 0
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jasmine-Lily

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值