C/C++二叉树核心面试题

题目 1:二叉树的三种遍历(递归 + 迭代)

题目描述

分别用递归和迭代方式实现二叉树的前序、中序、后序遍历。

解题思路

  • 递归法:按照「根左右」「左根右」「左右根」的顺序直接递归
  • 迭代法:用栈模拟递归过程,其中后序遍历可通过「根右左」遍历后反转得到

代码实现

cpp

运行

cpp 复制代码
struct TreeNode {
    int val;
    TreeNode *left;
    TreeNode *right;
    TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};

// 前序遍历-递归
void preorder(TreeNode* root, vector<int>& res) {
    if (!root) return;
    res.push_back(root->val);
    preorder(root->left, res);
    preorder(root->right, res);
}

// 中序遍历-迭代
vector<int> inorderTraversal(TreeNode* root) {
    vector<int> res;
    stack<TreeNode*> st;
    while (root || !st.empty()) {
        while (root) {
            st.push(root);
            root = root->left; // 一直往左走
        }
        root = st.top();
        st.pop();
        res.push_back(root->val); // 访问根
        root = root->right; // 进入右子树
    }
    return res;
}

// 后序遍历-迭代(根右左反转法)
vector<int> postorderTraversal(TreeNode* root) {
    vector<int> res;
    if (!root) return res;
    stack<TreeNode*> st;
    st.push(root);
    while (!st.empty()) {
        TreeNode* node = st.top();
        st.pop();
        res.push_back(node->val);
        if (node->left) st.push(node->left);
        if (node->right) st.push(node->right);
    }
    reverse(res.begin(), res.end());
    return res;
}

复杂度分析

  • 时间复杂度:O (n),每个节点访问一次
  • 空间复杂度:O (n),递归栈或显式栈的开销

面试考点

二叉树基础必考题。面试官常考察三种遍历的迭代写法,尤其是中序和后序,检验对栈模拟递归的理解。


题目 2:二叉树的最大深度

题目描述

给定一个二叉树,找出其最大深度。二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。

解题思路

方法一:递归分治 树的最大深度 = max (左子树深度,右子树深度) + 1

方法二:层序遍历 用队列进行广度优先搜索(BFS),每遍历完一层深度加 1。

代码实现

cpp

运行

cpp 复制代码
// 递归法
int maxDepth(TreeNode* root) {
    if (!root) return 0;
    return max(maxDepth(root->left), maxDepth(root->right)) + 1;
}

// 层序遍历法
int maxDepth(TreeNode* root) {
    if (!root) return 0;
    queue<TreeNode*> q;
    q.push(root);
    int depth = 0;
    while (!q.empty()) {
        int size = q.size();
        for (int i = 0; i < size; i++) {
            TreeNode* node = q.front();
            q.pop();
            if (node->left) q.push(node->left);
            if (node->right) q.push(node->right);
        }
        depth++;
    }
    return depth;
}

复杂度分析

  • 时间复杂度:O (n)
  • 空间复杂度:递归法最坏 O (n)(链状树),层序遍历最坏 O (n)(完美二叉树最后一层)

面试考点

二叉树递归与 BFS 基础。延伸问:求二叉树的最小深度?判断平衡二叉树?


题目 3:验证二叉搜索树

题目描述

给你一个二叉树的根节点 root,判断其是否是一个有效的二叉搜索树(BST)。BST 的定义:左子树所有节点小于根,右子树所有节点大于根,左右子树也都是 BST。

解题思路

中序遍历法: 二叉搜索树的中序遍历结果一定是严格递增序列。只需中序遍历二叉树,记录前一个节点的值,检查当前值是否始终大于前一个值即可。

代码实现

cpp

运行

cpp 复制代码
bool isValidBST(TreeNode* root) {
    stack<TreeNode*> st;
    long long prev = (long long)INT_MIN - 1; // 用long long避免边界溢出
    while (root || !st.empty()) {
        while (root) {
            st.push(root);
            root = root->left;
        }
        root = st.top();
        st.pop();
        if (root->val <= prev) return false;
        prev = root->val;
        root = root->right;
    }
    return true;
}

复杂度分析

  • 时间复杂度:O (n)
  • 空间复杂度:O (n)

面试考点

BST 性质的应用。注意边界陷阱:节点值可能等于 INT_MIN,直接用 int 存前值会出错。


题目 4:二叉树的层序遍历

题目描述

给你二叉树的根节点 root,返回其节点值的层序遍历(即逐层地,从左到右访问所有节点)。

解题思路

BFS 广度优先搜索: 使用队列存储每一层的节点。每次开始遍历一层前,先记录队列大小(当前层节点数),然后批量处理这一层的所有节点,同时将子节点入队,作为下一层的数据。

代码实现

cpp

运行

cpp 复制代码
vector<vector<int>> levelOrder(TreeNode* root) {
    vector<vector<int>> res;
    if (!root) return res;
    queue<TreeNode*> q;
    q.push(root);
    while (!q.empty()) {
        int size = q.size();
        vector<int> level;
        for (int i = 0; i < size; i++) {
            TreeNode* node = q.front();
            q.pop();
            level.push_back(node->val);
            if (node->left) q.push(node->left);
            if (node->right) q.push(node->right);
        }
        res.push_back(level);
    }
    return res;
}

复杂度分析

  • 时间复杂度:O (n),每个节点入队出队各一次
  • 空间复杂度:O (n),队列最大长度不超过 n

面试考点

BFS 的经典应用。延伸问:锯齿形层序遍历?二叉树的右视图?都是基于层序遍历的变形。
谢谢