现在的位置: 首页 > 综合 > 正文

递归思想的使用之汉罗塔问题

2018年03月20日 ⁄ 综合 ⁄ 共 1091字 ⁄ 字号 评论关闭

递归,一句话概括就是:把大问题分解成结构类似的小问题,分解,计算小问题,再合并(即子函数的返回)。

汉罗塔问题描述:

有三个杆子,依次标记为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


抱歉!评论已关闭.