用遞歸方法解決漢諾塔問題(Recursion Hanoi Tower Python)
阿新 • • 發佈:2017-11-21
else tro 如果 strong noi ron 最小 傳說 大小
漢諾塔問題源於印度的一個古老傳說:梵天創造世界的時候做了三根金剛石柱子,在一根柱子上從下往上按照大小順序摞著64片黃金圓盤。梵天命令婆羅門把圓盤按大小順序重新擺放在另一根柱子上,並且規定小圓盤上不能放大圓盤,在三根柱子之間一次只能移動一個圓盤。當所有的黃金圓盤都重新擺放在另一根柱子上時,世界就將在霹靂聲中毀滅,梵塔、廟宇和眾生都將同歸於盡。
假設A是起始柱,B是中間柱,C是目標柱。
從最簡單的例子開始看:
- 如果A柱上只剩一個圓盤,那麽將圓盤從A柱移到C柱即可。 (A --> C)
- 如果A柱上剩兩個圓盤,那麽先將小圓盤從A柱移到B柱,再將大圓盤從A柱移到C柱,最後將B柱上的小圓盤移到C柱。(A --> B, A --> C, B --> C)
- 如果A柱上剩三個圓盤,那麽先將最小的圓盤從A柱移到C柱,再將中間大小的圓盤從A柱移到B柱,然後將C柱上的最小的圓盤移到B柱,然後將A柱上的最大的圓盤移到C柱,然後將B柱上的最小的圓盤移到A柱,繼續將B柱上的中間大小的圓盤移到C柱,最後將A柱上的最小的圓盤移到C柱。 (A -->C, A -->B, C --> B, A --> C, B --> A, B --> C, A --> C) --- 前三步(A -->C, A -->B, C --> B)可以看成是A --> B的過程,中間是A --> C的過程,最後三步(B --> A, B --> C, A --> C)可以看成是B --> C的過程
綜上所述,如果需要移動n個圓盤,那麽整個過程可以抽象成以下三個步驟:
1. 將除底盤以外的圓盤(n-1個圓盤)從A柱移動到B柱
2. 將底盤從A柱移動到C柱
3. 將B柱上的圓盤(n-1個圓盤)移動到C柱
從最復雜的例子開始看:
- 如果A柱上有64個圓盤,最簡單的做法是把A柱上的64個圓盤想象成一共是2個圓盤(底盤是一個圓盤,底盤上面的63個圓盤是一個圓盤),這樣的話,只需先將A柱上的63個圓盤移動到B柱,再將底盤從A柱移到C柱,最後將B柱上的63個圓盤移到C柱。
- 如果A柱上有63個圓盤,則把A柱上的63個圓盤想象成一共是2個圓盤(底盤是一個圓盤,底盤上面的62個圓盤是一個圓盤),這樣的話,只需先將A柱上的62個圓盤移動到B柱,再將底盤從A柱移到C柱,最後將B柱上的62個圓盤移到C柱。
- 以此類推,直到A柱上只剩一個圓盤,然後將該圓盤從A柱移到C柱即可。
綜上可以看出,通過不斷重復嵌套,這個問題可以用遞歸方法解決。
代碼如下:
def hanoi(n,a,b,c): # n表示需要移動幾個圓盤,a代表起始柱,b代表中間柱,c代表目標柱 if n==1: # 如果只剩1個圓盤,那麽將圓盤從a柱移動c柱即可 print(a,"->",c) else: # 當n > 1時,用抽象出的3步來移動 hanoi(n-1,a,c,b) # 將n-1個圓盤從a移動到b print(a,"->",c) # 將底盤從a移動到c hanoi(n-1,b,a,c) # 將b上的n-1個圓盤移動到c
試一下移動3個圓盤的步驟是否和前文一致:
hanoi(3,"A","B","C")
運行結果如下:
A -> C
A -> B
C -> B
A -> C
B -> A
B -> C
A -> C
可以看出,移動3個圓盤需要7步。根據推算,移動n個圓盤需要2n-1步。假設每次移動一個圓盤都是1秒鐘的時間,婆羅門不停地在移動圓盤,那麽總共需要(264-1)秒的時間,世界就會毀滅。按一年365天計,需要584,942,417,355.072年世界才會毀滅。
用遞歸方法解決漢諾塔問題(Recursion Hanoi Tower Python)