这次我们要好好谈一谈递归,为什么很多同学看递归算法都是“一看就会,一写就废”。

成都创新互联始终致力于在企业网站建设领域发展。秉承“创新、求实、诚信、拼搏”的企业精神,致力为企业提供全面的网络宣传与技术应用整体策划方案,为企业提供包括“网站建设、成都响应式网站建设、手机网站建设、微信网站建设、微信平台小程序开发、商城网站开发、平台网站建设秉承"和谐、参与、激情"的文化,与客户和合作伙伴齐心协力一起成长,共同发展。
主要是对递归不成体系,没有方法论,每次写递归算法 ,都是靠玄学来写代码,代码能不能编过都靠运气。
本篇将介绍前后中序的递归写法,一些同学可能会感觉很简单,其实不然,我们要通过简单题目把方法论确定下来,有了方法论,后面才能应付复杂的递归。
这里帮助大家确定下来递归算法的三个要素。每次写递归,都按照这三要素来写,可以保证大家写出正确的递归算法!
确定递归函数的参数和返回值:确定哪些参数是递归的过程中需要处理的,那么就在递归函数里加上这个参数, 并且还要明确每次递归的返回值是什么进而确定递归函数的返回类型。
确定终止条件:写完了递归算法, 运行的时候,经常会遇到栈溢出的错误,就是没写终止条件或者终止条件写的不对,操作系统也是用一个栈的结构来保存每一层递归的信息,如果递归没有终止,操作系统的内存栈必然就会溢出。
确定单层递归的逻辑:确定每一层递归需要处理的信息。在这里也就会重复调用自己来实现递归的过程。
好了,我们确认了递归的三要素,接下来就来练练手:
确定递归函数的参数和返回值:因为要打印出前序遍历节点的数值,所以参数里需要传入vector在放节点的数值,除了这一点就不需要在处理什么数据了也不需要有返回值,所以递归函数返回类型就是void,代码如下:
- void traversal(TreeNode* cur, vector
 & vec) 
确定终止条件:在递归的过程中,如何算是递归结束了呢,当然是当前遍历的节点是空了,那么本层递归就要要结束了,所以如果当前遍历的这个节点是空,就直接return,代码如下:
- if (cur == NULL) return;
 
确定单层递归的逻辑:前序遍历是中左右的循序,所以在单层递归的逻辑,是要先取中节点的数值,代码如下:
- vec.push_back(cur->val); // 中
 - traversal(cur->left, vec); // 左
 - traversal(cur->right, vec); // 右
 
单层递归的逻辑就是按照中左右的顺序来处理的,这样二叉树的前序遍历,基本就写完了,在看一下完整代码:
前序遍历:
- class Solution {
 - public:
 - void traversal(TreeNode* cur, vector
 & vec) { - if (cur == NULL) return;
 - vec.push_back(cur->val); // 中
 - traversal(cur->left, vec); // 左
 - traversal(cur->right, vec); // 右
 - }
 - vector
 preorderTraversal(TreeNode* root) { - vector
 result; - traversal(root, result);
 - return result;
 - }
 - };
 
那么前序遍历写出来之后,中序和后序遍历就不难理解了,代码如下:
中序遍历:
- void traversal(TreeNode* cur, vector
 & vec) { - if (cur == NULL) return;
 - traversal(cur->left, vec); // 左
 - vec.push_back(cur->val); // 中
 - traversal(cur->right, vec); // 右
 - }
 
后序遍历:
- void traversal(TreeNode* cur, vector
 & vec) { - if (cur == NULL) return;
 - traversal(cur->left, vec); // 左
 - traversal(cur->right, vec); // 右
 - vec.push_back(cur->val); // 中
 - }
 
此时大家可以做一做leetcode上三道题目,分别是:
可能有同学感觉前后中序遍历的递归太简单了,要打迭代法(非递归),别急,我们明天打迭代法,打个通透!
Java:
- // 前序遍历·递归·LC144_二叉树的前序遍历
 - class Solution {
 - ArrayList
 preOrderReverse(TreeNode root) { - ArrayList
 result = new ArrayList (); - preOrder(root, result);
 - return result;
 - }
 - void preOrder(TreeNode root, ArrayList
 result) { - if (root == null) {
 - return;
 - }
 - result.add(root.val); // 注意这一句
 - preOrder(root.left, result);
 - preOrder(root.right, result);
 - }
 - }
 - // 中序遍历·递归·LC94_二叉树的中序遍历
 - class Solution {
 - public List
 inorderTraversal(TreeNode root) { - List
 res = new ArrayList<>(); - inorder(root, res);
 - return res;
 - }
 - void inorder(TreeNode root, List
 list) { - if (root == null) {
 - return;
 - }
 - inorder(root.left, list);
 - list.add(root.val); // 注意这一句
 - inorder(root.right, list);
 - }
 - }
 - // 后序遍历·递归·LC145_二叉树的后序遍历
 - class Solution {
 - public List
 postorderTraversal(TreeNode root) { - List
 res = new ArrayList<>(); - postorder(root, res);
 - return res;
 - }
 - void postorder(TreeNode root, List
 list) { - if (root == null) {
 - return;
 - }
 - postorder(root.left, list);
 - postorder(root.right, list);
 - list.add(root.val); // 注意这一句
 - }
 - }
 
Python:
- # 前序遍历-递归-LC144_二叉树的前序遍历
 - class Solution:
 - def preorderTraversal(self, root: TreeNode) -> List[int]:
 - # 保存结果
 - result = []
 - def traversal(root: TreeNode):
 - if root == None:
 - return
 - result.append(root.val) # 前序
 - traversal(root.left) # 左
 - traversal(root.right) # 右
 - traversal(root)
 - return result
 - # 中序遍历-递归-LC94_二叉树的中序遍历
 - class Solution:
 - def inorderTraversal(self, root: TreeNode) -> List[int]:
 - result = []
 - def traversal(root: TreeNode):
 - if root == None:
 - return
 - traversal(root.left) # 左
 - result.append(root.val) # 中序
 - traversal(root.right) # 右
 - traversal(root)
 - return result
 - # 后序遍历-递归-LC145_二叉树的后序遍历
 - class Solution:
 - def postorderTraversal(self, root: TreeNode) -> List[int]:
 - result = []
 - def traversal(root: TreeNode):
 - if root == None:
 - return
 - traversal(root.left) # 左
 - traversal(root.right) # 右
 - result.append(root.val) # 后序
 - traversal(root)
 - return result
 
Copyright © 2009-2022 www.wtcwzsj.com 青羊区广皓图文设计工作室(个体工商户) 版权所有 蜀ICP备19037934号