昨天看廖雪峰的Python教程,看到了遞歸函數(shù),具體的遞歸函數(shù)看他講的就可以,最好自己好好研究一下遞歸函數(shù)是干啥的,對于學習這一節(jié)有幫助,最后面有一個漢諾塔的練習題,漢諾塔簡單來說就是三根柱子,A,B,C,A上面有N個盤子,比如拿三個舉例子,有大中小三個盤子,然后把這三個盤子從A柱子上移動到C柱子上,在C柱子上的順序也是大中小,這個就是簡單的玩法介紹。


自己可以嘗試玩一下這個游戲,策略就是想辦法先把A柱子上的n-1個盤子先移動到B柱子上,然后再把B柱子上的盤子想辦法移動到C柱子上,總體思路就是這三步,接下來我們看代碼吧:
def move(n,a,b,c):
if n == 1:
print('move',a,'-->',c)
else:
move(n-1,a,c,b)
move(1,a,b,c)
move(n-1,b,a,c)
函數(shù)的第一行是自定義個函數(shù),接下來就是遞歸函數(shù)的結(jié)束條件,最下面就是移動盤子的步驟。
move(n-1,a,c,b)把n-1個盤子通過C移動到B;
move(1,a,b,c)把A柱子上的下面的那個盤子移動到C柱子;
move(n-1,b,a,c)把B柱子上的n-1個盤子移動到C柱子。
這個就是我們前面說的思路,三步走。
執(zhí)行的結(jié)果就是:

這個思路我覺得不難,對于我來說難點是什么呢?上面的運行結(jié)果一步一步怎么出來的呢?我研究了好一陣,因為我對遞歸函數(shù)不了解,問了其他人,查了資料,他們給我的解釋是這樣:
move(3,a,b,c)
move(2,a,c,b)
move(1,a,b,c) //A->C
move(1,a,c,b) //A->B
move(1,c,a,b) //C->B
move(1,a,b,c) //A->C
move(2,b,a,c)
move(1,b,c,a) //B->A
move(1,b,a,c) //B->C
move(1,a,b,c) //A->C
我對于這個我覺得看不懂,實在想不明白,為啥就會運行出來這個結(jié)果呢?函數(shù)到底一步一步怎么執(zhí)行的呢?所以我就用IDE來調(diào)試這段代碼,具體的運行過程是下面這樣:

解釋一下就是n=3的時候,函數(shù)進入了else,然后執(zhí)行move(n-1,a,c,b)此時的函數(shù)參數(shù)變了,之前是a,b,c,現(xiàn)在是a,c,b,一定要記住這個,因為后面需要用到這個,不然理解不了。

此時
n=2,又進入else的第一個函數(shù):
打印
A->C
此時需要注意參數(shù),這個參數(shù)a,c,b,這個參數(shù)是怎么來的呢?就是第一步的解釋,就是
n=2的時候的參數(shù)
打印
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
總結(jié)
遞歸的思想就是把這個目標分解成三個子目標
子目標1:將前n-1個盤子從a移動到b上
子目標2:將最底下的最后一個盤子從a移動到c上
子目標3:將b上的n-1個盤子移動到c上
然后每個子目標又是一次獨立的漢諾塔游戲,也就可以繼續(xù)分解目標直到N為1