C/C++ 漢諾塔問題描述與實現

漢諾塔問題

漢諾塔(tower of hanoil)問題是源於印度一個古老傳說。是遞歸應用中非常經典的一種表現。

問題大致描述如下

假設有A、B、C三個木樁和n個大小均不相同的盤子,從小到大編號依次爲1、2、3 … n,編號越大直徑越大。起初,這些盤子均被套在木樁A上,現在希望將A木樁上的盤子藉助B木樁當橋樑,以最少次數全部移到C木樁上。在移動時還需遵循以下規則:

  1. 每次只能移動一個盤子,而且只能從最上面的盤子開始移動。
  2. 盤子可以從任意一個木樁移動到另一個木樁。
  3. 直徑較小的盤子永遠只能至於直徑較大的盤子之上.

先分析只有一個盤子的情況,根據這些盤子移動步驟,帶來的現象找出漢諾塔問題的規律。

當 n = 1時
移動次數:211=12^{1}-1=1

直接將盤子從A木樁移動到C木樁

當 n = 2時
移動次數:221=32^{2}-1=3

①將1號盤子從A木樁移動到B木樁
②將2號盤子從A木樁移動到C木樁
③將1號盤子從B木樁移動到C木樁

當 n = 3時
移動次數:231=72^{3}-1=7

①將1號盤子從A木樁移動到C木樁
②將2號盤子從A木樁移動到B木樁
③將1號盤子從C木樁移動到B木樁
④將3號盤子從A木樁移動到C木樁
⑤將1號盤子從B木樁移動到A木樁
⑥將2號盤子從B木樁移動到C木樁
⑦將1號盤子從A木樁移動到C木樁

當n的值不大時,我們可以用圖解解決問題,但是當n的值較大時,再用圖解問題就會變得困難。從這三種情況可以大致發現漢諾塔移動的規律,歸納爲3個步驟

1、將n-1個盤子,從木樁A移動到木樁B。
2、將第n個最大盤子,從木樁A移動到木樁C。
3、將n-1個盤子,從木樁B移動到木樁C。

用遞歸方法描述漢諾塔的算法函數
void hanoi(int n, const char *p1, const char *p2, const char *p3)
{
	if(n==1)	//遞歸出口
		cout<<"盤子從"<< p1 <<"移到"<< p3;
	else
	{
		haoni(n-1,p1,p3,p2);
		cout<<"盤子從"<< p1 <<"移動到"<< p3;
		haoni(n-1,p2,p1,p3);
	}
}
移動n個盤子需要的最少移動次數
int hanoi(int n)
{
 if (n == 1)
  return 1;
 else
  return 2 * hanoi(n - 1)+1;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章