算法入门(四):二叉树 - 递归遍历三件套

算法入门(四):二叉树 - 递归遍历三件套

    • 前、中、后序遍历
    • 递归
    • [LC 144(前序)](#LC 144(前序))
    • [LC 94(中序)](#LC 94(中序))
    • [LC 145(后序)](#LC 145(后序))
    • [LC 589(N叉树前序)](#LC 589(N叉树前序))

前、中、后序遍历

本文暂不介绍二叉树的定义以及深度等概念。

这里给出一棵深度为3的二叉树:

cpp 复制代码
         A
       /   \
      B     C
     / \   / \
    D   E F   G

其三种遍历结果如下:

  1. 前序遍历(根 → 左 → 右)

    顺序:A → B → D → E → C → F → G

  2. 中序遍历(左 → 根 → 右)

    顺序:D → B → E → A → F → C → G

  3. 后序遍历(左 → 右 → 根)

    顺序:D → E → B → F → G → C → A

递归

递归需要思考清楚以下问题:

  • 递归函数的功能是什么,输入输出分别是什么
  • 递归函数的终止条件是什么,什么时候结束或者停止
  • 递推式是什么

对于二叉树的遍历问题:

  • 遍历函数的输入是根节点,输出是将节点值放入结果数组:res.push_back(node->val)
  • 当节点为空,结束遍历函数
  • 遍历函数的递推式就是遍历的动作,区分为前中后序

LC 144(前序)

第一次尝试:

cpp 复制代码
class Solution {
public:
    vector<int> res;
    void traversal(TreeNode* node){
        if(node == nullptr) return;
        res.push_back(node->val);
        traversal(node->left);
        traversal(node->right);
    }
    vector<int> preorderTraversal(TreeNode* root) {
        traversal(root);
        return res;
    }
};

如果想要让res不是全局变量的话,可以通过&传值,在vector vec中添加 &:

cpp 复制代码
class Solution {
public:
void traversal(TreeNode* cur, vector<int>& vec) {
        if (cur == nullptr) return;
        vec.push_back(cur->val);    // 中
        traversal(cur->left, vec);  // 左
        traversal(cur->right, vec); // 右
    }
    vector<int> preorderTraversal(TreeNode* root) {
        vector<int> res;
        traversal(root,res);
        return res;
    }
};

LC 94(中序)

同上。修改traversal中的顺序,中序遍历代表push动作在中间:

cpp 复制代码
class Solution {
public:
    void traversal(TreeNode* cur,vector<int>& vec){
        if(cur ==nullptr) return ;
        traversal(cur->left,vec);
        vec.push_back(cur->val);
        traversal(cur->right,vec);
    }
    vector<int> inorderTraversal(TreeNode* root) {
        vector<int> res;
        traversal(root,res);
        return res;
    }
};

LC 145(后序)

后序遍历代表push动作在最后:

cpp 复制代码
class Solution {
public:
    void traversal(TreeNode* cur,vector<int>& vec){
        if(cur == nullptr) return;
        traversal(cur->left,vec);
        traversal(cur->right,vec);
        vec.push_back(cur->val);
    }
    vector<int> postorderTraversal(TreeNode* root) {
        vector<int> res;
        traversal(root,res);
        return res;
    }
};

LC 589(N叉树前序)

如果前三道题掌握的话,这道题不会很困难:

cpp 复制代码
class Solution {
public:
    void traversal(Node* node,vector<int>& res){
        if(node == nullptr) return;
        res.push_back(node->val);
        if(node->children.size() == 0) return;
        for(int i =0;i<node->children.size();i++){
            traversal(node->children[i],res);
        }
    }
    vector<int> preorder(Node* root) {
        vector<int> res;
        traversal(root,res);
        return res;
    }
};
相关推荐
带多刺的玫瑰2 小时前
Leecode#26刷题之删除有序数组中的重复项
数据结构·算法·leetcode
en.en..3 小时前
C语言核心解析:#define与typedef本质区别
开发语言·c++·算法
wabs6665 小时前
关于二叉树【429.N叉树的层序遍历的思考】
数据结构·c++·算法·leetcode·二叉树
hetao17338375 小时前
2026-09-08 hetao1733837 的刷题记录
c++·算法
C++ 老炮儿的技术栈5 小时前
MFC CPtrArray的用法
开发语言·数据结构·c++·算法·mfc·c
weixin_446260855 小时前
CABAL:用于追踪同行评审中合谋投标影响的多智能体仿真框架
人工智能·算法·机器学习
不会就选b5 小时前
算法日常・每日刷题--<贪心>6
数据结构·算法·leetcode
青山木6 小时前
Hot 100 --- 跳跃游戏 II
java·数据结构·算法·leetcode·贪心算法
Tisfy6 小时前
LeetCode 3870.统计范围内的逗号:模拟 或 一步计算
数学·算法·leetcode·题解·模拟·遍历
明月_清风6 小时前
字符串匹配四大经典算法:BF、RK、BM、KMP 到底有什么区别?
后端·算法