1. 程式人生 > >漢諾塔問題(The Tower of Hanoi)的遞歸算法與非遞歸算法

漢諾塔問題(The Tower of Hanoi)的遞歸算法與非遞歸算法

for log col 遞歸 post struct () def ini

非遞歸算法:

  根據圓盤的數量確定柱子的排放順序:

    若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);
}

漢諾塔問題(The Tower of Hanoi)的遞歸算法與非遞歸算法