python實現漢諾塔的圖解遞歸算法


寫在前面

工作閑來無事,看了python,寫了一個漢諾塔。

還是蠻喜歡python這門語言的,很簡潔。

 

正文

 

 

 

一.起源:

漢諾塔(又稱河內塔)問題是源於印度一個古老傳說的益智玩具。大梵天創造世界的時候做了三根金剛石柱子,在一根柱子上從下往上按照大小順序摞着64片黃金圓盤。大梵天命令婆羅門把圓盤從下面開始按大小順序重新擺放在另一根柱子上。並且規定,在小圓盤上不能放大圓盤,在三根柱子之間一次只能移動一個圓盤。

二.抽象為數學問題:

如下圖所示,從左到右有A、B、C三根柱子,其中A柱子上面有從小疊到大的n個圓盤,現要求將A柱子上的圓盤移到C柱子上去,期間只有一個原則:一次只能移到一個盤子且大盤子不能在小盤子上面,求移動的步驟和移動的次數

 

解:(1)n == 1

第1次 1號盤 A---->C sum = 1 次

(2) n == 2

第1次 1號盤 A---->B

第2次 2號盤 A---->C

第3次 1號盤 B---->C sum = 3 次

(3)n == 3

第1次 1號盤 A---->C

第2次 2號盤 A---->B

第3次 1號盤 C---->B

第4次 3號盤 A---->C

第5次 1號盤 B---->A

第6次 2號盤 B---->C

第7次 1號盤 A---->C sum = 7 次

不難發現規律

  • 1個圓盤的次數 2的1次方減1
  • 2個圓盤的次數 2的2次方減1
  • 3個圓盤的次數 2的3次方減1
  • 。 。 。 。 。
  • n個圓盤的次數 2的n次方減1

故:移動次數為:2^n - 1

三.調用方法的棧機制:(特點:先進后出)

從主線程開始調用方法(函數)進行不停的壓棧和出棧操作,函數的調用就是將函數壓入棧中,函數的結束就是函數出棧的過程,這樣就保證了方法調用的順序流,即當函數出現多層嵌套時,需要從外到內一層層把函數壓入棧中,最后棧頂的函數先執行結束(最內層的函數先執行結束)后出棧,再倒數第二層的函數執行結束出棧,到最后,第一個進棧的函數調用結束后從棧中彈出回到主線程,並且結束。

四.算法分析(遞歸算法):

我們在利用計算機求漢諾塔問題時,必不可少的一步是對整個實現求解進行算法分析。到目前為止,求解漢諾塔問題最簡單的算法還是通過遞歸來求,至於是什么是遞歸,遞歸實現的機制是什么,我們說的簡單點就是自己是一個方法或者說是函數,但是在自己這個函數里有調用自己這個函數的語句,而這個調用怎么才能調用結束呢?,這里還必須有一個結束點,或者具體的說是在調用到某一次后函數能返回一個確定的值,接着倒數第二個就能返回一個確定的值,一直到第一次調用的這個函數能返回一個確定的值。

實現這個算法可以簡單分為三個步驟:

(1) 把n-1個盤子由A 移到 B;

(2) 把第n個盤子由 A移到 C;

(3) 把n-1個盤子由B 移到 C;

從這里入手,在加上上面數學問題解法的分析,我們不難發現,移到的步數必定為奇數步:

(1)中間的一步是把最大的一個盤子由A移到C上去;

(2)中間一步之上可以看成把A上n-1個盤子通過借助輔助塔(C塔)移到了B上,

(3)中間一步之下可以看成把B上n-1個盤子通過借助輔助塔(A塔)移到了C上;

五.python代碼實現

def move(n,a,b,c):
  if n == 1:
      print(a,'-->',c)
      return None
  else:
       move(n-1,a,c,b)
       print(a,'-->',c)
       move(n-1,b,a,c)

print(move(3, 'A', 'B', 'C'))

六.圖解程序運行流程

 

 

七.程序打印截圖

八.總結

關鍵點:

  1. 算法分析
  2. 遞歸思維
  3. python語句

附:草稿截圖

這個實例,讓我領略了算法的魅力,python語句好簡潔,優美,如果用其他語言,可能要多很多代碼。

本文第一次是發布在公眾號上,原文鏈接


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM