title: 树与堆
tags:
- module
- data-structure-and-algorithm
- tree
- heap
- joplin
type: module
source_type: reconstructed
created: 2026-04-22
updated: 2026-04-22
---
树与堆
[!abstract]
这一模块处理层次结构。重点不是把各种树名词割裂开背,而是理解它们都在解决“如何维护有层次的关系并支持高效操作”。
模块结论
- [[二叉树]] 是最基础的树形组织方式,遍历、节点数、高度等问题都从这里展开。
- [[二叉排序树]] 在二叉树上增加有序性,用来加速查找、插入和删除。
- [[AVL树]] 进一步在二叉排序树上增加平衡约束,避免退化。
- [[堆]] 是特殊的完全二叉树,更适合快速找最值,而不是做通用查找。
一、二叉树基础
- 每个结点最多两个孩子。
- 常见操作包括前序、中序、后序遍历,以及结点数、叶子数和高度统计。
- 顺序存储适合完全二叉树,链式存储适合一般二叉树。
遍历为什么重要
- 前序常用于描述“根先处理”。
- 中序在二叉排序树里会直接得到有序序列。
- 后序适合“先处理子问题,再处理根”的场景。
二、二叉排序树
- 左子树所有关键字小于根,右子树所有关键字大于根。
- 查找、插入、删除都围绕这条性质展开。
- 删除最值得复习,因为要区分 0 个孩子、1 个孩子、2 个孩子三类情况。
删除核心逻辑
- 叶子结点:直接删。
- 单孩子结点:用孩子顶替。
- 双孩子结点:常用后继或前驱替换后再删。
三、AVL 树
- 它是自平衡的二叉排序树。
- 任一结点左右子树高度差绝对值不超过 1。
- 一旦插入导致失衡,就需要旋转恢复平衡。
四种典型失衡
复习重点
- 别只背旋转名字,要能判断失衡发生在哪一侧、由哪种插入路径导致。
四、堆
- 堆是完全二叉树。
- 最大堆满足根不小于孩子,最小堆满足根不大于孩子。
- 典型操作是插入、删除堆顶、建堆。
堆和二叉排序树的区别
- 堆只保证局部父子有序,不保证整棵树中序有序。
- 堆适合反复取最值。
- 二叉排序树适合更一般的动态查找。
五、易错点
- 二叉树的顺序存储数组下标关系要和从 0 还是从 1 开始分开看。
- 二叉排序树最坏情况下会退化成链表。
- AVL 树旋转后不仅结构变了,高度也要更新。
- 堆不是完全排序结构,不能直接当成“任意查找都快”的树。
六、复习提问
- 二叉树三种深度优先遍历的访问次序分别是什么?
- 二叉排序树删除结点为什么要分三类情况?
- AVL 树为什么比普通二叉排序树更稳定?
- 堆为什么适合优先队列,却不适合一般查找?
来源
- [[raw/Joplin/计算机专业基础/数据结构与算法/(C)840数据结构与算法/2.二叉树的实现和应用.md]]
- [[raw/Joplin/计算机专业基础/数据结构与算法/(C)840数据结构与算法/3.堆--以最大堆为例.md]]
- [[raw/Joplin/计算机专业基础/数据结构与算法/(C)840数据结构与算法/5.二叉排序树.md]]
- [[raw/Joplin/计算机专业基础/数据结构与算法/(C)840数据结构与算法/6.平衡二叉树(AVL树).md]]
- [[raw/Joplin/计算机专业基础/数据结构与算法/(C++)数据结构与算法/12.二叉排序树.md]]
相关页面
- [[数据结构与算法]]
- [[二叉树]]
- [[堆]]
- [[二叉排序树]]
- [[AVL树]]