题目 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 的经典应用。延伸问:锯齿形层序遍历?二叉树的右视图?都是基于层序遍历的变形。
谢谢