树数据结构介绍
目录
什么是树?
树(Tree) 是一种非线性的数据结构,由节点(Node)和连接节点的边(Edge)组成。它模拟了自然界中树的结构,由根向下延伸。
树的图示
A <- 根节点
/|\
B C D <- A的子节点
/| |\
E F G H <- B和D的子节点
树的基本术语
1. 节点(Node)
- 树中的每个元素称为节点
- 节点包含数据和指向其他节点的引用
2. 根节点(Root)
- 树的最顶端节点,没有父节点
- 每棵树只有一个根节点
3. 父节点(Parent)
- 如果节点A连接到节点B,且A在B的上方,则A是B的父节点
4. 子节点(Child)
- 与父节点相对应,B是A的子节点
5. 叶子节点(Leaf)
- 没有子节点的节点
- 也称为终端节点
6. 内部节点(Internal Node)
- 至少有一个子节点的节点
7. 兄弟节点(Siblings)
- 拥有相同父节点的节点
8. 边(Edge)
- 连接两个节点的链接
9. 路径(Path)
- 从一个节点到另一个节点的节点序列
10. 深度(Depth)
- 从根节点到某个节点的边数
- 根节点的深度为0
11. 高度(Height)
- 从某个节点到叶子节点的最长路径的边数
- 树的高度是根节点的高度
12. 层级(Level)
- 节点的深度 + 1
- 根节点在第1层
13. 子树(Subtree)
- 树中的任意节点及其所有后代节点构成的树
树的特点
- 层次结构:树具有明确的层次关系
- 唯一路径:从根节点到任意节点只有一条路径
- 无环:树是无环的连通图
- 节点数 = 边数 + 1:有n个节点的树有n-1条边
二叉树
二叉树(Binary Tree) 是最常用的树结构,每个节点最多有两个子节点。
二叉树的类型
1. 完全二叉树(Complete Binary Tree)
- 除了最后一层,其他层都是满的
- 最后一层的节点从左到右连续排列
1
/ \
2 3
/ \ /
4 5 6
2. 满二叉树(Full Binary Tree)
- 每个节点要么有0个子节点,要么有2个子节点
1
/ \
2 3
/ \
4 5
3. 完美二叉树(Perfect Binary Tree)
- 所有内部节点都有两个子节点
- 所有叶子节点在同一层
1
/ \
2 3
/ \ / \
4 5 6 7
4. 平衡二叉树(Balanced Binary Tree)
- 任何节点的左右子树高度差不超过1
- 例如:AVL树、红黑树
5. 二叉搜索树(Binary Search Tree, BST)
- 左子树的所有节点值 < 根节点值
- 右子树的所有节点值 > 根节点值
- 左右子树也是二叉搜索树
50
/ \
30 70
/ \ / \
20 40 60 80
树的遍历
遍历是访问树中所有节点的过程。主要有以下几种方式:
1. 深度优先遍历(DFS - Depth First Search)
前序遍历(Pre-order)
顺序:根 → 左 → 右
def preorder(root):
if root:
print(root.data) # 访问根节点
preorder(root.left) # 遍历左子树
preorder(root.right) # 遍历右子树
示例:A → B → E → F → C → D → G → H
中序遍历(In-order)
顺序:左 → 根 → 右
def inorder(root):
if root:
inorder(root.left) # 遍历左子树
print(root.data) # 访问根节点
inorder(root.right) # 遍历右子树
示例:E → B → F → A → C → G → D → H
注意:对于二叉搜索树,中序遍历得到有序序列!
后序遍历(Post-order)
顺序:左 → 右 → 根
def postorder(root):
if root:
postorder(root.left) # 遍历左子树
postorder(root.right) # 遍历右子树
print(root.data) # 访问根节点
示例:E → F → B → C → G → H → D → A
2. 广度优先遍历(BFS - Breadth First Search)
层序遍历(Level-order)
逐层从左到右访问
from collections import deque
def levelorder(root):
if not root:
return
queue = deque([root])
while queue:
node = queue.popleft()
print(node.data)
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
示例:A → B → C → D → E → F → G → H
常见的树类型
1. 二叉搜索树(BST)
- 用于快速查找、插入和删除
- 平均时间复杂度:O(log n)
2. AVL树
- 自平衡的二叉搜索树
- 保证任何节点的左右子树高度差不超过1
3. 红黑树
- 另一种自平衡二叉搜索树
- Java的TreeMap、C++的map底层实现
4. B树和B+树
- 多路搜索树
- 用于数据库和文件系统
5. 堆(Heap)
- 完全二叉树
- 最大堆:父节点 ≥ 子节点
- 最小堆:父节点 ≤ 子节点
- 用于优先队列和堆排序
6. 字典树(Trie)
- 用于字符串检索
- 自动补全、拼写检查
7. 线段树(Segment Tree)
- 用于区间查询和更新
8. 哈夫曼树
- 用于数据压缩
- 构造最优前缀编码
树的应用场景
- 文件系统:文件夹和文件的层次结构
- 数据库索引:B树、B+树用于高效查询
- HTML/XML解析:DOM树
- 编译器:抽象语法树(AST)
- 人工智能:决策树、游戏树(如国际象棋)
- 网络路由:路由表的组织
- 组织结构:公司的层级结构
- 优先级管理:堆实现优先队列
- 自动补全:字典树
- 图形界面:GUI组件树
Python实现示例
二叉树节点定义
class TreeNode:
def __init__(self, data):
self.data = data
self.left = None
self.right = None
完整的二叉搜索树实现
class BinarySearchTree:
def __init__(self):
self.root = None
# 插入节点
def insert(self, data):
if self.root is None:
self.root = TreeNode(data)
else:
self._insert_recursive(self.root, data)
def _insert_recursive(self, node, data):
if data < node.data:
if node.left is None:
node.left = TreeNode(data)
else:
self._insert_recursive(node.left, data)
else:
if node.right is None:
node.right = TreeNode(data)
else:
self._insert_recursive(node.right, data)
# 查找节点
def search(self, data):
return self._search_recursive(self.root, data)
def _search_recursive(self, node, data):
if node is None:
return False
if node.data == data:
return True
elif data < node.data:
return self._search_recursive(node.left, data)
else:
return self._search_recursive(node.right, data)
# 前序遍历
def preorder_traversal(self):
result = []
self._preorder_helper(self.root, result)
return result
def _preorder_helper(self, node, result):
if node:
result.append(node.data)
self._preorder_helper(node.left, result)
self._preorder_helper(node.right, result)
# 中序遍历
def inorder_traversal(self):
result = []
self._inorder_helper(self.root, result)
return result
def _inorder_helper(self, node, result):
if node:
self._inorder_helper(node.left, result)
result.append(node.data)
self._inorder_helper(node.right, result)
# 后序遍历
def postorder_traversal(self):
result = []
self._postorder_helper(self.root, result)
return result
def _postorder_helper(self, node, result):
if node:
self._postorder_helper(node.left, result)
self._postorder_helper(node.right, result)
result.append(node.data)
# 层序遍历
def levelorder_traversal(self):
if not self.root:
return []
from collections import deque
result = []
queue = deque([self.root])
while queue:
node = queue.popleft()
result.append(node.data)
if node.left:
queue.append(node.left)
if node.right:
queue.append(node.right)
return result
# 获取树的高度
def height(self):
return self._height_recursive(self.root)
def _height_recursive(self, node):
if node is None:
return -1 # 空树高度为-1,单节点高度为0
return 1 + max(self._height_recursive(node.left),
self._height_recursive(node.right))
使用示例
# 创建二叉搜索树
bst = BinarySearchTree()
# 插入节点
nodes = [50, 30, 70, 20, 40, 60, 80]
for node in nodes:
bst.insert(node)
# 查找节点
print(bst.search(40)) # True
print(bst.search(25)) # False
# 各种遍历
print("前序遍历:", bst.preorder_traversal()) # [50, 30, 20, 40, 70, 60, 80]
print("中序遍历:", bst.inorder_traversal()) # [20, 30, 40, 50, 60, 70, 80]
print("后序遍历:", bst.postorder_traversal()) # [20, 40, 30, 60, 80, 70, 50]
print("层序遍历:", bst.levelorder_traversal()) # [50, 30, 70, 20, 40, 60, 80]
# 获取树的高度
print("树的高度:", bst.height()) # 2
学习建议
初学者路径
- 理解概念:先掌握树的基本术语和概念
- 手动画图:用笔画出树的结构,理解各种遍历方式
- 实现简单树:从二叉树开始,实现基本的插入和遍历
- 练习遍历:重点理解递归遍历和层序遍历
- 学习BST:理解二叉搜索树的特性
- 进阶学习:AVL树、红黑树、堆等高级树结构
练习题推荐
- LeetCode 104: 二叉树的最大深度
- LeetCode 94: 二叉树的中序遍历
- LeetCode 102: 二叉树的层序遍历
- LeetCode 98: 验证二叉搜索树
- LeetCode 226: 翻转二叉树
时间复杂度总结
| 操作 | 二叉搜索树(平均) | 二叉搜索树(最坏) | 平衡树 |
|---|---|---|---|
| 搜索 | O(log n) | O(n) | O(log n) |
| 插入 | O(log n) | O(n) | O(log n) |
| 删除 | O(log n) | O(n) | O(log n) |
| 遍历 | O(n) | O(n) | O(n) |
总结
树是一种强大的数据结构,它:
- 提供了层次化的数据组织方式
- 支持高效的搜索、插入和删除操作
- 广泛应用于各种实际场景
- 是学习算法和数据结构的重要基础

1322

被折叠的 条评论
为什么被折叠?



