汉诺塔问题求解

    汉诺塔问题是一个典型的递归问题。

怎么去理解?

实际上就是给你3个固定的圆柱,然后给你若干个盘子在起始圆柱上通过挪动依次搬到最后一根圆柱,但是还是要按照圆盘的大小从小到大排列。具体描述以及三个圆盘的搬移。

汉诺塔问题求解

上图可以看到要完成操作需要执行七次操作,我们再来看4个圆盘的操作

汉诺塔问题求解

可以很清楚的发现是15次移动即可完成

我们往前推移,发现1个圆盘则需要移动一次即可,两个圆盘即可挪动3次

汉诺塔问题求解

我们可以发现一个规律挪动圆盘的次数和盘子的数量有紧密关系

不难得出,T(n) = 2^n-1次挪动

但是我们还可以发现一个规律,那么就是每一个T(n) = 2*T(n-1)+1

我们可以发现3个盘子挪动7次,2个盘子挪动3次,会发现T(3) = 2*T(2)+1

4个盘子挪动15次,3个盘子挪动7次,会发现T(4) = 2*T(3)+1

T(n) = 2*T(n-1)+1

这个式子得出来可以干什么?

我们可以得出来n个盘子挪动的次数可以由n-1个盘子先从A柱子挪动到B柱子,然后将最大的盘子挪动到C柱子,最后再将B柱子的盘子在做n-1次挪动到C柱子即可。

汉诺塔问题求解

所以我们可以使用递归不断重复操作即可的到答案。

参考源代码:

#include<iostream>
using namespace std;

int count(int n)
{
	if(n == 1) return 1;
	else return 2*count(n-1)+1;
}

void hanio(int n,char start,char middle,char end)
{
	if(n == 0){
		return;
	} 
	else
	{
		hanio(n-1,start,end,middle);
		cout<<start<<"->"<<end<<endl;
		hanio(n-1,middle,start,end);
	}
}

int main()
{
	hanio(3,'A','B','C');
	cout<<"一共搬移"<<count(3)<<"次盘子"<<endl;
	return 0;
}