汉诺塔(Hanoi)问题递归&非递归的C++实现及总结
由于刚入门不算很久,所以就那汉诺塔这种简单问题来练下手啦~~
【汉诺塔问题内容】(虽然路人皆知但还是写一下好了。。。)
相传在古印度圣庙中,有一种被称为汉诺塔(Hanoi)的游戏。该游戏是在一块铜板装置上,有三根杆(编号A、B、C),在A杆自下而上、由大到小按顺序放置64个金盘(如下图)。游戏的目标:把A杆上的金盘全部移到C杆上,并仍保持原有顺序叠好。操作规则:每次只能移动一个盘子,并且在移动过程中三根杆上都始终保持大盘在下,小盘在上,操作过程中盘子可以置于A、B、C任一杆上。
![这里写图片描述](https://gss2.bdstatic.com/-fo3dSag_xI4khGkpoWK1HF6hhy/baike/s=250/sign=5696214b4b34970a4373172aa5cbd1c0/d50735fae6cd7b896014d3e7052442a7d9330e5e.jpg)
详细的背景可以去 百度百科自己看~~
【递归实现】
//汉诺塔问题最简单最经典的解决方法当然是递归解决啦~~
#include <iostream>
using namespace std;
void hanoi(int n, int a, int b, int c)
{
if(n > 0)
{
hanoi(n-1, a, c, b);
cout << "move " << a << " to " << b << endl;
hanoi(n-1, c, b, a);
}
}
int main()
{
int n;
cin >> n;
hanoi(n, 1, 2, 3);
return 0;
}
//非常简单就搞定了
【非递归实现】
//当然汉诺塔问题也可以非递归实现,就是写起来稍微麻烦一点点,主要依赖于栈的数据结构。
#include <iostream>
#include <stack>
using namespace std;
struct hanoiunrec //结构体,表示汉诺塔的信息
{
hanoiunrec();
hanoiunrec(int n, char a, char b, char c):_n(n), _x(a), _y(b), _z(c){} //构造函数
int _n;
char _x, _y, _z;
};
void hanoi(int n, char x, char y, char z)
{
stack<hanoiunrec> s; //声明一个汉诺塔类型的栈,即其元素都具有汉诺塔结构体信息
s.push(hanoiunrec(n, x, y, z)); //将一个汉诺塔入栈
while (!s.empty()) //栈不空则执行
{
hanoiunrec q = s.top(); //取栈顶元素为q
s.pop(); //把栈顶弹出
n = q._n; //分别将当前处理汉诺塔信息赋给函数参数
x = q._x;
y = q._y;
z = q._z;
if (n == 1) //如果只剩一个盘了,则移动并输出操作
{
cout << "Move " << q._x << " to " << q._z << endl;
}
else //还剩多个盘,则将新的汉诺塔元素入栈,返回while循环开始操作
{
s.push(hanoiunrec(n - 1, y, x, z));
s.push(hanoiunrec(1, x, y, z));
s.push(hanoiunrec(n - 1, x, z, y));
}
}
}
int main()
{
hanoi(10, 'A', 'B', 'C'); //以10个盘举个例子
return 0;
}
【递归与非递归方法的异同】
其实咧,,汉诺塔问题递归与非递归实现对于计算机而言原理是相同的。首先,在时间复杂度方面,两种方法相同,均为O(2n);对于实现结果,两种方法产生的序列也是相同的,证明可参考《算法设计与分析习题解答(第3版)》,王晓东编著;在空间复杂度方面,递归实现每一次调用递归函数,计算机将为其分配新的内存,其占用空间大于非递归实现所利用的栈结构。