你以为树只是画图?不——它是算法面试的“隐形主角”

如果数组是算法世界的地基

那么「树」,就是贯穿整个面试的 承重结构

无论你刷的是 力扣 Hot100 、校招面试,还是前端进阶,
树 & 二叉树一定会反复出现:

  • DOM 是一棵树
  • Vue / React 的虚拟 DOM 是树
  • 文件系统是树
  • 递归,几乎是为树量身定做的

但很多人一提到树就懵:

"概念太多了..."

"遍历顺序老记混..."

"一写递归就心虚..."

这篇文章,我们用最接地气的方式,把树和二叉树一次讲透。


一、什么是「树」?------不是代码,是抽象能力

数据结构中的树,其实是对自然界树的抽象 🌲

我们先统一语言:

自然界 数据结构
树根 根节点 root
树枝 边 edge
分叉 子节点 child
叶子 叶子节点 leaf

一棵树的核心特征只有一个:

🌟 只有一个根节点,其余节点都从它延伸出来


二、树的几个"面试高频概念"(一定会被问)

1️⃣ 层次(level)

  • 根节点是 第 1 层
  • 子节点依次 +1

📌 面试常问:

"这棵树的第 k 层有多少节点?"


2️⃣ 高度(height)

⚠️ 容易混淆!

  • 从叶子节点开始算
  • 向上 +1

📌 面试爱问:

"树的高度是多少?"


3️⃣ 度(degree)

  • 一个节点有几个子树
  • 就是它的度

👉 叶子节点的度 = 0


三、什么是二叉树?别被"2"骗了 ❌

很多人第一反应是:

❌ "二叉树 = 每个节点最多 2 个孩子"

不完全对。

二叉树的真正定义👇

一棵二叉树:

  • 可以是 空树

  • 如果不是空树:

    • 必须由:
      根节点 + 左子树 + 右子树
    • 且 左右子树本身也是二叉树

📌 关键点只有一句话:

⚠️ 左右之分是"有顺序的",不能随便交换

所以:

  • ❌ 二叉树 ≠ 度为 2 的树
  • ✅ 二叉树 = 有左右语义的结构

四、二叉树节点的最小模型(JS)

kotlin 复制代码
function TreeNode(val){
  this.val = val
  this.left = this.right = null
}

只有 3 件事:

  • 数据域 val
  • 左孩子 left
  • 右孩子 right

📌 面试时你只要记住:
树 ≈ 节点 + 引用


五、为什么「树」和「递归」天生一对?

因为:树的定义本身就是递归的

  • 树 = 根 + 子树
  • 子树 = 更小的树
  • ......

📌 所以你刷到树题时,脑子里先问一句:

"这是不是一个可以拆成左右子树的重复问题?"

如果答案是 YES ------

👉 递归基本就稳了


六、二叉树遍历:面试最爱考的 4 种方式

一句话总纲

🔑 左右子树顺序永远不变,变的只有"根"什么时候输出


1️⃣ 前序遍历(Preorder)

👉 根 → 左 → 右

scss 复制代码
function preorder(root){
  if(!root) return
  console.log(root.val)
  preorder(root.left)
  preorder(root.right)
}

📌 适合:

  • 构建树
  • 拷贝树

2️⃣ 中序遍历(Inorder)

👉 左 → 根 → 右

scss 复制代码
function inorder(root){
  if(!root) return
  inorder(root.left)
  console.log(root.val)
  inorder(root.right)
}

📌 经典结论(面试加分):

二叉搜索树的中序遍历是有序的


3️⃣ 后序遍历(Postorder)

👉 左 → 右 → 根

scss 复制代码
function postorder(root){
  if(!root) return
  postorder(root.left)
  postorder(root.right)
  console.log(root.val)
}

📌 适合:

  • 删除节点
  • 释放资源
  • 自底向上计算

七、层序遍历:唯一的「非递归主角」

🌊 从上到下,一层一层

核心思想:队列(FIFO)

scss 复制代码
function levelOrder(root){
  if(!root) return []
  const res = []
  const queue = [root]

  while(queue.length){
    const node = queue.shift()
    res.push(node.val)
    if(node.left) queue.push(node.left)
    if(node.right) queue.push(node.right)
  }

  return res
}

📌 面试官想考你的是:

  • 你是否知道 BFS
  • 你是否能想到 队列

八、树题的"万能拆解模板"

每次看到树题,按这个流程走👇

① 明确递归函数的定义

dfs(root) 到底返回什么?


② 找重复子问题

左子树怎么做?右子树怎么做?


③ 找退出条件

root == null 时怎么办?


④ 决定「根」什么时候处理

  • 前?中?后?

📌 90% 的树题,死在第 ① 步没想清楚


九、最后:你不是不会树,是没"建模"

很多人学树失败,并不是因为代码写不出,而是:

  • ❌ 把它当"记忆题"
  • ❌ 死背遍历顺序
  • ❌ 不理解递归的意义

真正的高手,看到树只想一件事:

"这棵树,能不能拆成左右子树的重复问题?"

一旦你建立了这个视角:

  • 树不再难
  • 递归不再怕
  • 面试不再慌
相关推荐
福兮说3 小时前
前端下载大文件,点了按钮半天没反应:fetch + blob 的三个问题和三种替代写法
前端·javascript·性能优化·文件下载
专注仿真3 小时前
ACM算法
算法·深度优先
GreenTea3 小时前
我把 Agent 的 while 循环拆掉了:一种你可能没想到的 Agent 架构
前端·后端·架构
科技观察哨3 小时前
六足平台选型与纳米定位系统集成:HEB-640六自由度位移台在半导体光刻对准中的参数边界与国产替代评估
前端·人工智能
niucloud-admin3 小时前
JAVA V6 多商户商城 开发文档——web前端
前端
颜进强4 小时前
16 · NestJS LifecycleEvents 生命周期事件:五个钩子、三条边界,和 rag-server 的优雅停机
前端·后端·ai编程
顺顺 尼5 小时前
linux 进程信号(上)
linux·c++·算法
今年下半年5 小时前
【VUE】整合腾讯地图、自定义区域边界、村委名称及资产统计(放大显示资产点位)
前端·javascript·vue.js
罗西的思考5 小时前
[Agent Memory / 强化学习] MemPO源码学习笔记 ---(5)--- GRPO
人工智能·算法·机器学习
郑州光合科技余经理5 小时前
同城电商系统:库存变更怎么同步到订单
java·开发语言·前端·后端·uni-app·php·ai编程