遞歸:解決漢諾塔問題(數據結構3.2 P103)

關於漢諾塔問題我思考了一段時間。最後總結原因之前想不明白還是對遞歸問題沒有深入理解。我的另一篇博文《遞歸詳解》已經很好的介紹了遞歸的原理。


分析漢諾塔問題:由以下三步組成

1 用C做過度,將A柱上的n-1個盤子直接移到C柱上

2 將A柱上的最後一個盤子移動到C柱上。

3  用A做過度,將B柱上的n-1個盤子直接移到C柱上


由此將移動n個盤子的漢諾塔問題歸結爲移動n-1個盤子的漢諾塔問題



然後我們要知道:其實遞歸和自己編寫遞歸函數的方法是相反的。當你要寫一個遞歸函數時你只需要做2步:

1. 在程序中不要把對n-1的調用看做一個一層層深入下去的調用,而只是把他看做一個可以立即完成n-1任務的指令。並使用這個指令解決事件n的問題。

2 將終止遞歸條件適當的放到程序中。(一般的放置位置都是如下放在if條件語句中)


現給出遞歸函數的模板如下:

Result M(Problem prob)
{
if (<problem can be solved easily>)
return <easy solution>;
// The problem cannot be solved easily.
Problem smaller1 = <reduce problem to smaller problem>
Result result1 = M(smaller1);
Problem smaller2 = <reduce problem to smaller problem>
Result result2 = M(smaller2);
...
Result finalResult = <combine all results of smaller problem to solve large problem>
return finalResult;
}



最終我們將漢諾塔的代碼實現如下:

#include <iostream>  
using namespace std;  

void Move(int n,char x,char y){  
	cout<<"把"<<n<<"號從"<<x<<"挪動到"<<y<<endl;  
}  

void Hannoi(int n,char a,char b,char c){  
	if(n==1)  
		Move(1,a,c);  
	else  
	{  
		Hannoi(n-1,a,c,b);  
		Move(n,a,c);  
		Hannoi(n-1,b,a,c);  
	}  
}  

int main()  
{  
	cout<<"以下是7層漢諾塔的解法:"<<endl;  
	Hannoi(7,'A','B','C');  
	cout<<"輸出完畢!"<<endl;  
	
	system("pause");
}  


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