算法分析——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     return 0 ;
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     static int 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函數時都會進行初始化,如圖所示:

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