文件夹套文件夹、公司一层管一层——树是【一对多】的层次结构;二叉树每节点最多两个孩子,完全二叉树能直接装进数组,平衡树保证不歪成一根链——本章收官,也是第三章【理想的数据处理方式】的答案:结构选对,查找从百万次降到二十次。
数组(3-8)是【一对一排队】、树是【一对多分层】——数据结构的最后一块大拼图。回收三处旧地:文件系统(树莓派课 4-4 目录树)、面向对象继承(C++ 课第十一章的类层次也是树)、哈希(3-13 的另一条加速路线)。
一、树:一对多的层次结构
树由节点组成,最顶上叫根,往下每层分叉,最末梢叫叶子。生活原型全是它:文件夹(根目录往下套)、公司组织架构、族谱、HTML 标签嵌套。树的判定就一条:任何节点只能有一个上级(父节点)——两个上级的那不叫树,叫图(后面课程的事)。
二、二叉树与它的两种形态
二叉树:每个节点最多两个孩子(左孩子、右孩子)——结构最简单、规律最好用:
- 完全二叉树:除最后一层外全满,最后一层从左到右排——可以无缝装进数组!下标规律(下标从 0 数):下标 i 的节点,父节点是 (i-1)//2,左孩子 2i+1、右孩子 2i+2。堆(优先队列)就靠这条规律住在数组里;
- 二叉搜索树(BST):左子树全部 < 根 < 右子树——查找像【猜数字游戏】对半砍,100 万个节点只要约 20 次比较(2 的 20 次方约 100 万)。
三、平衡树:别让树歪掉
二叉搜索树有个致命弱点:按顺序插入就歪成一根链(1、2、3、4 依次插入,全往右边挂)——查找退化回 O(n),白搭。平衡树(AVL、红黑树)在插入删除时自动旋转整形,保证左右大致等高——查找稳定在 O(log n)。现实里数据库索引(B 树家族)、语言标准库的有序集合,底层全是平衡树。
四、动手 Demo:数组里的树
tree = [8, 3, 10, 1, 6, 14] # 完全二叉树按层放进数组
def parent(i): return (i - 1) // 2 # 父节点下标
def left(i): return 2 * i + 1
def right(i): return 2 * i + 2
print(tree[parent(3)]) # tree[1] -> 3 (下标3 的爸爸)
print(tree[left(1)]) # tree[3] -> 1 (下标1 的左孩子)
print(tree[right(1)]) # tree[4] -> 6 (下标1 的右孩子)
看到什么算成功:3、1、6。
读结果:数组的 6 个元素画成分层图——根 8,第二层 3 和 10,第三层 1、6、14。同一份数据两种视图:数组给【O(1) 的上下级跳转】,树给【分层的直觉】。这条下标规律正是堆排序与优先队列的全部地基。
五、30 秒实验
跑 import heapq; h = [5, 1, 8]; heapq.heapify(h); print(h)——得 [1, 5, 8]。heapify 一步把普通列表整成二叉堆(最小值浮到下标 0)——完全二叉树的数组形态正在你电脑里天天干活。
六、常见误区
- 【树的根在上还是在下随便画】——习惯上根永远在最上面(倒着长的树);【根节点】【父节点】【叶节点】都以【往根的方向是上】为准。
- 【二叉搜索树永远快】——错。不保证平衡就退化:顺序插入歪成链、查找 O(n);要快必须平衡——所以现实中的 BST 基本都是平衡树变种。
- 【完全二叉树和满二叉树是一回事】——错。满二叉树每层都满;完全二叉树允许最后一层【从左排不满右边】——完全的约束更松,恰好够【装进数组不浪费】。
自测三问(点开对答案)
1. **下标 i 的节点,父与两孩子下标各是多少?** 答:父 (i-1)//2、左孩子 2i+1、右孩子 2i+2(下标从 0 起)——完全二叉树住数组的通行证。 2. **为什么平衡树查找是 O(log n)?** 答:每下一层候选砍一半(左右子树有序分开)——100 万节点约 20 层就锁定,与哈希的 O(1) 相比还多送【有序遍历】。 3. **数据库索引为什么用 B 树家族不用普通二叉搜索树?** 答:数据量巨大时树高决定磁盘读取次数——B 树一个节点多叉、树更矮,磁盘 I/O 次数大幅减少。- ☑ 第三章 完结 —— 教材这一章已读完十七节:从进制(3-1)与位运算(3-2)的地基出发,走过算术与变量(3-3~3-6)、整数与浮点的精度世界(3-7)、数组到链表的存法之争(3-8/3-15)、字符编码与 Unicode 统一(3-9/3-10)、结构与枚举(3-11)、类型转换与溢出(3-12)、哈希(3-13)、指针(3-14)、栈与队列(3-16),最后以树(3-17)收官——下一章第四章已开读:流程图、程序处理的基础
相关笔记
- 关联数组、哈希函数 —— 查找加速的另一条路线
- 树莓派 4-4 · 目录结构 —— 文件系统就是一棵树
- C++ 11.1 · 继承 —— 类的层次也是一棵树
- 第四章 4-1 · 流程图 —— 下一章起点:处理流程的图纸
- 第四章 4-17 · 字符串查找与 BM 算法 —— 下一章收官:有序思考的落地
- ⌨️ 编程原理 · 索引 —— 全课路线图