zoukankan      html  css  js  c++  java
  • 汉诺塔问题(The Tower of Hanoi)的递归算法与非递归算法

    非递归算法:

      根据圆盘的数量确定柱子的排放顺序:

        若n为偶数,按顺时针方向依次摆放 A B C;

        若n为奇数,按顺时针方向依次摆放 A C B。

      然后进行如下操作:

      (1)按顺时针方向把圆盘1从现在的柱子移动到下一根柱子,即当n为偶数时,若圆盘1在柱子A,则把它移动到B;若圆盘1在柱子B,则把它移动到C;若圆盘1在柱子C,则把它移动到A。

      (2)接着,把另外两根柱子上可以移动的圆盘移动到新的柱子上。即把非空柱子上的圆盘移动到空柱子上,当两根柱子都非空时,移动较小的圆盘。

      (3)反复进行(1)(2)操作,最后就能按规定完成汉诺塔的移动。

    C++实现:

    #include<bits/stdc++.h>
    using namespace std;
    typedef unsigned long long LL;
    struct Hanoi
    {
        int n;
        struct Tower
        {
            char Name;
            stack<int> Disks;
        }Tow[3];
        void init(int num)
        {
            n=num;
            for(int i=0;i<3;i++)
            {
                Tow[i].Name='A'+i;
                while(!Tow[i].Disks.empty()) Tow[i].Disks.pop();
            }
            for(int i=n;i>=1;i--) Tow[0].Disks.push(i);
        }
        void solve()
        {
            LL cnt=0,cnt_max=(1<<n)-1;
            while(cnt<cnt_max)
            {
                cnt++;
    
                int flag1,flag2;
                if(cnt%2)//第奇数次的移动
                {
                    for(int i=0;i<3;i++) if(!Tow[i].Disks.empty() && Tow[i].Disks.top()==1) flag1=i;
                    if(n%2)//n为奇数
                        flag2=((flag1-1)+3)%3;
                    else
                        flag2=(flag1+1)%3;
                }
                else//第偶数次的移动
                {
                    flag1=flag2=-1;
                    for(int i=0;i<3;i++)
                    {
                        if(!Tow[i].Disks.empty() && Tow[i].Disks.top()==1) continue;
    
                        if(flag1==-1) flag1=i;
                        else if(flag2==-1) flag2=i;
                    }
    
                    if(!Tow[flag1].Disks.empty() && !Tow[flag2].Disks.empty())
                    {
                        if(Tow[flag1].Disks.top()>Tow[flag2].Disks.top()) swap(flag1,flag2);
                    }
                    else
                    {
                        if(Tow[flag1].Disks.empty()) swap(flag1,flag2);
                    }
                }
    
                cout<<cnt<<": "<<"Move disk "<<Tow[flag1].Disks.top()<<" from "<<Tow[flag1].Name<<" to "<<Tow[flag2].Name<<endl;
                Tow[flag2].Disks.push(Tow[flag1].Disks.top());
                Tow[flag1].Disks.pop();
            }
        }
    }hanoi;
    int main()
    {
        int n;
        cout<<"输入圆盘个数:"; cin>>n;
        hanoi.init(n);
        hanoi.solve();
    }

    递归算法:

    设Hanoi(n,a,c,b)表示n个圆盘在a柱上,通过服从汉诺塔规则的若干步骤移动,在b柱的辅助下,全部按原顺序移动到了c柱上;

    #include<bits/stdc++.h>
    using namespace std;
    typedef unsigned long long LL;
    LL cnt;
    void Hanoi(int n,char a,char c,char b)
    {
        if(n==1)
        {
            cout<<++cnt<<": "<<"Move disk "<<n<<" from "<<a<<" to "<<c<<endl;
            return;
        }
    
        Hanoi(n-1,a,b,c);
        cout<<++cnt<<": "<<"Move disk "<<n<<" from "<<a<<" to "<<c<<endl;
        Hanoi(n-1,b,c,a);
        return;
    }
    int main()
    {
        int n;
        cout<<"输入圆盘个数:";
        cin>>n;
        cnt=0;
        Hanoi(n,'A','C','B');
    }
  • 相关阅读:
    TabControl
    Loading
    Dialog
    Combobox
    Markdown编辑器Editor.md使用方式
    XSS攻击
    跨域解决方案及实现
    angular4 自定义表单组件
    angular4 Form表单相关
    js 详解setTimeout定时器
  • 原文地址:https://www.cnblogs.com/dilthey/p/8323841.html
Copyright © 2011-2022 走看看