1. 程式人生 > >如何理解漢諾塔的遞迴?

如何理解漢諾塔的遞迴?

在知乎上看到一個比較容易理解的

地址:https://www.zhihu.com/question/24385418

搞清楚遞迴只要搞清兩點:

  1. 結束條件(遞迴出口)
  2. 把問題規模縮小

什麼是遞迴這個問題 李冰答主借用了網路上的一張圖片,非常形象,此處引用一下


出口條件就是圖中的小鯉魚,規模縮小是找個除了規模更小其他都一模一樣的自己

在漢諾塔問題中小鯉魚就是隻有一個盤子的時候


但是如何讓自己規模縮小? 由於小的盤子不能在大的盤子上,最後一個盤子挪的時候前n-1個盤子必須已經被挪開,因此整個問題 被分為三步,如下
經過這樣的分解,一個挪n個盤子的問題被轉化為了: 兩次挪n-1個盤子的過程加一個直接move的 過程。問題規模由n變為n-1,就可以繼續縮小直到找到小鯉魚---只剩一個盤子的情況 用js簡單實現了,對照註釋和前面的解析理解一下:
//把n個盤子借住helper從from柱子挪到to柱子上
function hanoi(n,from,to,helper){
	//判斷是否找到我們的小鯉魚,找到我就直接返回,沒找到我就把自己規模縮小
	if(n==1){
		console.log('move a plate from '+ from + ' to ' + to);
		return;
	}
	hanoi(n-1,from,helper,to);//把n-1個從from挪到helper上,藉助to
	move(from,to);//把第n個盤子直接從from挪到to
	hanoi(n-1,helper,to,from);//把n-1個從helper挪到from上,藉助to
}
//把一個盤子從一個柱子挪到另一個柱子上
function move(from,to)
{
	console.log('move a plate from '+ from + ' to ' + to);
}

最後劃下重點:對於遞迴問題,要抓住兩點:結束條件和如何讓問題規模縮小問題。遞迴問題的正確性是根據數學歸納法來證明的,只要找到這兩點也就可以使用數學歸納法了。
特別注意分析問題的時候不要讓自己按著程式執行的順序鑽進去,這樣會很容易困惑和亂掉,盯準關鍵兩點,問題自然迎刃而解