前端面试必刷:二叉树高频算法最优解(迭代版)
二叉树是前端算法面试核心考点,本文基于 ES6+ 提供无递归、无栈溢出的迭代实现,覆盖遍历、高频题型,附带详细注释与解法要点,可直接用于面试书写与刷题。
二叉树节点定义
class TreeNode {
constructor(val = 0, left = null, right = null) {
this.val = val
this.left = left
this.right = right
}
}
一、四大遍历(核心模板)
1. 前序遍历(根→左→右)LeetCode 144
const preorderTraversal = (root) => {
const res = []
if (!root) return res
// 栈实现深度优先遍历
const stack = [root]
while (stack.length) {
// 弹出栈顶节点
const node = stack.pop()
// 记录根节点值
res.push(node.val)
// 右节点先入栈,保证左节点优先处理
if (node.right) stack.push(node.right)
if (node.left) stack.push(node.left)
}
return res
}
📌 解法要点
- 栈 + 迭代,避免递归溢出
- 右先入栈 → 左先执行,符合前序规则
- 时间复杂度 O (n),空间复杂度 O (n)
2. 中序遍历(左→根→右)LeetCode 94
const inorderTraversal = (root) => {
const res = []
const stack = []
// 指针追踪当前节点
let cur = root
while (cur || stack.length) {
// 持续向左遍历,全部入栈
while (cur) {
stack.push(cur)
cur = cur.left
}
// 弹出最左侧节点
const node = stack.pop()
res.push(node.val)
// 转向右子树
cur = node.right
}
return res
}
📌 解法要点
- 二叉树最常用遍历模板
- 左子树优先 → 根 → 右子树
- BST 中序可直接得到递增序列
3. 后序遍历(左→右→根)LeetCode 145
const postorderTraversal = (root) => {
const res = []
if (!root) return res
const stack = [root]
while (stack.length) {
const node = stack.pop()
res.push(node.val)
// 左先入栈,右后处理
if (node.left) stack.push(node.left)
if (node.right) stack.push(node.right)
}
// 反转得到后序结果
return res.reverse()
}
📌 解法要点
- 前序变种:根→右→左,反转后即为后序
- 代码极简,面试书写效率最高
- 时间复杂度 O (n)
4. 层序遍历(BFS)LeetCode 102
const levelOrder = (root) => {
const res = []
if (!root) return res
// 队列实现广度优先
const queue = [root]
while (queue.length) {
// 固定当前层节点数量,防止入队干扰循环
const levelSize = queue.length
const currentLevel = []
for (let i = 0; i < levelSize; i++) {
// 队首出队
const node = queue.shift()
currentLevel.push(node.val)
// 子节点入队,下一层处理
if (node.left) queue.push(node.left)
if (node.right) queue.push(node.right)
}
res.push(currentLevel)
}
return res
}
📌 解法要点
- 队列结构,一层一轮处理
- 适用于:最短路径、树宽、层级相关问题
- 标准 BFS 模板
二、高频面试题
1. 二叉树最大深度 LeetCode 104
const maxDepth = (root) => {
if (!root) return 0
// 深度 = 1 + 左右子树最大深度
return 1 + Math.max(maxDepth(root.left), maxDepth(root.right))
}
📌 解法要点
- 极简递归思路
- 自底向上计算高度
2. 对称二叉树 LeetCode 101
const isSymmetric = (root) => {
// 双指针镜像校验
const check = (l, r) => {
if (!l && !r) return true
if (!l || !r) return false
// 左左对应右右,左右对应右左
return l.val === r.val && check(l.left, r.right) && check(l.right, r.left)
}
return check(root.left, root.right)
}
📌 解法要点
- 递归 + 双指针
- 核心:镜像位置值相等
3. 翻转二叉树 LeetCode 226
const invertTree = (root) => {
if (!root) return null
// 递归翻转左右子树
const left = invertTree(root.left)
const right = invertTree(root.right)
// 交换左右节点
root.left = right
root.right = left
return root
}
📌 解法要点
- 自底向上交换孩子
- 面试高频手撕题
4. 验证二叉搜索树 LeetCode 98
const isValidBST = (root) => {
// 带区间校验:节点必须在 (min, max) 内
const dfs = (node, min, max) => {
if (!node) return true
if (node.val <= min || node.val >= max) return false
// 左子树 < 根,右子树 > 根
return dfs(node.left, min, node.val) && dfs(node.right, node.val, max)
}
return dfs(root, -Infinity, Infinity)
}
📌 解法要点
- 不能仅比较父子节点,必须全局区间判断
- 标准 BST 验证模板
三、测试用例
const root = new TreeNode(1)
root.left = new TreeNode(2)
root.right = new TreeNode(3)
root.left.left = new TreeNode(4)
root.left.right = new TreeNode(5)
root.right.right = new TreeNode(6)
root.left.right.left = new TreeNode(7)
root.left.right.right = new TreeNode(8)
console.log('前序:', preorderTraversal(root))
console.log('中序:', inorderTraversal(root))
console.log('后序:', postorderTraversal(root))
console.log('层序:', levelOrder(root))
数组转二叉树实现
// LeetCode 官方:数组转二叉树实现
function arrayToTree(arr) {
if (!arr.length) return null;
const root = new TreeNode(arr[0]);
const queue = [root];
let i = 1;
while (queue.length && i < arr.length) {
const parent = queue.shift();
// 左孩子
if (arr[i] !== null) {
parent.left = new TreeNode(arr[i]);
queue.push(parent.left);
}
i++;
// 右孩子
if (i < arr.length && arr[i] !== null) {
parent.right = new TreeNode(arr[i]);
queue.push(parent.right);
}
i++;
}
return root;
}
总结
- 前 / 中 / 后序:DFS + 栈,迭代优先,无溢出风险
- 层序遍历:BFS + 队列,按层处理
- 所有实现均为面试最优版本,简洁、规范、高效
- 覆盖前端二叉树面试 90%+ 高频考点