昨天看廖雪峰的Python
教程崔步,看到了遞歸函數(shù)缎谷,具體的遞歸函數(shù)看他講的就可以列林,最好自己好好研究一下遞歸函數(shù)是干啥的,對(duì)于學(xué)習(xí)這一節(jié)有幫助希痴,最后面有一個(gè)漢諾塔的練習(xí)題砌创,漢諾塔簡(jiǎn)單來(lái)說(shuō)就是三根柱子,A刽辙,B甲献,C,A上面有N個(gè)盤子晃洒,比如拿三個(gè)舉例子球及,有大中小三個(gè)盤子,然后把這三個(gè)盤子從A柱子上移動(dòng)到C柱子上筹陵,在C柱子上的順序也是大中小际歼,這個(gè)就是簡(jiǎn)單的玩法介紹。
自己可以嘗試玩一下這個(gè)游戲闪朱,策略就是想辦法先把A柱子上的n-1個(gè)盤子先移動(dòng)到B柱子上钻洒,然后再把B柱子上的盤子想辦法移動(dòng)到C柱子上锄开,總體思路就是這三步,接下來(lái)我們看代碼吧:
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ù)的第一行是自定義個(gè)函數(shù)头遭,接下來(lái)就是遞歸函數(shù)的結(jié)束條件癣诱,最下面就是移動(dòng)盤子的步驟撕予。
move(n-1,a,c,b)
把n-1個(gè)盤子通過(guò)C移動(dòng)到B;
move(1,a,b,c)
把A柱子上的下面的那個(gè)盤子移動(dòng)到C柱子;
move(n-1,b,a,c)
把B柱子上的n-1個(gè)盤子移動(dòng)到C柱子实抡。
這個(gè)就是我們前面說(shuō)的思路,三步走赏淌。
執(zhí)行的結(jié)果就是:
這個(gè)思路我覺(jué)得不難六水,對(duì)于我來(lái)說(shuō)難點(diǎn)是什么呢?上面的運(yùn)行結(jié)果一步一步怎么出來(lái)的呢鼠冕?我研究了好一陣胯盯,因?yàn)槲覍?duì)遞歸函數(shù)不了解,問(wèn)了其他人憎乙,查了資料叉趣,他們給我的解釋是這樣:
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
我對(duì)于這個(gè)我覺(jué)得看不懂,實(shí)在想不明白阵谚,為啥就會(huì)運(yùn)行出來(lái)這個(gè)結(jié)果呢烟具?函數(shù)到底一步一步怎么執(zhí)行的呢朝聋?所以我就用IDE來(lái)調(diào)試這段代碼,具體的運(yùn)行過(guò)程是下面這樣:
解釋一下就是n=3
的時(shí)候荔睹,函數(shù)進(jìn)入了else
言蛇,然后執(zhí)行move(n-1,a,c,b)
此時(shí)的函數(shù)參數(shù)變了,之前是a,b,c吨拗,現(xiàn)在是a,c,b,一定要記住這個(gè)翩瓜,因?yàn)楹竺嫘枰玫竭@個(gè)携龟,不然理解不了。
此時(shí)
n=2
坟桅,又進(jìn)入else
的第一個(gè)函數(shù):打印
A->C
此時(shí)需要注意參數(shù)仅乓,這個(gè)參數(shù)a,c,b蓬戚,這個(gè)參數(shù)是怎么來(lái)的呢?就是第一步的解釋豫喧,就是
n=2
的時(shí)候的參數(shù)打印
A-> B
打印
C->B
打印
A->C
打印
B->A
打印
B->C
打印
A->C
這個(gè)就是完整的步驟孵班,一步一步對(duì)照著來(lái)招驴,基本上就能搞明白代碼具體一步一步怎么運(yùn)行的:
上面總共打印了:
A->C
A->B
C->B
A->C
B->A
B->C
A->C
總結(jié)
遞歸的思想就是把這個(gè)目標(biāo)分解成三個(gè)子目標(biāo)
子目標(biāo)1:將前n-1個(gè)盤子從a移動(dòng)到b上
子目標(biāo)2:將最底下的最后一個(gè)盤子從a移動(dòng)到c上
子目標(biāo)3:將b上的n-1個(gè)盤子移動(dòng)到c上
然后每個(gè)子目標(biāo)又是一次獨(dú)立的漢諾塔游戲忽匈,也就可以繼續(xù)分解目標(biāo)直到N為1