汉诺塔(Hanoi) ——递归思想

        汉诺塔(Tower of Hanoi),又称河内塔,是一个源于印度古老传说的益智玩具。传说故事可以点这看

        汉诺塔问题是一个经典的数学难题,由 3 根柱子和多个半径不等的圆盘构成,如下图所示:

汉诺塔(Hanoi) ——递归思想_第1张图片

        汉诺塔的操作步骤究竟是什么样的呢,我们可以通过这个游戏来感受一下:点我进入游戏界面

        可见,汉诺塔的大体步骤就如下gif图所示:

汉诺塔(Hanoi) ——递归思想_第2张图片

图片来自:编程帮——汉诺塔问题

        对于汉诺塔问题,易知可以采用分治思想解决,我们可以大致划分为三个步骤解决(设有n个圆盘):

  1. 第 n-1 个圆盘, A -> B;
  2. 第 n 个圆盘,    A -> C;
  3. 第 n-1 个圆盘, B -> C;

        为了能够移动第 n-1 个圆盘从A->B,我们肯定会进行下列操作:

  1. 第 n-2 个圆盘, A -> C;
  2. 第 n-1 个圆盘, A -> B;
  3. 第 n-2 个圆盘, C -> B;

        为了能够移动第 n-1 个圆盘从B->C,我们肯定会进行下列操作:

  1. 第 n-2 个圆盘, B -> A;
  2. 第 n-1 个圆盘, B -> C;
  3. 第 n-2 个圆盘, A -> C;

        当我们要移动第 n-2 个圆盘时,应先移动他上面的圆盘,即重复上述操作……便可以完成汉诺塔游戏。

        这时就可以发现,汉诺塔的拆解过程刚好满足递归算法的定义。

        汉诺塔体现了一种重要的思想:分治思想(递归思想)

6947: 汉诺塔游戏

#include
void hanoi(int n, char x, char y, char z)  //汉诺塔函数
{
        if (n==1)
        {
        	printf("%c -> %c\n",x,z);  //如果只有 1 个圆盘,则直接从X柱移动到Z柱
        }
        else  //递归调用 hanoi() 函数,将 n-1 个圆盘(除了最大的圆盘)从A柱移动到B柱
        {
            hanoi(n-1,x,z,y);  //将A柱上剩余的最后一个大圆盘移动到Z柱上
            printf("%c -> %c\n",x,z);
            hanoi(n-1,y,x,z);  //递归调用 hanoi() 函数,将B柱上的 n-1 圆盘移动到Z柱上
        }
}
int main(void)
{
    int n;
    while(scanf("%d", &n)!=EOF)  //圆盘数量
    {
    	hanoi(n,'A','B','C');  //汉诺塔函数  n个圆盘  3根柱子A、B、C
	}
    return 0;
}

4695: 汉诺塔之最小搬运次数

        汉诺塔问题中,n 个圆盘至少需要 2^n-1 次移动操作。

#include
#include
int main()
{
	int n;
	while(scanf("%d",&n)!=EOF)
	{
		int flag = pow(2,n);  调用pow函数
		printf("%d\n",flag-1);
	}
	return 0;
}

你可能感兴趣的:(汉诺塔(Hanoi) ——递归思想)