1. 程式人生 > >演算法分析——Hanoi塔問題(還是寫不出來啊!)

演算法分析——Hanoi塔問題(還是寫不出來啊!)

上圖為 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()
7 {
8 int n ;
9 printf("請輸入n的值:");
10 scanf("%d",&n);
11 12 hanoi(n , 'A' , 'B' , 'C');
13 14 return0 ;
15 }
16 17 void hanoi(int i , char A , char
B , char C)
18 {
19 if(i ==1)
20 {
21 move(i , A , C);
22 }
23 else24 {
25 hanoi(i -1 , A , C , B); //函式遞迴呼叫 26 move(i , A , C);
27 hanoi(i -1 , B , A , C);
28 }
29 }
30 31 void move(int i , char x , char y)
32 {
33 staticint c =1 ; //區域性變數i申明為 static 34 printf("%d: %d from %c ——> %c \n", c++ , i , x , y);
35 }
複製程式碼

 若輸入n值為3,則:

下面說說第33行申明的靜態區域性變數,在區域性變數申明中放入static可以使變數具有靜態儲存期限而不再是自動儲存期限,擁有永久的儲存單元,

所以在整個程式執行期間都會保留變數值,如程式碼中第33行定義的區域性變數 i , 在每次的函式呼叫時保留該值 ,若不加static則 i 的值在每次調

用move函式時都會進行初始化,如圖所示: