文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

二叉树的递归遍历,套路都在这里

2024-12-03 01:35

关注

主要是对递归不成体系,没有方法论,每次写递归算法 ,都是靠玄学来写代码,代码能不能编过都靠运气。

本篇将介绍前后中序的递归写法,一些同学可能会感觉很简单,其实不然,我们要通过简单题目把方法论确定下来,有了方法论,后面才能应付复杂的递归。

这里帮助大家确定下来递归算法的三个要素。每次写递归,都按照这三要素来写,可以保证大家写出正确的递归算法!

确定递归函数的参数和返回值:确定哪些参数是递归的过程中需要处理的,那么就在递归函数里加上这个参数, 并且还要明确每次递归的返回值是什么进而确定递归函数的返回类型。

确定终止条件:写完了递归算法, 运行的时候,经常会遇到栈溢出的错误,就是没写终止条件或者终止条件写的不对,操作系统也是用一个栈的结构来保存每一层递归的信息,如果递归没有终止,操作系统的内存栈必然就会溢出。

确定单层递归的逻辑:确定每一层递归需要处理的信息。在这里也就会重复调用自己来实现递归的过程。

好了,我们确认了递归的三要素,接下来就来练练手:

以下以前序遍历为例:

确定递归函数的参数和返回值:因为要打印出前序遍历节点的数值,所以参数里需要传入vector在放节点的数值,除了这一点就不需要在处理什么数据了也不需要有返回值,所以递归函数返回类型就是void,代码如下:

  1. void traversal(TreeNode* cur, vector<int>& vec) 

确定终止条件:在递归的过程中,如何算是递归结束了呢,当然是当前遍历的节点是空了,那么本层递归就要要结束了,所以如果当前遍历的这个节点是空,就直接return,代码如下:

  1. if (cur == NULLreturn

确定单层递归的逻辑:前序遍历是中左右的循序,所以在单层递归的逻辑,是要先取中节点的数值,代码如下:

  1. vec.push_back(cur->val);    // 中 
  2. traversal(cur->left, vec);  // 左 
  3. traversal(cur->right, vec); // 右 

单层递归的逻辑就是按照中左右的顺序来处理的,这样二叉树的前序遍历,基本就写完了,在看一下完整代码:

前序遍历:

  1. class Solution { 
  2. public
  3.     void traversal(TreeNode* cur, vector<int>& vec) { 
  4.         if (cur == NULLreturn
  5.         vec.push_back(cur->val);    // 中 
  6.         traversal(cur->left, vec);  // 左 
  7.         traversal(cur->right, vec); // 右 
  8.     } 
  9.     vector<int> preorderTraversal(TreeNode* root) { 
  10.         vector<int> result; 
  11.         traversal(root, result); 
  12.         return result; 
  13.     } 
  14. }; 

那么前序遍历写出来之后,中序和后序遍历就不难理解了,代码如下:

中序遍历:

  1. void traversal(TreeNode* cur, vector<int>& vec) { 
  2.     if (cur == NULLreturn
  3.     traversal(cur->left, vec);  // 左 
  4.     vec.push_back(cur->val);    // 中 
  5.     traversal(cur->right, vec); // 右 

后序遍历:

  1. void traversal(TreeNode* cur, vector<int>& vec) { 
  2.     if (cur == NULLreturn
  3.     traversal(cur->left, vec);  // 左 
  4.     traversal(cur->right, vec); // 右 
  5.     vec.push_back(cur->val);    // 中 

此时大家可以做一做leetcode上三道题目,分别是:

可能有同学感觉前后中序遍历的递归太简单了,要打迭代法(非递归),别急,我们明天打迭代法,打个通透!

其他语言版本

Java:

  1. // 前序遍历·递归·LC144_二叉树的前序遍历 
  2. class Solution { 
  3.     ArrayList<Integer> preOrderReverse(TreeNode root) { 
  4.         ArrayList<Integer> result = new ArrayList<Integer>(); 
  5.         preOrder(root, result); 
  6.         return result; 
  7.     } 
  8.  
  9.     void preOrder(TreeNode root, ArrayList<Integer> result) { 
  10.         if (root == null) { 
  11.             return
  12.         } 
  13.         result.add(root.val);           // 注意这一句 
  14.         preOrder(root.left, result); 
  15.         preOrder(root.right, result); 
  16.     } 
  17. // 中序遍历·递归·LC94_二叉树的中序遍历 
  18. class Solution { 
  19.     public List<Integer> inorderTraversal(TreeNode root) { 
  20.         List<Integer> res = new ArrayList<>(); 
  21.         inorder(root, res); 
  22.         return res; 
  23.     } 
  24.  
  25.     void inorder(TreeNode root, List<Integer> list) { 
  26.         if (root == null) { 
  27.             return
  28.         } 
  29.         inorder(root.left, list); 
  30.         list.add(root.val);             // 注意这一句 
  31.         inorder(root.right, list); 
  32.     } 
  33. // 后序遍历·递归·LC145_二叉树的后序遍历 
  34. class Solution { 
  35.     public List<Integer> postorderTraversal(TreeNode root) { 
  36.         List<Integer> res = new ArrayList<>(); 
  37.         postorder(root, res); 
  38.         return res; 
  39.     } 
  40.  
  41.     void postorder(TreeNode root, List<Integer> list) { 
  42.         if (root == null) { 
  43.             return
  44.         } 
  45.         postorder(root.left, list); 
  46.         postorder(root.right, list); 
  47.         list.add(root.val);             // 注意这一句 
  48.     } 

Python:

  1. # 前序遍历-递归-LC144_二叉树的前序遍历 
  2. class Solution: 
  3.     def preorderTraversal(self, root: TreeNode) -> List[int]: 
  4.         # 保存结果 
  5.         result = [] 
  6.          
  7.         def traversal(root: TreeNode): 
  8.             if root == None: 
  9.                 return 
  10.             result.append(root.val) # 前序 
  11.             traversal(root.left)    # 左 
  12.             traversal(root.right)   # 右 
  13.  
  14.         traversal(root) 
  15.         return result 
  16.  
  17. # 中序遍历-递归-LC94_二叉树的中序遍历 
  18. class Solution: 
  19.     def inorderTraversal(self, root: TreeNode) -> List[int]: 
  20.         result = [] 
  21.  
  22.         def traversal(root: TreeNode): 
  23.             if root == None: 
  24.                 return 
  25.             traversal(root.left)    # 左 
  26.             result.append(root.val) # 中序 
  27.             traversal(root.right)   # 右 
  28.  
  29.         traversal(root) 
  30.         return result 
  31.  
  32. # 后序遍历-递归-LC145_二叉树的后序遍历 
  33. class Solution: 
  34.     def postorderTraversal(self, root: TreeNode) -> List[int]: 
  35.         result = [] 
  36.  
  37.         def traversal(root: TreeNode): 
  38.             if root == None: 
  39.                 return 
  40.             traversal(root.left)    # 左 
  41.             traversal(root.right)   # 右 
  42.             result.append(root.val) # 后序 
  43.  
  44.         traversal(root) 
  45.         return result 

 【编辑推荐】

  1. 手把手教你使用Python轻松打造淘宝主图视频生成神器
  2. 为什么 NanoID 会取代 UUID
  3. 加密货币世界中的黑客预防与缓解
  4. 最近腾讯35岁员工薪资曝光,你这辈子还能追得上吗?

 

来源:代码随想录内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯