汉诺塔问题是大家理解递归的一个基础问题。看了很多博客都不是很理解,下面我将从最简单的解法为大家讲解:

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对递归进行分析,如图:

感觉大家观看,有什么写的不好的不对的地方请留言给出。谢谢。嘿嘿。