%% # 纲要 > 主干纲要、Hint/线索/路标 # Q&A #### 已明确 #### 待明确 > 当下仍存有的疑惑 **❓<font color="#c0504d"> 有什么问题?</font>** # Buffer ## 闪念 > sudden idea ## 候选资料 > Read it later %% # 总结 B 树与 B+树是 "**自平衡==多叉==搜索树**",可**保持数据==有序==**,支持在 $O(\log n)$ 时间进行**查询**、**顺序访问**、**插入**和**删除**操作。 > [!info] $M$ 阶 B 树/B+ 树:即**树中每个节点==最多==具有 $M$ 个子节点** <br><br> ## "B 树" 与 "B+树"的区别 - B 树: - **内部节点**同时存储 **关键字 & 对应数据**。 - B+树: - **内部节点**仅存储 "**关键字**"(索引),**数据**只在 "**==叶节点==**" 存储。 - **叶节点层**构成 "**双向链表**",支持 "**==范围查询==**"。 > [!NOTE] B+ 树的优点 > > - **索引节点** 仅存储索引而无数据,占用空间小,故**相较于 B 树==单节点可存储更多索引==**,**树的高度将更矮**。 > - **数据全部集中在叶节点**,且叶节点层构成 "**双向链表**" 的形式,故支持**高效的 "==范围查询=="**。 > - 例如,对于 `SELECT * from tbl where t > 10;` 这类查询,在定位到数据 `t=10`后,**即可沿着 next 指针一路查找**。 > - B 树不支持直接的范围查询,范围查询**需要遍历树**。 > > [!info] B+树是关系型数据库的 "**标准索引结构**" > > - MySQL InnoDB 使用 B+树索引(聚簇索引和二级索引) ## B 树/B+树的节点信息 B 树、B+树中节点包含的信息: | | B 树节点 | B +树内部节点 | B+树叶节点 | | ------------ | ----- | --------- | ------ | | **关键字** 数组 | ✔️ | ✔️ | ✔️ | | **数据指针** 数组 | ✔️ | ❌ | ✔️ | | **子节点指针** 数组 | ✔️ | ✔️ | ❌ | | **双向链表**指针 | ❌ | ✔️(部分实现有) | ✔️ | - **关键字** 数组:每个节点内包含 **多个关键字**,**每个关键字** 即为一项数据的 "**==索引==**",对应一个 "**数据指针**"。 - **数据指针** 数组:指向一项数据的实际位置。 - **子节点指针** 数组:指向子节点的指针。 - **双向链表指针**:B+树的**所有叶子节点**通过 `prev`、`next` 两个指针形成 "**==有序==的双向链表**",实现 "**范围查询**"。 > [!important] "**关键字**" 即为一项数据的 「**==索引==**」,要求 **==唯一无重复==**,与 "**数据指针**" 逐一对应 <br><br><br> # B 树 > B-Tree $M$ 阶 B 树定义为: - **根节点**若非叶节点,则 **==至少==有 2 个子节点**。 - 除根节点外,每个**内部节点** 的 **==子节点数量==** 范围为 :$\left[{\Large\left\lceil\frac{M}{2}\right\rceil}, M\right]$ - 除根节点外,每个节点的 "**==关键字数量==**" 范围为:$\left[{\Large\left\lceil\frac{M}{2}\right\rceil}-1, M-1\right]$ - 具有 **$k$ 个子节点**的节点,**具有 $k -1$ 个关键字**。 - **关键字==升序==排列**。 - **子节点排列满足 "==搜索树==" 的性质**。 - **所有叶节点均在同一层**。 > [!info] 阶数 $M$ 即每个节点 "**==最多==拥有的子节点数量**" > > 当 $M=100$ 时,**百万**数据量 B+树是 3 层,**亿级**数据量的 B+树是 5 层。 > [!NOTE] B 中每个节点内的 **关键字升序排列**,且其**子节点排列**满足 "**==搜索树==**" 性质 > > ![[Excalidraw-Solution/B树与B+树.excalidraw.md#^group=K69UYEdbhuIRZOYtHxxtC|725]] > > > [!example] 5 阶 B 树 > > ![[_attachment/00-数据结构与算法笔记/数据结构/B树与B+树.assets/IMG-B树与B+树-6F9EF4A89C84984EEFAFF56ABAD89622.png|621]] > > [!example] 3 阶 B 树 > > ![[_attachment/00-数据结构与算法笔记/数据结构/B树与B+树.assets/IMG-B树与B+树-B2DD0BF6E6F31678E8F07098B671D8E2.png|814]] > > <br><br> # B+ 树 B+ 树是 B 树的变体和升级,更适合实现实际应用中操作系统的**文件索引**和**数据库索引**。 **$M$ 阶 B+树** 进一步具备以下特性: - **内部节点**只存储 "==**关键字**==",无对应数据,每项关键字为其**相邻后一子树** 中的 **==最小==叶节点关键字**。 - **叶节点** 存储 **关键字&数据**,**所有数据**都只存储在叶节点。 - 部分实现中,**叶节点**不同于内部节点,若其**最多可存储 $N$ 项关键字**,则**至少需存储 ${\Large\left\lceil\frac{N}{2}\right\rceil}$ 项**。 - **叶节点**额外具有 `prev`、`next` 指针,构成一条 "**==有序双向链表==**",支持 **==范围查询==**(直接遍历叶节点) - 部分实现中,**每层内部节点**也均构成 "有序双向链表"。 > [!example] 5 阶 B+ 树 > ![[_attachment/00-数据结构与算法笔记/数据结构/B树与B+树.assets/IMG-B树与B+树-4009124E16E924C9ED009BDB30E09DD1.png]] > [!example] 4 阶 B+树 > > 部分实现中,**叶节点**不同于内部节点,若其**最多可存储 $N$ 项关键字**($N\neq M-1$),则**至少需存储 ${\Large\left\lceil\frac{N}{2}\right\rceil}$ 项**。 > > ![[_attachment/00-数据结构与算法笔记/数据结构/B树与B+树.assets/IMG-B树与B+树-3DCE2ACC74C58D1C8A5F7EF7DDDAA6B9.png|629]] > > > > [!quote] > > - Each node, except for the root and the leaves, has $\left[{\Large\left\lceil\frac{M}{2}\right\rceil}, M\right]$ children,and has $\left[{\Large\left\lceil\frac{M}{2}\right\rceil}-1, M-1\right]$ keys. > > - If each leaf can store $N$ records at most($N$ may be not equal to $M-1$),it must store ${\Large\left\lceil\frac{N}{2}\right\rceil}$ records at least. > <br><br> # 参考资料 - [B 树 - OI Wiki](https://oi-wiki.org/ds/b-tree/) - [B+ 树 - OI Wiki](https://oi-wiki.org/ds/bplus-tree/) - [B树(B-树)、B+树、R树简介 - mylomen](https://mylomen.com/archives/177) - [notes/docs/B树和B+树详解.md at master · wardseptember/notes · GitHub](https://github.com/wardseptember/notes/blob/master/docs/B%E6%A0%91%E5%92%8CB+%E6%A0%91%E8%AF%A6%E8%A7%A3.md) # Footnotes