用遞歸來解決漢諾塔問題(超詳細的個人解讀)(Python)

一、遞歸的關鍵特徵

1、存在一個或多個基例,基例不需要再次遞歸,它是確定的表達式(是一個能直接算出值的表達式)。

2、所有遞歸鏈要以一個或多個基例結尾。

二、漢諾塔問題

漢諾塔(又稱河內塔)問題是源於印度一個古老傳說的益智玩具。大梵天創造世界的時候做了三根金剛石柱子,在一

根柱子上從下往上按照大小順序摞着64片黃金圓盤。大梵天命令婆羅門把圓盤從下面開始按大小順序重新擺放在另一

根柱子上。並且規定,在小圓盤上不能放大圓盤,在三根柱子之間一次只能移動一個圓盤。
在這裏插入圖片描述
個人理解:首先A爲初始柱子,B爲過渡柱子,C爲目標柱子。

(1)如果當前只有一個盤子,我們可以直接把它從A移動到C。此時也是遞歸中的基例

(2)如果有n個圓盤,那麼我們可以構造出hannt(n,A,C,B),表示n個柱子從A移動到C,此時B爲中間過渡柱子。

第一步:先把A上n-1個柱子移動到B柱子上,此時C柱子爲中間的過渡柱子(我們可以把n-1個柱子看作一個整體),這一步我們便可以用hannt(n-1,A,B,C)

第二步:此時A上只有一個圓盤(最底下的最大的圓盤),把A上的最後一個圓盤移動到C即可(此時C圓盤上爲一個最大的圓盤)。我們可以用print函數來打印出來這一步。

第三步:再把B柱子上的n-1個圓盤移動到C柱子,此時A柱子爲中間過渡柱子。這一步我們可以用hannt(n-1,B,C,A)

三、補充

(如有錯誤,請指出):當把n-1個圓盤移動到B柱子,C柱子上只有一個最大的圓盤時候,相當於C柱子上沒有(因爲C柱子只有一個最大的圓盤)。

此時A柱子上爲空柱子,這不便和n盤子時情形一樣嗎,只是A柱子與B柱子換了換位置。

四、代碼

def hannt(n,a,c,b):
    if n==1:
        print("{}:{}->{}".format(1,a,c))
    else:
        hannt(n-1,a,b,c)
        print("{}:{}->{}".format(n,a,c))
        hannt(n-1,b,c,a)
hannt(3,"A","C","B")

結果:

1:A->C
2:A->B
1:C->B
3:A->C
1:B->A
2:B->C
1:A->C

五、遞歸的補充

1、字符串的逆序輸出

代碼(手機橫屏看):

def reverse(s):
    if s=="":
        return s
    else:
        return reverse(s[1:])+s[0]#s[0]是首字符,s[1:]是剩餘字符串,將它們反向連接,可以得到反字符串
tf=input("請輸入一個字符串:")
print(reverse(tf))

結果:

請輸入一個字符串:abcdef
fedcba

2、斐波那契數列

在這裏插入圖片描述
代碼:

def f(n):
    if n == 1 or n == 2 :
        return 1
    else :
        return f(n-1) + f(n-2)
n=eval(input("請輸入一個整數:"))
x=f(n)
print(x)

結果

請輸入一個整數:5
5
>>> 
==================== RESTART: C:\Users\我的電腦\Desktop\樣本.py ====================
請輸入一個整數:2
1
>>> 
==================== RESTART: C:\Users\我的電腦\Desktop\樣本.py ====================
請輸入一個整數:10
55
>>> 
==================== RESTART: C:\Users\我的電腦\Desktop\樣本.py ====================
請輸入一個整數:9
34

補充:

我總結我所有python筆記於一篇博客裏:
點擊即可進入Python學習筆記大總結(我把我所有python筆記做了總結和學習順序,點擊即可進入相關博客。希望可以便於你們閱讀)

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