轉自:http://www.cnblogs.com/liangyan19910818/archive/2011/08/26/2153926.html
上圖為 3 階 Hanoi 塔
假設有三個命名為 A B C 的塔座 ,在塔座A上插有n個直徑大小不相同,由小到大編號為1 ,2 ,3 ,··· ,n的圓盤,要求將A座上的圓盤移至塔座C
並按同樣的順序疊排
圓盤移動必須遵守下列規則:
1:每次只能移動一個圓盤 2:圓盤可以插在任意一個塔座上 3:任何時刻都不能將一個較大的圓盤放在一個較小的圓盤上
該問題的復雜性:
若有n個盤子,則移動完所需之次數為2^n - 1,
所以當盤數為64時,則所需次數為:
2^64 - 1 = 18446744073709551615
為5.05390248594782e+16年,也就是約5000世紀,如果對這數字沒什么概念,就假設每秒鍾搬一個盤子好了,也要約5850億年左右。
以三階Hanoi塔為例,我們所需要的7個步驟是:
1——>C
2——>B
1——>B
3——>C
1——>A
2——>C
1——>C
則對於n階Hanoi塔:
n = 1時只需將編號為1的圓盤從A座移至C座
n > 1時,我們分三個階段:
1:將A塔座上的n-1個圓盤按照規定移至到B塔座
2:將編號為n的圓盤由A座移至C座
3:利用A塔座,將B塔座上的n-1個圓盤按規定移至到C塔座
如何將n-1個圓盤由一個塔座移至到另一個塔座是一個和原問題有相同特征屬性的問題,只是問題的規模小些,我們可以用同樣的方法求解,即用到遞歸函數
代碼如下:
1 #include <stdio.h> 2 3 void hanoi(int i , char A , char B , char C); 4 void move(int i , char x , char y); 5 6 int main(void) 7 { 8 int n ; 9 printf("請輸入n的值:"); 10 scanf("%d",&n); 11 12 hanoi(n , 'A' , 'B' , 'C'); 13 14 return 0 ; 15 } 16 17 void hanoi(int i , char A , char B , char C) 18 { 19 if(i > 0) 20 { 21 hanoi(i - 1 , A , C , B); //函數遞歸調用 22 move(i , A , C); 23 hanoi(i - 1 , B , A , C); 24 } 25 } 26 27 void move(int i , char x , char y) 28 { 29 static int c = 1 ; //局部變量i申明為 static 30 printf("%d: %d from %c ——> %c \n", c++ , i , x , y); 31 }
若輸入n值為3,則:
下面說說第33行申明的靜態局部變量,在局部變量申明中放入static可以使變量具有靜態存儲期限而不再是自動存儲期限,擁有永久的存儲單元,
所以在整個程序執行期間都會保留變量值,如代碼中第33行定義的局部變量 i , 在每次的函數調用時保留該值 ,若不加static則 i 的值在每次調
用move函數時都會進行初始化,如圖所示: