【问题描述】
问题描述:假设有3个分别命名为A、B、C的塔座,在塔座A上插有n个直径大小各不同,从小到大标号为1,2,….,n的圆盘,要求将塔座A上的n个圆盘移动到C盘上,并且仍按原来的顺序叠排。
同时遵循下列规则:
每次只能移动一个圆盘;
圆盘可以插在A、B、C中的任一塔座上;
任何时刻都不能将一个较大的圆盘压在较小的圆盘之上。
【解决思路】
递归思想
当有3个圆盘时,移动起来是很简单的。
那么当有多个圆盘时,把最底层的两个圆盘除外,上面的所有圆盘当作整体,然后在研究这个“整体”,这样相当于还是在研究3个圆盘的情况。如果上面的整体数量还很多,可以继续对其使用整体思想,这也就是所谓的递归。
而上述算法,则是一直递归到n=1为止,然后在把递归,一层层“翻”出来!
递归算法优缺点:
优点:程序结构清晰,形式简洁但递归程序在执行时需要系统提供隐式的工作栈来保存调用过程中的参数、局部变量和返回地址。
缺点:占用内存空间多,运行效率较低。
与此类似的还有八皇后问题,迷宫问题等。
个人理解:
其实就是两块,B为辅助杆,想办法先把上面一堆先放到B杆上,再把最下面最大的一个放到C上(C上放了最大的,此时就相当于没有放任何圆盘),再把B杆上的一堆移到C杆上。
对于上面一堆的处理,用递归思想,再拆成最大的一个和上面的一堆,再次用此法移动。化大问题为小问题。
整个移动过程:
- 首先A杆上面的一个(其实是一堆)借助C杆,从A杆移动到B杆上,再把最下面最大的一个放到C上,这时A杆为空(这是的B杆就相当于最初的A杆),C杆仍是辅助杆;
- 再把B杆上面的一个(其实是一堆)借助C杆,从B杆移动到A杆上,再把最下面最大的一个放到C上,这时B杆为空(回到最初的样子);
- 再下次,以此类推,递归。
每经历一次这个过程,就会有最大的一块放到C杆上,直至最上面的一个圆盘也放到了C杆上。
(注:上述所说的3个圆盘,是最简单的例子。3个分成最下面的一个和上面的一堆,其实还是主要处理上面一堆的问题,也就是分成两部分)
【算法】
void Hanoi(int n,char A,char B,char C){
//将塔座A上的n个圆盘按规则搬到C上,B做辅助塔
if(n==1) move(A,1,C); //将编号为1的圆盘从A移动到C
else{
Hanoi(n-1,A,C