借助堆栈以非递归(循环)方式求解汉诺塔的问题(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;
}