← 目录 / 算法文档 · 模块十一 树与二叉树 / 11.1 树的基本概念

11.1 树的基本概念

从家谱和文件夹说起——认识节点、父子关系、深度与高度,为后面的存储和遍历打好地基。

本页目录
① 树是什么:从家谱和文件夹说起

你有没有留意过,家里的家谱和电脑里的文件夹,其实长得很像?家谱里,爷爷下面分出爸爸和叔叔,爸爸和叔叔下面又各自分出你和堂兄弟;文件夹也是一样,一个文件夹下面能装好几个子文件夹,子文件夹下面还能再装子文件夹。这种"一个东西能往下分出好几个,一层一层展开,绝不会转个圈又绕回去"的结构,在计算机里就叫

之所以叫"树",是因为倒过来看,它还真有点像一棵大树:最上面是树根,往下渐渐分叉出树枝,最后长出一片片树叶。只不过我们画图的时候习惯把"根"画在最上面,"叶子"画在最下面——这个习惯要提前说一声,免得和现实里的树反着看,反而觉得别扭。

👪 家谱
爷爷是"根",爸爸和叔叔是爷爷的孩子,你和堂兄弟是爸爸、叔叔的孩子。每个人都只有一个直接的上级(父亲),但可以有好几个孩子。
📁 文件夹
C:\ 是根目录,下面有 UsersProgram Files 等文件夹,Users 下面又有具体的用户文件夹……一层套一层,永远不会有一个文件夹同时是另一个文件夹的"孙子"又是它的"祖先"。
💡
树和之前学过的数组、链表最大的区别是:数组、链表是"一条线",每个元素最多连着前后两个邻居;树是"一对多",一个节点可以同时连着好几个"下级"。这也是为什么树能天然地表示"层级"关系,比如目录结构、公司组织架构、比赛淘汰赛对阵图。
② 基本术语:节点、父子、叶子、子树

下面用一棵具体的树,把树相关的术语一次性讲清楚。这棵树在接下来两节(存储、遍历)里还会反复用到,建议先记住它的样子:

1 根节点 2 3 4 5 6 叶子节点(4、5、6 都没有子节点)
节点 1根节点(没有父节点,整棵树从它开始);21子节点12父节点23 互为兄弟节点(同一个父节点);456 都没有子节点,叫叶子节点。以 2 为根往下看(2、4、5),单独也构成一棵完整的树,叫 1子树
📖
连接节点的线叫"边",从根节点走到任意一个节点所经过的边,叫这个节点的路径。比如从 1 走到 4,路径是 1→2→4,经过了 2 条边。这个"经过了几条边"的数字,就是下一节要讲的深度
③ 深度与高度:两个最容易搞混的概念

深度和高度这两个词看着像近义词,但方向完全相反,是初学者最容易搞混的地方:

概念怎么数方向
深度(depth)根节点数到这个节点,经过几条边自上而下
高度(height)从这个节点数到它最深的那个叶子,经过几条边自下而上
1 深度0 2 深度1 高度1 3 深度1 4 深度2 · 高度0 5 深度2 · 高度0 6 深度2 · 高度0
灰色数字是深度,橙色数字是高度——全篇统一用这两种颜色,方便一眼分清。节点 4深度是 2(从根 1 走过 1→2→4 共 2 条边)。节点 2高度是 1(从 2 到它最深的叶子 45,只隔 1 条边)。整棵树的高度,通常就说成"根节点的高度"——这里是 2。叶子节点的高度永远是 0(自己就是最深的叶子,不用再往下走)。
💡
简单来说:深度回答的是"我离根有多远",高度回答的是"我离最远的叶子有多远"。记住两个"锚点"就不会搞混:根节点的深度永远是 0(自己到自己,不用走);叶子节点的高度永远是 0(自己就是最深的叶子,也不用再走)。
④ 二叉树:每个节点最多两个子节点

树的每个节点可以有任意多个子节点(比如文件夹可以有很多子文件夹)。但学算法时最常遇到、也最重要的一种树,是二叉树——规定每个节点最多只能有两个子节点,分别叫左子节点右子节点(哪怕只有一个子节点,也要分清楚它是"左"还是"右",这一点在下一节讲存储方式时很关键)。

上面例子里的树,每个节点的子节点数都不超过 2 个,所以它本身就是一棵二叉树:节点 1 的左子节点是 2、右子节点是 3;节点 3 只有左子节点 6、没有右子节点。

📐
两个常见的特殊二叉树:
满二叉树——除了叶子节点,每个节点都有两个子节点,而且所有叶子都在同一层(一层填得满满的);
完全二叉树——除了最后一层,其它层都填满,最后一层的节点从左往右连续排列,中间不能有空缺。上面例子里的树就是一棵完全二叉树:最后一层是 4、5、6,从左到右紧挨着排列,没有跳过任何位置。
完全二叉树这个性质非常重要——下一节讲"用数组存二叉树"时,正是利用了这个"从左到右紧凑排列"的特点,才能省下大量空间。
⑤ 常见陷阱

把本节内容汇总成几条最容易踩坑的规则:

只有一个子节点时,别忘了区分左右:比如某个节点只有一个子节点,这个子节点必须明确是"左子节点"还是"右子节点",不能笼统地说"有一个子节点"——这在二叉树里是两种不同的结构,写代码时对应的是 left 还是 right 指针,混淆会导致存储和遍历都出错。
深度和高度不要搞反:深度的参照点永远是"根",高度的参照点是"当前节点自己"。一个常见的错误是把"根节点的深度"当成 0 之外的值,或者把叶子节点的高度算成 1——记住根节点深度固定是 0,叶子节点高度固定是 0。
"满二叉树"和"完全二叉树"不是一回事:满二叉树要求所有叶子都在同一层,是完全二叉树的一种特殊情况;完全二叉树只要求最后一层从左往右连续排列,最后一层可以不填满。所有满二叉树都是完全二叉树,反过来不一定成立。
🏆
接下来:下一节(11.2)讲二叉树怎么真正存进程序里——数组式存储(专门利用完全二叉树"紧凑排列"的性质)和链式存储(用指针连接,更通用)两种方式,以及各自的适用场景。