
二叉树的叉树递归遍历
这次我们要好好谈一谈递归,为什么很多同学看递归算法都是归遍“一看就会,一写就废”。历套路都里
主要是叉树对递归不成体系,没有方法论,归遍每次写递归算法 ,历套路都里都是叉树靠玄学来写代码,代码能不能编过都靠运气。归遍
本篇将介绍前后中序的历套路都里递归写法,一些同学可能会感觉很简单,叉树其实不然,归遍我们要通过简单题目把方法论确定下来,历套路都里有了方法论,叉树后面才能应付复杂的归遍递归。
这里帮助大家确定下来递归算法的历套路都里三个要素。每次写递归,都按照这三要素来写,可以保证大家写出正确的递归算法!
确定递归函数的参数和返回值:确定哪些参数是递归的过程中需要处理的,那么就在递归函数里加上这个参数, 并且还要明确每次递归的返回值是什么进而确定递归函数的云服务器返回类型。
确定终止条件:写完了递归算法, 运行的时候,经常会遇到栈溢出的错误,就是没写终止条件或者终止条件写的不对,操作系统也是用一个栈的结构来保存每一层递归的信息,如果递归没有终止,操作系统的内存栈必然就会溢出。
确定单层递归的逻辑:确定每一层递归需要处理的信息。在这里也就会重复调用自己来实现递归的过程。
好了,我们确认了递归的三要素,接下来就来练练手:
以下以前序遍历为例:
确定递归函数的参数和返回值:因为要打印出前序遍历节点的数值,所以参数里需要传入vector在放节点的数值,除了这一点就不需要在处理什么数据了也不需要有返回值,所以递归函数返回类型就是void,代码如下:
void traversal(TreeNode* cur, vector<int>& 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<int>& vec) { if (cur == NULL) return; vec.push_back(cur->val); // 中 traversal(cur->left, vec); // 左 traversal(cur->right, vec); // 右 } vector<int> preorderTraversal(TreeNode* root) { vector<int> result; traversal(root, result); return result; } }; 那么前序遍历写出来之后,中序和后序遍历就不难理解了,代码如下:
中序遍历:
void traversal(TreeNode* cur, vector<int>& vec) { if (cur == NULL) return; traversal(cur->left, vec); // 左 vec.push_back(cur->val); // 中 traversal(cur->right, vec); // 右 } 后序遍历:
void traversal(TreeNode* cur, vector<int>& vec) { if (cur == NULL) return; traversal(cur->left, vec); // 左 traversal(cur->right, vec); // 右 vec.push_back(cur->val); // 中 } 此时大家可以做一做leetcode上三道题目,分别是:
144.二叉树的服务器托管前序遍历 145.二叉树的后序遍历 94.二叉树的中序遍历 可能有同学感觉前后中序遍历的递归太简单了,要打迭代法(非递归),别急,我们明天打迭代法,打个通透!
其他语言版本
Java:
// 前序遍历·递归·LC144_二叉树的前序遍历 class Solution { ArrayList<Integer> preOrderReverse(TreeNode root) { ArrayList<Integer> result = new ArrayList<Integer>(); preOrder(root, result); return result; } void preOrder(TreeNode root, ArrayList<Integer> result) { if (root == null) { return; } result.add(root.val); // 注意这一句 preOrder(root.left, result); preOrder(root.right, result); } } // 中序遍历·递归·LC94_二叉树的中序遍历 class Solution { public List<Integer> inorderTraversal(TreeNode root) { List<Integer> res = new ArrayList<>(); inorder(root, res); return res; } void inorder(TreeNode root, List<Integer> list) { if (root == null) { return; } inorder(root.left, list); list.add(root.val); // 注意这一句 inorder(root.right, list); } } // 后序遍历·递归·LC145_二叉树的后序遍历 class Solution { public List<Integer> postorderTraversal(TreeNode root) { List<Integer> res = new ArrayList<>(); postorder(root, res); return res; } void postorder(TreeNode root, List<Integer> 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 【编辑推荐】
手把手教你使用Python轻松打造淘宝主图视频生成神器 为什么 NanoID 会取代 UUID 加密货币世界中的黑客预防与缓解 最近腾讯35岁员工薪资曝光,你这辈子还能追得上吗?