汉诺塔问题个人理解(附源码C语言)

第一次写博客,就挑一个比较简单的题目,比较适合学习算法的新手,题目不复杂,但是初学者可能会面临一些困惑,个人在学过一段时间算法后的一点理解。(仅供参考)

汉诺塔问题描述:

古代有一个寺庙,庙内有三个座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;
}

运行结果

两个盘子的时候
10个盘子的时候

至于64个盘子,哈哈,有生之年你是无法完成的啦!!!

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值