1.背景介紹
Hanio (漢諾塔,又稱河內塔)問題是源於印度一個古老傳說的益智玩具。大梵天創造世界的時候做了三根金剛石柱子,在一根柱子上從下往上按照大小順序摞着64片黃金圓盤。大梵天命令婆羅門把圓盤從下面開始按大小順序重新擺放在另一根柱子上。並且規定,在小圓盤上不能放大圓盤,在三根柱子之間一次只能移動一個圓盤。
我們姑且不去追溯傳說的緣由,現考慮一下把64片金片,由一根針上移到另一根針上,並且始終保持上小下大的順序。這需要多少次移動呢?這里需要遞歸的方法。假設有n片,移動次數是f(n).顯然f(1)=1,f(2)=3,f(3)=7,且f(k+1)=2*f(k)+1。此后不難證明f(n)=2^n-1。n=64時,
假如每秒鍾一次,共需多長時間呢?一個平年365天有31536000 秒,閏年366天有31622400秒,平均每年31556952秒,我們用多功能計算器計算一下:
18446744073709551615秒
這表明移完這些金片需要5845.54億年以上,而地球存在至今不過45億年,太陽系的預期壽命據說也就是數百億年。真的過了5845.54億年,不說太陽系和銀河系,至少地球上的一切生命,連同梵塔、廟宇等,都早已經灰飛煙滅。
2.代碼實現
遞歸實現相當簡單,不過多解釋就直接附上C++代碼
1 #include <cstdio> 2 #include <cstring> 3 4 void hanio(int n,char a,char b,char c){ 5 //臨界條件:只剩一個盤 6 if(n==1) printf("%d號圓盤 :%c --> %c\n",n,a,c); 7 else { 8 hanio(n-1,a,c,b); 9 printf("%d號圓盤 :%c --> %c\n",n,a,c); 10 hanio(n-1,b,a,c); 11 } 12 } 13 int main(){ 14 int n; 15 printf("本漢諾塔游戲為從A柱子移到C柱子。\n請輸入開始一共圓盤個數n:"); 16 while(scanf("%d",&n)==1){ 17 hanio(n,'A','B','C'); 18 printf("輸出結束!\n繼續輸入n:"); 19 } 20 return 0; 21 }
3.測試結果:
結語:
遞歸在算法中很常見,是一種非常重要的思想。這次就以介紹漢諾塔的實現作為引子,后續還會繼續更新更多遞歸算法。敬請關注!