看完必会的汉诺塔以及递归理解

长篇警告

全部都是在学习过程中自己的理解,若其中有误请及时提出,以便修改

递归是我们学习过程中必不可少的一部分,很多刚入门的同学无法理解递归的含义,或者只是知道这是一种自己调用自己的函数,但是并不知道原理以及原因。

在递归调用中,有直接调用自己和间接调用自己。无论是直接还是间接都是相同的,没有什么差别。

递归

在我看来的递归,就是将一个大问题拆分为自己本身与子问题的过程,然后逐步解决子问题(当自己本身没有子问题时即递归结束)。当子问题全部解决完,大问题也将轻而易举地完成。

可能上述的话有点不好理解,接下来我将用阶乘的例子说明!

在此定义一个递归函数fun()

int fun(int n)
{
	if(1 == n)
	{
		return 1;
	}
	else
	{
		return n*fun(n-1);
	}
}

假如此时需要计算4!

那么大问题就是解决4!,自身就是4,子问题便是3!

【说明】当知道3!的结果时,便可轻松解决4!。因此,可将大问题拆解为,“自己本身–>4”和“子问题–>3!”;

  1. 第一步:拆解为【 "4"和“3!”】
  2. 第二步:将3!作为下一个大问题,拆解【“ 3 ” 和 “ 2!”】
  3. 第三步:将2!作为下一个大问题,拆解【" 2 " 和 " 1! "】

此时1!再没有子问题,因此递归结束!!!

将所有的子问题与本身结合便可得出大问题的结果!

汉诺塔

汉诺塔很多在学习的时候并未真正的理解,或许只是知道原理,知道代码怎么写,但是完全凭借记忆力,背下来的代码!

接下来我就图形解读代码解读!从原理到代码的一步一步的理解!

汉诺塔是学习递归中的经典例子之一!

首先我们需要知道物理中的一种方法便是"整体法"。利用上述所说,便是将所有的子问题看成一个整体,之后再慢慢解决。

汉诺塔图解原理

其中有3个柱子,为X、 Y、 Z。分别赋予其他名字。此时称X为移动柱,Y为借助柱,Z为目标柱子!
在这里插入图片描述
如图!假设此时有4个盘子,需要从X依次移到Z上。

此时将问题拆解。【自己本身–>第四个盘子从X到Z】【子问题–>前三个视为整体移到Y】

在这里插入图片描述

在这里插入图片描述

(此时前三个盘子在Y柱上,便称Y为移动柱)

继续将子问题拆解。【自己本身–>第三个盘子从Y到Z】【子问题–>前两个视为整体移到X】

在这里插入图片描述
继续拆解。【自己本身–>第二个盘子从X到Z】【子问题–>将最上面的盘子从X移到Y】

汉诺塔代码解读

因此,图的逻辑便为如此。接下来是代码的解读!

重点

第一个参数为盘子数,第二个参数是移动柱,第三个参数是借助柱,第四个参数是目标柱。每次的移动柱和借助柱都互换,所以每次函数调用时参数内容不同!!切不可认为每次移动柱与借助柱一成不变!!!


void hanoi(int n,char X,char Y,char Z)
{
	if(1 == n)
	{	
		printf("%c-->%c\n",X,Z);
	}
	else
	{
		hanoi(n-1,X,Z,Y);//将n-1个盘子从移动柱X,利用借助柱子Z,移动到目标柱Y上
		printf("%c-->%c\n",X,Z);//将第n个盘子直接从X-->Z
		hanoi(n-1,Y,X,Z);//将剩下的n-1盘子,从移动柱Y,利用借助柱X,移动到目标柱Z上	
	}
}

【说明】:在函数调用时,若此时该函数调用未全部执行完,就不会继续向下执行代码!

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值