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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章