树
定义
不同于线性的数据结构数组、链表、栈,树是非线性的。如图所示(图片来源leetcode),树是由n(n>=1)个有限节点组成一个具有层次关系的集合。
常用术语
- 结点的度:结点拥有的子树的数目。例如A的度为3。
- 叶子:度为零的结点,如B、E、F、G
- 树的度:树中结点的最大的度
- 节点的高度:节点到叶子节点的最长路径
- 节点的深度:根节点到这个节点所经历的边的个数
- 节点的层数:节点的深度加 1
- 树的高度:根节点的高度
二叉树
定义
二叉树是每个节点最多有两个子树的树结构。如图所示:
二叉树是最常用的树。
满二叉树
除了叶子节点之外,每个节点都有左右两个子节点,这种二叉树就叫作满二叉树。如图:
完全二叉树
一棵二叉树中,只有最下面两层结点的度可以小于2,并且最下一层的叶结点集中在靠左的若干位置上。这样的二叉树称为完全二叉树。一棵满二叉树必定是一棵完全二叉树,而完全二叉树未必是满二叉树。如图所示:
二叉查找树(或二叉搜索树)
二叉搜索树(BST)是二叉树的一种特殊表示形式,它满足如下特性:
- 每个节点中的值必须大于(或等于)存储在其左侧子树中的任何值。
- 每个节点中的值必须小于(或等于)存储在其右子树中的任何值。
如图所示:
AVL树
AVL树是一种严格的平衡的二叉树。平衡二叉树的严格定义是这样的:二叉树中任意一个节点的左右子树的高度相差不能大于1。如图:
上面的两张图片,左边的是AVL树,它的任何节点的两个子树的高度差别都<=1;而右边的不是AVL树,因为7的两颗子树的高度相差为2(以2为根节点的树的高度是3,而以8为根节点的树的高度是1)。
平衡二叉树就是AVL树,是一种特殊的二叉搜索树。
红黑树
红黑树是一种特殊的二叉查找树。红黑树的每个节点上都有存储位表示节点的颜色,可以是红(Red)或黑(Black)。如图所示:
红黑树需要满足的要求:
- 根节点是黑色的;
- 每个叶子节点都是黑色的空节点(NIL),也就是说,叶子节点不存储数据;
- 任何相邻的节点都不能同时为红色,也就是说,红色节点是被黑色节点隔开的;
- 每个节点,从该节点到达其可达叶子节点的所有路径,都包含相同数目的黑色节点;
哈夫曼树
路径长度:树中一个结点到另一个结点之间的分支构成这两个结点之间的路径,路径上的分支数目为路径长度。例如:节点4 到 节点5 的路径长度为 2;节点3 到节点6 的路径长度为4.
树的路径:从树根到每一个结点的路径长度之和,这种路径长度最短的树是完全二叉树. 上图中,树的路径长度为:1 + 1 + 2 + 2 + 2 + 3 = 11。
权:若将树中结点赋一个有某种含义的数值,则这个数值称为该结点的权
结点的带权路径长度:从根结点到该结点间的路径长度与该结点的权的乘积,如D节点的带权路径长度为 4 * 3 = 12
树的带权路径长度(WPL):树中所有带权结点的路径长度之和 上图中,树的带权路径长度WPL为:7 X 1 + 5 X 2 + 2 X 3 + 4 X 3 = 35。
而哈夫曼树就是树的带权路径长度最短的二叉树,也叫做最优树。
前缀树
N 叉树 :一棵以根节点开始,每个节点不超过 N 个子节点的树,称为 N叉树
如图,前缀树(又叫字典树) 是 N叉树 的一种特殊形式。通常来说,一个前缀树是用来 存储字符串 的。前缀树的每一个节点代表一个 字符串(前缀)。每一个节点会有多个子节点,通往不同子节点的路径上有着不同的字符。子节点代表的字符串是由节点本身的 原始字符串 ,以及 通往该子节点路径上所有的字符 组成的。
B树、B+树、B*树
背景
当我们数据量非常大,以至于必须需要磁盘来存储数据时。由于一次磁盘访问时间远远大于内存访问时间,因此减少磁盘访问的次数就可以缩短访问的时间。
如果使用之前讲过的二叉平衡搜索树,则查找的速率为logN次磁盘访问的时间;若过我们有更多的分支,那么树的高度就会降低,磁盘访问的速度就会缩小为 ,这样虽然代码变得更加复杂,但是相对于磁盘访问的时间可以忽略不计。
B树
B树(也叫做 B-树) 是一种多路平衡搜索树,不是二叉搜索树,B树的 M > 2,B树的 M 可以等于 3、4、5....。例如:当 M = 3时,是三叉树;而 M = 4 时是四叉树,而二叉搜索树 M = 2。
如图(图片来源知乎)是M = 5的B树.其中 M、D、G是保存的数据。
B树特点:
- 所有节点的数据都是按从小到大的顺序排列
- 非叶子节点保存数据的个数满足[ceil(M/2) - 1,M-1]
- 所有叶子节点均在同一层
注:ceil()是向上取整的函数,例如 ceil(1.1) = 2
B+树
B+树是B树的一个升级版,它与B+树的不同点为:
- 非叶子节点不保存数据记录的指针,只进行数据索引;叶子节点用来保存数据
- B+树叶子节点的关键字从小到大有序排列,左边结尾数据都会保存右边节点开始数据的指针
B+树如图所示(图片来源这里):
B*树
B*树是B+树的变种,其与B+树的区别有:
- B*树在B+树的非根和非叶子节点再增加指向兄弟节点的指针
- B*树规定非叶子节点的键值个数至少为(2/3)M
B*树如图(图片来源这里)
参考
- 平衡二叉树、B树、B+树、B*树 理解其中一种你就都明白了
- B树、B+树、B*树
- 数据结构--哈夫曼树
- leetcode
- 极客时间的《数据结构与算法之美》专栏