汉诺塔(Hanoi)问题递归&非递归的C++实现及总结

汉诺塔(Hanoi)问题递归&非递归的C++实现及总结

由于刚入门不算很久,所以就那汉诺塔这种简单问题来练下手啦~~

【汉诺塔问题内容】(虽然路人皆知但还是写一下好了。。。)
  相传在古印度圣庙中,有一种被称为汉诺塔(Hanoi)的游戏。该游戏是在一块铜板装置上,有三根杆(编号A、B、C),在A杆自下而上、由大到小按顺序放置64个金盘(如下图)。游戏的目标:把A杆上的金盘全部移到C杆上,并仍保持原有顺序叠好。操作规则:每次只能移动一个盘子,并且在移动过程中三根杆上都始终保持大盘在下,小盘在上,操作过程中盘子可以置于A、B、C任一杆上。


  详细的背景可以去 百度百科自己看~~

【递归实现】
//汉诺塔问题最简单最经典的解决方法当然是递归解决啦~~

#include 
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   
#include   
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 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版)》,王晓东编著;在空间复杂度方面,递归实现每一次调用递归函数,计算机将为其分配新的内存,其占用空间大于非递归实现所利用的栈结构。

你可能感兴趣的:(C++,算法,数据结构)