递归,一句话概括就是:把大问题分解成结构类似的小问题,分解,计算小问题,再合并(即子函数的返回)。
汉罗塔问题描述:
有三个杆子,依次标记为A,B,C。还有n个大小不同的盘子,较大的盘子放在较小的盘子的下面,依次放置在A杆上,现在要通过若干次操作将所有盘子移到C杆上,且不能违反下列规则:
1.每次只能移动一个盘子
2.不允许大的盘子出现在小的盘子的上面
下面我们来用递归的方法分析一下:
1.分解
把盘子中每两个看成一个整体,以两个位单位进行移动.那么如果n=5,5=3+2,问题3就不具有和大问题相同的结构了(在递归中,分解时需要注意大问题和子问题是否类似,能否通过同一套方法解决)。最终只能分成每次一个盘子的小问题。最终分解方案是n=(n-1)+1,n-1=(n-2)+1,···,2=1+1。描述为:
对于n个盘子而言(起始杆A,介质杆B,目标杆C):(注意每次的起始,介质,目标都不一样)
a.将n-1个盘子从A通过C杆为介质移动到B
b.将第n个盘子从A直接移动到C
c.将n-1个盘子从B通过A杆为介质移动到C
对于n-1个盘子而言(起始杆A,介质杆C,目标杆B):
a.将n-2个盘子从A通过B杆为介质移动到C
b.将第n-1个盘子从A直接移动到B
c.将n-2个盘子从C通过A杆为介质移动到B
总结:
对x个盘子而言(起始s,介质j,目标d)
a.将x-1个盘子从s通过d杆移动到j(第一个必须把x-1个盘移到介质杆上去)
b.将第x个盘子从s直接移动到d
c.将x-1个盘子从j通过s杆移动到d
2.计算
小问题指的是:将一个盘子从A杆移动到C杆,可以不违反任何规则下直接移动了
3.合并
合并是分解的逆过程,汉罗塔问题中就是指子函数的返回
最终程序如下:
#include <stdio.h> void move(int n,char start,char jiezhi,char des) { //n=1时,直接移动 if (n==1) { printf("%c->%c\n",start,des); return; } //将x-1个盘子从s通过d杆移动到j(第一个必须把x-1个盘移到介质杆上去) move(n-1,start,des,jiezhi); //将第x个盘子从s直接移动到d printf("%c->%c\n",start,des); //将x-1个盘子从j通过s杆移动到d move(n-1,jiezhi,start,des); } void main() { move(3,'A','B','C'); }
一起学习,一起进步,欢迎访问我的博客:http://blog.csdn.net/wanghao109