1. 二叉树基础与JavaScript实现
二叉树是每个节点最多有两个子节点的树结构,在算法题中极为常见。JavaScript中我们通常用对象来表示节点:
javascript复制function TreeNode(val, left, right) {
this.val = (val === undefined ? 0 : val);
this.left = (left === undefined ? null : left);
this.right = (right === undefined ? null : right);
}
这个构造函数创建了一个典型的二叉树节点,包含值属性和左右子节点指针。在实际使用时,我们需要注意:
在JavaScript中,未赋值的属性默认是undefined,所以这里用null显式表示空节点,这是与许多其他语言不同的地方。
1.1 二叉树的三种基本遍历
前序遍历(根-左-右)
前序遍历先访问根节点,然后左子树,最后右子树。递归实现直观易懂:
javascript复制function preorderTraversal(root) {
const res = [];
const traverse = (node) => {
if (!node) return;
res.push(node.val); // 先访问根节点
traverse(node.left);
traverse(node.right);
};
traverse(root);
return res;
}
但在实际面试中,面试官往往要求迭代实现以避免递归的栈溢出风险:
javascript复制function preorderTraversal(root) {
if (!root) return [];
const stack = [root], res = [];
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;
}
中序遍历(左-根-右)
中序遍历的递归实现只需调整访问顺序:
javascript复制function inorderTraversal(root) {
const res = [];
const traverse = (node) => {
if (!node) return;
traverse(node.left);
res.push(node.val); // 中间访问根节点
traverse(node.right);
};
traverse(root);
return res;
}
迭代实现需要借助指针和栈:
javascript复制function inorderTraversal(root) {
const stack = [], res = [];
let curr = root;
while (curr || stack.length) {
while (curr) {
stack.push(curr);
