浅入快出--递归之汉诺塔(二)

引言

“枪炮分长短,佼人有深浅”

在第一篇递归方法论的文章中,我们讨论了如何将问题高效地进行分解,以便于提高程序的计算效率,上一篇文章的地址如下:

http://blog.csdn.net/huzhiyuan0000000/article/details/73896491

求解斐波那契数列是递归方法的简单应用,那么如何使用递归方法解决比较繁琐的问题呢?

我们这里就举一个比较经典的例子--汉诺塔(Tower of Hanoi)问题,该问题具体规则如下:

  • 有A,B,C三根木杆,A杆上由下到上有大,中,小三个圆盘,现在按照以下要求将三个圆盘从A杆移动到C杆。
  1. 每次移动一个圆盘;
  2. 尺寸大的圆盘不能放在尺寸小的圆盘上。


解题思路

1.首先我们只考虑大盘,将中,小盘作为整体,那么归位的过程如下(A杆为源杆,C杆为目标杆):





2.那么中,小盘怎样才可以实现从A杆到B杆呢?此时我们就要只考虑中盘了,A杆为源杆,B杆为目标杆,过程如下:




注意思路2里面的目标杆与思路1里面的目标杆不同,但是有没有发现,思路2和思路1中的移动顺序及其的相似呢?


3.上一个思路中已经将中,小两个盘从A杆移动到B杆,最后,我们参照思路2将中,小两个盘从B杆移动到C杆就大功告成了,此时的B杆为源杆,C杆为目标杆。


我们将以上三个思路总结一下,就可以得出:

//n个圆盘,圆盘从小到大为 1→n
//a为源杆,b为过渡杆,c为目标杆 
void Hanoi(int n, char a,char b,char c)
{
	//思路2:将n-1个圆盘从A杆到B杆 
	Hanoi(n - 1, a, c, b);
	//思路1:将最大的圆盘从A杆到C杆 
	Move(n, a, c);
	//思路3:将n-1个圆盘从B杆到C杆 
	Hanoi(n - 1, b, a, c);
}
将以上伪代码可以整理为:

int count;
void Move(int n, char a, char b)
{
    count++;
    printf("第%d次移动 Move %d: Move from %c to %c !\n",count,n,a,b);
}

void Hanoi(int n, char a, char b, char c)
{
    if (n == 1)
    {
        Move(n, a, c);
    }
    else
    {
        Hanoi(n - 1, a, c, b);
        Move(n, a, c);
        Hanoi(n - 1, b, a, c);
    }
}

int main()
{
    int n;
    printf("请输入汉诺塔的层数:");
    scanf(" %d",&n);
    Hanoi(n, 'A', 'B', 'C');
    return 0;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值