漢諾塔問題圖解--超簡單方案

漢諾塔問題是大家理解遞歸的一個基礎問題。看了很多博客都不是很理解,下面我將從最簡單的解法爲大家講解:

1.首先是一個盤子,即A塔上有1個盤子的情況(Emmm,畫圖水平有限,僅限說明問題);

這是我們只需要將A中的盤子移到C中,經過一次操作即可:The 1:{A}-->{C}

2.兩個盤子的情況:

只需要進行如上三步就可以:

The 1:{A}-->{B}               The 2:{A}-->{C}              The 3:{B}-->{C}            

從這三步我們可以看出,我們這裏將B作爲一個緩衝柱來看待。先將小盤移到B,再將大盤移到C,然後再把小盤移到C。

3.兩個盤子可能還是發現不了規律,我們再推廣成三個盤子看一下:

通過以上七步,我們可以驗證A中有兩個盤子的結論,我們不斷地將A柱和B柱當成緩衝柱。將所有盤子移動到C柱上。

在這裏,我們思考一下:

解決三個盤子的問題可不可以看成解決兩個盤子的問題呢?

我們把三個盤子的上邊兩個小盤子看成一個盤子。

然後我們要如何處理呢?

這樣是不是就變成了兩個盤子的移動。

當N變成64,也就是初始A柱上有64個盤子時,我們把前63個盤子看成一個整體移動到B,然後把第64個最大的盤子移動到C,最後再把B柱上的63個盤子看成一個整體移動到C盤上。這就相當於把64個盤子的規模轉化成了63個盤子

那麼63個盤子要如何移動呢?

我們把前62個盤子看成一個整體,把前62個盤子從A柱移動到B柱,然後再把第63個大盤子從A柱移動到C柱,最後將B柱上的62個盤子堪稱一個 整體移動到C柱上,就完成了63個盤子的移動。

以此類推:

我們會發現問題規模會不斷的縮小。直到1個盤子的情況。

例如。N初始值爲3,即A上有三個盤子:

通過我們的遞推求解,要想解決三個盤子的情況,先解決 n-1即2個盤子的情況。

要想解決兩個盤子的情況要先解決n-1即1個盤子的情況。

我們把一個盤子從A移動到C後,遞歸回溯,再把第二個盤子從A移動到B,最後把C上的盤子移動到B上,這樣兩個盤子的情況解決完,接着解決三個盤子的情況,把最後最大的盤子移動到C,然後把B中的最小盤子移動到A,然後把B中的第二個盤子移動到C,最後把A中的最小盤子移動到C,就成功解決了問題。

最後貼一下代碼:

#include<iostream>
using namespace std;
int i=0;
//n:A中初始的盤子數量
//a:A柱的名稱
//b:B柱的名稱
//c:C柱的名稱 
int hannuota(int n,char a,char b,char c)
{
	if(n==1)
	{
		i++;
		printf("The %d:{%c}-->{%c}\n",i,a,c);//如果只有一個盤子就直接從A移動到C 
	}	
	else
	{
		hannuota(n-1,a,c,b);//把n-1個盤子看成一個整體從A移動到B 
		hannuota(1,a,b,c);  //最大的一個盤子移動到C 
		hannuota(n-1,b,a,c);//最後把B中的n-1個盤子看成一個整體移動到B 
	}
} 
int main()
{
	hannuota(3,'a','b','c');
	return 0;
} 

代碼完全按照以上分析的思想進行撰寫。

有同學可能對遞歸不太瞭解,這裏以N=3對遞歸進行分析,如圖:

感覺大家觀看,有什麼寫的不好的不對的地方請留言給出。謝謝。嘿嘿。

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