13 |「递归与树」简析

本文简析了递归的概念,强调其作为循环的另一种形式,以及在解决复杂问题时通过函数自身调用来定义子问题的关键点。文章进一步探讨了树的结构,并详细阐述了如何利用递归进行前序、后序和中序遍历,其中提到前序遍历适用于传递参数,后序遍历适用于计算依赖子节点结果,而中序遍历在二叉搜索树中特别适用。
摘要由CSDN通过智能技术生成

前言

前言:简析「递归与分治」。

一. 递归

1、什么是递归

  • 递归的本质还是一种循环,但是这种循环不是通过 for 或者 while 来实现,而是通过函数体进行循环。

2、特点

  • 函数自身调用自身。
  • 通过函数体来进行的循环(每一个函数体是一个子问题)。
  • 以自相似的方法重复进行的过程。

3、关键点

  • 定义好子问题。
  • 定好边界。

4、模板

void recursion(int level, int param)
{
	// terminator:终止条件
	if (level > MAX_LEVEL) {							//(1)
		// process result:处理过程结果
		return;
	}
	// process logic in current level:当前层的处理逻辑
	process(level, param);								//(2)
	// drill down:向下一层
	recur(level + 1, new_param);						//(3)
	// restore the current level status:恢复当前层状态	//(4)
}
  • (1)终止条件;
  • (2)处理本层信息;
  • (3)递归处理子问题;
  • (4)递归结束前要将所有修改过的全局变量还原
  • 注意:递归函数中的局部变量和参数是不需要恢复的,因为属于每一个函数体,结束时局部变量和参数自动被释放掉。而全局变量共享于所有的函数体(子问题),当一个递归结束时需要还原,一个子问题结束时要回到上一个子问题时,当前子问题对全局变量的修改需要还原成递归前的状态,在进入每一个函数体时,函数体之前的修改不能对后面产生影响。

二、树

1、结构

  • 树是链表结构的扩展,每个节点都有左右指针,用于指向下一个节点。

2、遍历

1)树为什么适合用递归遍历

  • 链表只有一个分叉,可直接采用 for 循环一层遍历;树分两个叉,采用递归进行遍历。
  • 树结构天然具有递归的性质即子树的性质和整个树的性质一致;使用递归可以轻松地将整个树问题转换成子树问题。当层层递归到最小子树时,这个最小子树的解也称为递归出口往往很容易得到,然后再一步步向上回溯就能得到原问题的解。

2)树递归的思路

  • 写出子问题的推导(归纳成一个子问题);
  • 写出终止条件。

3)分类

a、前序遍历(自顶向下)
  • 在每个递归层级上首先访问节点进行计算,并在递归调用函数时将这些值通过参数传递给子树。
b、后序遍历(自底向上)
  • 首先对所有子节点递归调用函数,然后根据返回值和根节点本身的值得到答案,后序遍历依赖左右子树的返回值。
c、中序遍历
  • 适用于二叉搜索树

4)总结

  • 如果能使用参数和节点本身的值来决定应该传递给子节点的参数,就用前序遍历。
  • 对于树中的任意一个节点,如果知道它子节点的答案,就能计算出当前节点的答案,就用后序遍历。
  • 如果遇到二叉搜索树,就用中序遍历。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一个写代码的修车工

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值