Python数据结构深度探索:树的构建与遍历
Python数据结构深度探索:树的构建与遍历
一、树的基础概念
1.1 定义与特性
树(Tree)是一种非线性的层次化数据结构,具有以下核心特征:
- 由**节点(Node)和边(Edge)**组成
- 每个节点有零个或多个子节点
- 没有父节点的节点称为根节点(Root)
- 没有子节点的节点称为叶节点(Leaf)
- 任意两个节点之间有且仅有一条路径
1.2 核心术语
- 深度(Depth):根节点到当前节点的边数
- 高度(Height):当前节点到最深叶节点的边数
- 层级(Level):根节点为第1层,子节点层级递增
- 子树(Subtree):以某个节点为根的局部树结构
二、二叉树与二叉搜索树
2.1 二叉树定义
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
- 每个节点最多有两个子节点
- 左子树和右子树有明确区分
2.2 二叉搜索树(BST)
- 关键性质:
- 左子树所有节点值 < 根节点值
- 右子树所有节点值 > 根节点值
- 左右子树都是BST
- 操作复杂度:
- 查找:O(log n)
- 插入:O(log n)
- 删除:O(log n)
三、树的构建与操作
3.1 基础操作实现
class BinaryTree:
def __init__(self):
self.root = None
def insert(self, val):
"""递归插入节点"""
def _insert(node, value):
if not node:
return TreeNode(value)
if value < node.val:
node.left = _insert(node.left, value)
else:
node.right = _insert(node.right, value)
return node
self.root = _insert(self.root, val)
def search(self, target):
"""迭代查找节点"""
current = self.root
while current:
if target == current.val:
return True
elif target < current.val:
current = current.left
else:
current = current.right
return False
3.2 遍历算法
递归实现
def preorder(root):
"""前序遍历:根->左->右"""
if root:
print(root.val, end=' ')
preorder(root.left)
preorder(root.right)
def inorder(root):
"""中序遍历:左->根->右"""
if root:
inorder(root.left)
print(root.val, end=' ')
inorder(root.right)
def postorder(root):
"""后序遍历:左->右->根"""
if root:
postorder(root.left)
postorder(root.right)
print(root.val, end=' ')
迭代实现
def iterative_inorder(root):
"""栈实现中序遍历"""
stack = []
current = root
while stack or current:
while current:
stack.append(current)
current = current.left
current = stack.pop()
print(current.val, end=' ')
current = current.right
四、每日挑战:验证二叉搜索树
4.1 题目要求
实现函数 is_valid_bst(root)
:
- 输入:二叉树根节点
- 输出:布尔值(是否有效BST)
- 要求:
- 时间复杂度不超过O(n)
- 空间复杂度不超过O(n)
4.2 参考答案
# 方法一:递归边界检查
def is_valid_bst(root):
def validate(node, low=-float('inf'), high=float('inf')):
if not node:
return True
if not (low < node.val < high):
return False
return (validate(node.left, low, node.val) and
validate(node.right, node.val, high))
return validate(root)
# 方法二:中序遍历验证
def is_valid_bst_inorder(root):
stack, prev = [], -float('inf')
while stack or root:
while root:
stack.append(root)
root = root.left
root = stack.pop()
if root.val <= prev:
return False
prev = root.val
root = root.right
return True
五、复杂度对比
操作 | 平均复杂度 | 最坏情况 |
---|---|---|
插入 | O(log n) | O(n) |
查找 | O(log n) | O(n) |
删除 | O(log n) | O(n) |
遍历 | O(n) | O(n) |
六、应用场景
- 文件系统目录结构
- 数据库索引(B树/B+树)
- 游戏决策树
- XML/HTML文档解析
- 机器学习决策树算法
七、最佳实践
- 内存优化:使用线索二叉树减少空指针
- 平衡策略:AVL树或红黑树保持平衡
- 批量操作:Morris遍历实现O(1)空间遍历
- 可视化调试:使用Graphviz生成树结构图
# 安装graphviz:pip install graphviz
from graphviz import Digraph
def visualize_tree(root):
dot = Digraph()
def add_nodes(node):
if node:
dot.node(str(node.val))
if node.left:
dot.edge(str(node.val), str(node.left.val))
add_nodes(node.left)
if node.right:
dot.edge(str(node.val), str(node.right.val))
add_nodes(node.right)
add_nodes(root)
return dot
进阶练习:尝试实现红黑树的插入和删除操作,观察自平衡过程如何维持O(log n)的操作复杂度。