当前位置: 首页 > java >正文

004 树与二叉树:从原理到实战

摘要:树形结构是计算机科学的基石,而二叉树则是其中最闪耀的明珠。本文将简单介绍树和二叉树的概念,为后续数据结构和算法的学习打一个基础


一、树(Tree):数据世界的金字塔结构

1. 树的本质

树是一种分层抽象模型,它用节点间的父子关系打破了线性结构的桎梏。就像现实中的金字塔:

  • 根节点是塔尖,掌握全局
  • 内部节点是中层管理者,承上启下
  • 叶子节点是基层执行者,专注细节
树的数学定义(严谨版)

树T是一个满足以下条件的n(n≥0)个节点的有限集合:

  1. 当n=0时,称为空树
  2. 当n>0时,存在唯一根节点,其余节点分为m(m≥0)个互不相交的子树

2. 树的20个核心术语详解

通过家族关系类比理解(以图1为例):

        董事长(CEO)/    |    \CTO    CFO   COO/  \         /   \Dev1  Dev2   Ops1  Ops2
术语解释示例
度 (Degree)节点的子节点数CTO的度为2
路径 (Path)节点间的边序列CEO→CTO→Dev1是路径
兄弟节点 (Sibling)同父节点的节点Dev1和Dev2是兄弟
堂兄弟节点同层但父节点不同Dev1与Ops1是堂兄弟
祖先节点 (Ancestor)从根到该节点的路径上的所有节点CEO是Dev1的祖先
后代节点 (Descendant)某节点子树中的所有节点CTO的后代是Dev1,Dev2
森林 (Forest)互不相交的树的集合删除根节点后得到森林

3. 树的分类大全(7种维度)

维度1:节点分支数
class TreeNode:def __init__(self, data):self.data = dataself.children = []  # 普通树的实现方式# 二叉树节点
class BinaryTreeNode:def __init__(self, val):self.val = valself.left = Noneself.right = None
类型特点应用场景
普通树子节点数无限制文件系统
二叉树每个节点最多2个子节点表达式计算
Trie树每个边代表一个字符输入法词库
维度2:节点关系特性
  • 有序树:子节点顺序不可交换(如二叉树)
  • 无序树:子节点顺序无关(如公司部门结构)

4. 树的5种遍历方式详解(非二叉树)

以公司组织架构为例:

        CEO/   |   \VP1  VP2  VP3/  \       / | \
M1   M2   M3 M4 M5
  1. 广度优先遍历(BFS)
    访问顺序:CEO → VP1 → VP2 → VP3 → M1 → M2 → M3 → M4 → M5
    场景:计算组织架构层级

  2. 深度优先遍历(DFS)

    • 前序:CEO → VP1 → M1 → M2 → VP2 → VP3 → M3 → M4 → M5
      (适用于复制树结构)
    • 后序:M1 → M2 → VP1 → VP2 → M3 → M4 → M5 → VP3 → CEO
      (适用于计算文件夹大小)
    • 中序:仅对二叉树有意义
  3. Z型遍历
    输出:CEO ← VP1 → VP2 ← VP3 → M3 ← M4 → M5
    场景:DNA序列分析

代码实现(Python)
from collections import dequeclass GeneralTree:def __init__(self, root):self.root = rootdef bfs(self):if not self.root:return []result = []queue = deque([self.root])while queue:level_size = len(queue)current_level = []for _ in range(level_size):node = queue.popleft()current_level.append(node.data)for child in node.children:queue.append(child)result.append(current_level)return result  # 返回分层结果# 示例用法
ceo = TreeNode("CEO")
vp1 = TreeNode("VP1")
vp2 = TreeNode("VP2")
vp3 = TreeNode("VP3")
ceo.children = [vp1, vp2, vp3]
vp1.children = [TreeNode("M1"), TreeNode("M2")]
vp3.children = [TreeNode("M3"), TreeNode("M4"), TreeNode("M5")]tree = GeneralTree(ceo)
print("BFS结果:", tree.bfs())
# 输出: [['CEO'], ['VP1', 'VP2', 'VP3'], ['M1', 'M2', 'M3', 'M4', 'M5']]

5. 树的6大经典应用场景

场景1:Linux文件系统
/
├── bin
├── etc
│   ├── apt
│   └── network
├── home
│   ├── user1
│   └── user2
└── usr
  • 路径表示:/home/user1/docs/file.txt
  • 操作特点:快速定位文件(类似B+树索引)
场景2:XML/HTML解析
<html><head><title>Page</title></head><body><div class="content"><p>Hello World</p></div></body>
</html>

对应的DOM树:

           html/     \head       body|          |title       div|           |"Page"       p|"Hello World"
场景3:人工智能决策树
          是否周末?/        \是            否/              \
天气好?          需要加班?/  \             /    \
外出 宅家        加班   看电影
  • 信息增益:通过熵值计算最佳分裂属性
  • 剪枝优化:防止过拟合

二、二叉树:简洁与高效的完美平衡

1. 二叉树的5大特性证明

特性1:第i层最多有2^(i-1)个节点
证明:数学归纳法

  • 基础:i=1时,根节点1个=2^0 ✔️
  • 归纳:假设第k层最多 2 k − 1 2^{k-1} 2k1节点,则第k+1层最多 2 ⋅ 2 k − 1 = 2 k 2 \cdot 2^{k-1}=2^k 22k1=2k ✔️

特性2:深度为h的二叉树最多有 2 h − 1 2^{h -1} 2h1个节点
应用:快速判断树是否满二叉树

2. 完全二叉树的数组存储技巧

概念:
满二叉树:除了叶子节点外,其余节点都有左右子节点
完全二叉树:可以是满二叉树,也可以是某个满二叉树删除最后一层的最后若干个节点。

用数组存储完全二叉树
将节点按层序存入数组:

        1(0)/   \2(1)   3(2)/  \ 
4(3) 5(4)

数组表示:[1,2,3,4,5]

父子关系计算

  • 父节点索引 = (i-1)//2
  • 左子节点索引 = 2i +1
  • 右子节点索引 = 2i +2
class ArrayBinaryTree:def __init__(self, array):self.array = arraydef parent(self, index):return (index-1)//2 if index >0 else Nonedef left_child(self, index):left = 2*index +1return left if left < len(self.array) else None# 示例
tree = ArrayBinaryTree([1,2,3,4,5])
print(tree.left_child(0))  # 输出1

3. 二叉搜索树(BST)的平衡之道

查找效率对比

数据结构平均时间复杂度最坏情况
数组(无序)O(n)O(n)
BSTO(log n)O(n)
平衡BSTO(log n)O(log n)

BST退化成链表的危险

1\2\3\4

此时查找效率降级为O(n)

解决方案
引入AVL树(通过旋转保持平衡)或红黑树(通过颜色标记)


三、平衡二叉树

1. AVL树旋转的四种情况

以左旋为例:

不平衡点(A)\B\C

旋转后:

      B/ \A   C

五、知识图谱:树形结构的演进之路

二叉树
N叉树
二叉搜索树
AVL树
红黑树
B树
B+树
数据库索引
TreeMap
快速查找

总结

本文就树的概念做一个简要介绍,其中涉及到的更深入的概念,随后还会涉及到。

推荐练习

/* 树和二叉树 已完结
144. 二叉树的前序遍历(简单)
94. 二叉树的中序遍历(简单)
145. 二叉树的后序遍历(简单)
102. 二叉树的层序遍历(中等)
107. 二叉树的层序遍历 II(中等)
199. 二叉树的右视图(中等)
105. 从前序与中序遍历序列构造二叉树(中等)
106. 从中序与后序遍历序列构造二叉树(中等)
108. 将有序数组转换为二叉搜索树(简单)
101. 对称二叉树(简单)
104. 二叉树的最大深度(简单)
111. 二叉树的最小深度(简单)
110. 平衡二叉树(简单)
112. 路径总和(简单)
113. 路径总和 II(中等)
124. 二叉树中的最大路径和(困难)
98. 验证二叉搜索树(中等)
99. 恢复二叉搜索树(中等)
230. 二叉搜索树中第K小的元素(中等)
450. 删除二叉搜索树中的节点(中等)
235. 二叉搜索树的最近公共祖先(简单)
236. 二叉树的最近公共祖先(中等)
297. 二叉树的序列化与反序列化(困难)
501. 二叉搜索树中的众数(简单,可用Morris中序遍历优化空间)
226. 翻转二叉树(简单)
543. 二叉树的直径(简单)
617. 合并二叉树(简单)
96. 不同的二叉搜索树(中等)
337. 打家劫舍 III(中等,树形DP)

http://www.xdnf.cn/news/3725.html

相关文章:

  • Baklib赋能企业知识管理数字化转型
  • MCP 协议知识分享指南
  • VS调试技巧
  • 网站即时备份,网站即时备份的方法有哪些
  • 简介QML中的Canvas
  • 机器学习入门-线性回归模型/损失函数/梯度下降
  • 【WZOI】【题解】【质数密度】质数密度题解报告
  • 旋转矩阵公式理解
  • 【云备份】服务端数据管理模块设计与实现
  • 嵌入式 GCC 编译工具链:32 位与 64 位助力高效开发
  • [UVM]UVM中reg_map的作用及多个rem_map的使用案例
  • 【C++篇】类和对象(上)
  • 饱和蒸汽再生数据采集挥发性有机物(VOCs)吸附脱附实验装置
  • Pillow 玩图术:轻松获取图片尺寸和颜色模式
  • 肥胖风险的多类预测——CatBoost模型的89%
  • 《MATLAB实战训练营:从入门到工业级应用》趣味入门篇-用声音合成玩音乐:MATLAB电子琴制作(超级趣味实践版)
  • 用可视化学习逆置法
  • 【Linux】Linux应用开发小经验
  • 信息安全导论 第七章 网络边界防御技术
  • 前端面经-VUE3篇(二)--vue3组件知识(二)依赖注入、异步组件、生命周期、组合式函数、插件
  • piccolo-large-zh-v2 和 bge-m3哪个效果好?
  • 【Mytais系列】SqlSession
  • 经典算法 求解硬币组成问题
  • 【Mytais系列】Select语句执行流程
  • 学习笔记:Qlib 量化投资平台框架 — FOR DEVELOPERS
  • 使用线性表实现通讯录管理
  • MySQL表的约束
  • Yocto介绍
  • 【C语言练习】018. 定义和初始化结构体
  • 【c++】模板详解