核心定义
树是非线性数据结构,由n(n≥0)个节点组成的有限集合:
- 当n=0时,称为"空树";
- 当n>0时,有且仅有一个根节点(Root) ,其余节点分为若干个互不相交的子集,每个子集仍是树(称为"子树")。
- 资料:
https://pan.quark.cn/s/43d906ddfa1b
关键术语(必记)
| 术语 | 定义 |
|---|---|
| 根节点(Root) | 树的最顶层节点,无父节点(如文件系统的"根目录")。 |
| 父节点/子节点 | 若节点A直接包含节点B,则A是B的父节点,B是A的子节点(父子是直接关系)。 |
| 兄弟节点 | 同一父节点的子节点互称兄弟(如同一文件夹下的同级文件)。 |
| 叶子节点 | 无子节点的节点(树的"末端")。 |
| 深度(Depth) | 从根节点到当前节点的路径长度(根节点深度=0或1,需注意场景约定)。 |
| 高度(Height) | 从当前节点到最远叶子节点的路径长度(叶子节点高度=0)。 |
| 层数(Level) | 根节点为第1层(或第0层),子节点层数=父节点层数+1(与深度对应)。 |
| 子树(Subtree) | 以某节点为根的所有后代节点组成的树(含该节点)。 |
树的核心特性
- 无环性:任意两个节点之间有且仅有一条路径(不存在循环);
- 层次性:节点按"父子关系"分层排列,根在上,叶子在下;
- 唯一性:有且仅有一个根节点,所有非根节点有且仅有一个父节点。
常见树的分类(高频考点)
1. 按节点子树数量划分
- 二叉树 :每个节点最多有2个子节点(左子树、右子树),是最常用的树结构;
- 特殊二叉树:满二叉树(所有叶子节点在同一层,且非叶子节点都有2个子节点)、完全二叉树(按层序编号,与满二叉树编号一致,缺右不缺左)。
- 多叉树 :每个节点可以有多个子节点(如三叉树、N叉树);
- 典型应用:文件系统(目录树)、Trie树(前缀树)。
2. 按特殊规则划分
- 二叉搜索树(BST):左子树所有节点值 < 根节点值,右子树所有节点值 > 根节点值(支持快速查找、插入、删除,时间复杂度O(logn),最坏O(n));
- 平衡二叉树(AVL):左右子树高度差绝对值≤1(解决BST失衡问题,保证查找效率稳定O(logn));
- 红黑树:通过"红黑节点"规则维持平衡(插入删除效率比AVL高,用于Java TreeMap、HashMap(JDK8));
- B树/B+树:多路平衡查找树(用于数据库索引,适配磁盘IO)。
二叉树的存储方式
-
顺序存储(数组):
- 适用于完全二叉树,按层序编号存储(根节点存index=0,左子节点=2i+1,右子节点=2i+2);
- 优点:访问节点快,无需存储指针;缺点:非完全二叉树浪费空间。
-
链式存储(链表):
- 每个节点包含"数据域"+"左指针(指向左子树)"+"右指针(指向右子树)";
- 优点:空间利用率高,适合任意二叉树;缺点:访问子节点需通过指针遍历。
二叉树的核心遍历算法(必会代码)
遍历目标:按一定顺序访问树中所有节点,分为深度优先(DFS) 和广度优先(BFS)。
1. 深度优先遍历(DFS)
(1)前序遍历(根→左→右)
python
# 递归实现
def preorder(root):
if not root:
return []
return [root.val] + preorder(root.left) + preorder(root.right)
# 迭代实现(栈)
def preorder_iter(root):
stack, res = [root] if root else [], []
while stack:
node = stack.pop()
res.append(node.val)
if node.right: # 右子树先入栈(栈先进后出)
stack.append(node.right)
if node.left:
stack.append(node.left)
return res
(2)中序遍历(左→根→右)
- 二叉搜索树的中序遍历是升序序列(核心特性)。
python
# 递归实现
def inorder(root):
if not root:
return []
return inorder(root.left) + [root.val] + inorder(root.right)
# 迭代实现(栈)
def inorder_iter(root):
stack, res, curr = [], [], root
while stack or curr:
while curr: # 左子树到底
stack.append(curr)
curr = curr.left
curr = stack.pop()
res.append(curr.val)
curr = curr.right # 访问右子树
return res
(3)后序遍历(左→右→根)
python
# 递归实现
def postorder(root):
if not root:
return []
return postorder(root.left) + postorder(root.right) + [root.val]
# 迭代实现(栈+标记)
def postorder_iter(root):
stack, res = [(root, False)] if root else [], []
while stack:
node, visited = stack.pop()
if visited:
res.append(node.val)
else:
stack.append((node, True)) # 标记根节点,后续处理
if node.right:
stack.append((node.right, False))
if node.left:
stack.append((node.left, False))
return res
2. 广度优先遍历(BFS,层序遍历)
- 按"层"访问节点(从上到下,从左到右),用队列实现。
python
from collections import deque
def levelorder(root):
if not root:
return []
res = []
queue = deque([root])
while queue:
level_size = len(queue) # 当前层节点数
level = []
for _ in range(level_size):
node = queue.popleft()
level.append(node.val)
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
res.append(level) # 按层存储结果
return res
树的典型应用场景
- 数据查找:二叉搜索树、平衡二叉树、B+树(数据库索引);
- 排序:二叉搜索树的中序遍历(升序);
- 层级数据存储:文件系统、组织架构图;
- 字符串处理:Trie树(前缀匹配,如搜索引擎自动补全);
- 算法优化:哈夫曼树(数据压缩)、决策树(机器学习)。