《数据结构、算法与应用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 
#include 
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

你可能感兴趣的:(数据结构,算法与应用,C++语言描述学习笔记,c++,数据结构,算法)