第一次写博客,就挑一个比较简单的题目,比较适合学习算法的新手,题目不复杂,但是初学者可能会面临一些困惑,个人在学过一段时间算法后的一点理解。(仅供参考)
汉诺塔问题描述:
古代有一个寺庙,庙内有三个座A、B、C,A座上有64个盘子,盘子大小不等,大的在下,小的在上。有一个和尚想把这个盘子从A座移到C座,但每次只能允许移动一个盘子,并且在移动过程中,3个座上的盘子始终保持大盘在下,小盘在上。问通过多少步才可以移动成功?据说64个盘子移动成功后会发生意想不到的事。哈哈,一起看看吧。
分析
其实这种题目如果是第一次接触递归的话,可能有点蒙,但是只要大家明白了递归的思想,其实就能一眼看出使用递归求解了,因为递归很方便大众所理解。
“递归算法是一种直接或者间接调用自身函数或者方法的算法。”,这是递归官方的解释,如果对递归不清楚的建议先去学习一下,毕竟递归思想在算法中还是经常会使用的。
好了,正式讲解本题:首先,我们只有三个坐,坐就类似于........enen!![这个样子](https://img-blog.csdnimg.cn/20191126231539285.png)
初始条件下,所有的盘(*假设有n个*)都在A坐上(大的在下,小的在上),题目要求我们移动若干步到C坐。
当n=1时,要想移动到C,只需要一步,就是直接把盘子从A移动到C,不需要借助B盘即可实现。
当n=2时,这时就无法直接移动了,因为要保证大盘在下,小盘在上的原则,此时我们就可以先把A上的最上面的小盘移动到B上,再把A上剩下的那个大盘移动到C上,最后把B上的小盘移动到C上,就完成了本次移动,共花了3步。
当n=3时,先把最小的移动到C上,再把第二小的移动到B上,接着把C上的最小盘移动到B上,A上最大的盘移动到C上,B上最小盘移动到A上,B上次小盘移到C上,A上最小盘移到C上。
其实说白了就是把A上的盘子借助B移到C上,B是起到中间桥梁的作用。
**
递归核心
首先借助C把A上n-1个盘移到B上,此时A仅剩1个,直接移到C上,再把B上的n-1个盘借助A移到C上。
int move(int n,char x,char y,char z) //x借助y移动到z
{
if(n==1)
{
printf("%c--%c\n",x,z);
return 0;
}
else
{
move(n-1,x,z,y);
printf("%c--%c\n",x,z);
move(n-1,y,x,z);
}
}
本次递归的终止条件是当n==1时,输出如何移动,本次调用结束,返回上一层。
具体实现
#include<stdio.h>
int num=0;
int move(int n,char x,char y,char z) //x借助y移动到z
{
if(n==1)
{
printf("%c--%c\n",x,z);
num++;
return 0;
}
else
{
move(n-1,x,z,y);
printf("%c--%c\n",x,z);
num++;
move(n-1,y,x,z);
}
return num;
}
int main()
{
int a;
printf("输入汉诺塔层数:");
scanf("%d",&a);
int c=move(a,'X','Y','Z');
printf("共移动%d次",num);
return 0;
}
运行结果
至于64个盘子,哈哈,有生之年你是无法完成的啦!!!