Hanoi塔問題

設A,B,C是三個塔座。開始時,在塔座A上有一疊共n個圓盤,這些圓盤自上而下,由大到小地疊在一起,各圓盤從小到大編號爲1,2,。。。,n。現要求將塔座A上的這一疊圓盤移到塔座B上,並仍按同樣順序疊置。在移動圓盤時應遵守以下移動規則:

規則(1)每次只能移動一個圓盤;

規則(2)任何時刻都不允許將較大的圓盤壓在較小的圓盤之上;

規則(3)在滿足移動規則(1)和(2)的前提下,可將圓盤移至A,B, C中任一塔座上。

       這個問題有一個簡單的解法。假設塔座A、B、C排列成一個三角形,A——>B——>C——>A構成一順時針循環。在移動圓盤的過程中,若是奇數次移動,則將最小的圓盤移到順時針方向的下一塔座上;若是偶數次移動,則保持最小的圓盤不動。而其他兩個塔座之間,將較小的圓盤移到另一塔座上去。

       上述算法簡潔明確,可以證明它是正確的。下面用遞歸技術來解決同一問題。

當n=1時,問題比較簡單。此時,只要將編號爲1的圓盤從塔座A直接移至塔座B上即可。

當n>1時,需要利用塔座C作爲輔助塔座。此時設法將n-1個較小的圓盤依照移動規則從塔座A移至塔座C,然後,將剩下的最大圓盤從塔座A移至塔座B,最後,再設法將n-1個較小的圓盤依照移動規則從塔座C移至塔座B。

這樣一來,n個圓盤的移動問題就可分解爲兩次n-1個圓盤的移動問題,我們又可以遞歸地用上述方法來做。

void Hanoi(int n,int A,int B,int C)
{
      if(n>0)
      {
            Hanoi(n-1,A,C,B);
            Move(n,A,B);
            Hanoi(n-1,C,B,A);
     }
}


 

其中,Hanoi(n,A,B,C)表示將塔座A上自下而上,由大到小疊在一起的n個圓盤依移動規則移至塔座B上並仍按同樣順序疊排。在移動過程中,以塔座C作爲輔助塔座。

            Move(n,A,B)表示將塔座A上編號爲n的圓盤移至塔座B上。

 

Hanoi塔問題的非遞歸算法描述

void hanoi(int n)
{
    int top[3]={0,0,0};
    int **tower;
    Make2DArrary(tower,n+1,3);//生成二維數組
    int b,bb,x,y,min=0;
    for(int i=0;i<=n;i++)
    {
        tower[i][0]=n-i+1;
        tower[i][1]=n+1;
        tower[i][2]=n+1;
    }
    top[0]=n;b=odd(n);bb=1;
    while(top[1]<n)
    {
        if(bb)
        {
            x=min;
            if(b)
                y=(x+1)%3;
            else 
                y=(x+2)%3;
            min=y;bb=0;
        }
        else
        {
            x=(min+1)%3;y=(min+2)%3;bb=1;
            if(tower[top[x]][x]>tower[top[y]][y])
                Swap(x,y);
        }
        move(tower[top[x]][x],x+1,y+1);
        tower[top[y]+1][y]=tower[top[x]][x];
        top[x]--;top[y]++;
    }
}

下面對非遞歸算法進行模擬

下面用數數歸納法證明遞歸算法和非遞歸算法產生相同的移動序列。

當n=1和n=2時容易直接驗證。設當k<=n-1時,遞歸算法 和非遞歸算法產生完全相同的移動序列。考察k=n的情形。

將移動分爲順序時針移動(C)、逆時針移動(CC)和非最小圓盤塔座間的移動(O)三種情況。

當n爲奇數時,順時針非遞歸算法產生的移動序列爲C,O,C,O,...,C;逆時針非遞歸算法產生的移動序列爲CC,O,CC,O,...,CC。

當n爲偶數時,順時針非遞歸算法產生的移動序列爲CC,O,CC,O,...,CC;逆時針非遞歸算法產生的移動序列爲C,O,C,O,...,C。

(1)當n爲奇數時,順時針遞歸算法hanoi(n,A,B,C)產生的移動序列爲

hanoi(n-1,A,B,C)產生的移動序列,O,hanoi(n-1,C,B,A)產生的移動序列。

其中,hanoi(n-1,A,C,B)和hanoi(n-1,C,B,A)均爲偶數圓盤逆時針移動問題。由數學歸納法知,它們產生的移動序列均爲C,O,C,O,...,C。因此,hanoi(n,A,B,C)產生的移動序列爲C,O,C,O,...,C。

(2)當n爲偶數時,順時針遞歸算法hanoi(n,A,B,C)產生的移動序列爲

hanoi(n-1,A,C,B)產生的移動序列,O,hanoi(n-1,C,B,A)產生的移動序列

其中,hanoi(n-1,A,B,C)和hanoi(n-1,C,B,A)均爲奇數圓盤逆時針移動問題。由數學歸納法知,它們產生的移動序列均爲CC,O,CC,O,...,CC。因此,hanoi(n,A,B,C)產生的移動序列爲CC,O,CC,O,...,CC。

當n爲奇數和偶數時的逆時針遞歸算法也類似。

由數學歸納法可知,遞歸算法和非遞歸算法產生相同的移動序列。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章