二叉树、二叉查找树、平衡树和红黑树概念及其性质
前言
在所有的树结构,基本上都遵循左小右大的原则。本文分享二叉树、二叉查找树、平衡树和红黑树概念及其性质。
二叉树
二叉树(Binary Tree)是指每个节点最多只有两个分支的树结构(即不存在分支大于 2 的节点),如下图所示:
这是一棵拥有 6 个节点深度为 2(深度从 0 开始),并且根节点为 3 的二叉树。二叉树的左右两个分支通常被称作左子树和右子树,而且这些分支左右次序不能随意地颠倒。
二叉查找树
二叉查找树是一种特殊结构的二叉树,可以非常方便地对树中所有节点进行排序和检索。 一棵空树或者满足以下性质的二叉树被称之为二叉查找树(Binary Search Tree),也被称为二叉搜索树、有序二叉树(Ordered Binary Tree)或排序二叉树(Sorted Binary Tree)等。
(1)若任意节点的左子树不为空,则左子树上所有节点的值均小于它的根节点的值;
(2)若任意节点的右子树不为空,则右子树上所有节点的值均大于或等于它的根节点的值;
(3)任意节点的左、右子树都是二叉查找树。
一棵标准的二叉查找树:
排序二叉树的数据操作效率:
1. 查找效率最好为O(log n)、最坏为O(n);
2. 插入效率和查找效率相同(先查找插入的位置,且只插入到叶子节点);
3. 删除效率最好为O(log n) + O(1)(只有左或者右子树),最坏为O(log n) + O(log n)(只有左右子树同时存在)。
平衡二叉树
又称作AVL树。它是一棵空树或它的左右两棵子树高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。这样的好处就是可以减少二叉查找树的深度。
平衡二叉树牺牲了插入和删除数据的代价,但是提高了查询效率(稳定查询效率为O(log n))。
红黑树
关于红黑树的性质,它在排序二叉树基础上增加了如下几个要求:
性质 1:每个节点要么是红色,要么是黑色。
性质 2:根节点永远是黑色的。
性质 3: 所有叶子都是黑色的空节点(NIL 节点);
性质 4:每个红色节点的两个子节点都是黑色。
性质 5:从任一节点到其子树中每个叶子节点的路径都包含相同数量的黑色节点。
红黑树结构如下图所示:
红黑树的优势
红黑树的优势在于它是一棵平衡二叉查找树,普通的二叉查找树(非平衡二叉查找树)在极端情况下可能会退化为链表的结构,例如,当我们依次插入 3、4、5、6、7、8 这些数据时,二叉树会退化为如下链表结构:
当二叉查找树退化为链表数据结构后,再进行元素的添加、删除以及查询时,它的时间复杂度就会退化为 O(n);而如果使用红黑树的话,它就会将以上数据转化为平衡二叉查找树,这样就可以更加高效的添加、删除以及查询数据了,这就是红黑树的优势。红黑树的高度近似 log2n,它的添加、删除以及查询数据的时间复杂度为 O(logn)。自平衡的红黑树
红黑树通过变色和旋转操作来维护红黑树的规则,变色就是让黑节点变成红的,红的变成黑的,旋转又分为“左旋转”和“右旋转”。这个比较复杂,容易晕,我们就只要知道红黑树就是通过这种方式来实现它的自平衡性就行了。
B树(平衡多路查找树)
在学习二叉树和平衡二叉树的过程中,我们发现,每个节点上只存储了一个元素,当有100个元素需要储存时,在二叉树及平衡二叉树中,会产生100个节点。如果让一个节点存储多个元素,那么,是不是可以减少节点,从而减少树整体层级高度呢?要知道,减少树高度的过程,就是优化查询效率的过程。
于是,B树就出现了,B树与平衡二叉树相似,不同的是B树属于多叉树,又名平衡多路查找树,顾名思义,就是每个节点上可以存储多个元素的树。与平衡二叉树不同的是,B树所有的叶子节点都处于同一层级,不存在层级高度差的问题。数据库索引技术里大量使用B树和B+树这两种数据结构。
一棵n阶的B-Tree有如下特性:
- 若根节点不是叶子节点,则至少有2个子节点 ;
- 每个非根节点包含的关键字个数m满足:n/2 - 1 < m < n -1;
- 除根节点以外,树的维纳指标正好是关键字的总数+1,即除根节点以外的所有节点(不包括叶子节点)的度数正好是关键字的总数+1,故内部子树个数k满足:n/2 < k < n -1;
- 所有叶子节点都位于同一层,且不包含其它关键字信息。
- 每个节点既保存索引,又保存数据。
MongoDB使用B-树,所有节点都有Data域,而且不需要进行范围查找,只要找到指定索引就可以进行访问,无疑单次查询平均快于Mysql。
B+树
B+树是一个n叉树,是B树的扩展,每个节点通常都有多个孩子,一颗B+树包含根节点、内部节点和叶子节点。内部节点又称为索引节点。
B+树的特征如下:
-
非叶子节点不存放数据,只存放keys;
-
叶子节点之间存在指针相连,而且是单链表;
-
有n个子树的节点含有n个关键字;
-
所有叶子节点包含了全部关键字的信息,以及指向这些关键字记录的指针,且叶子节点本身依赖关键字的大小,即自小而大顺序连接;
-
所有的非终端节点可以看成索引的一部分,节点中包含了其它子树的最大或最小关键字。
其实,B+树是二叉搜索树的扩展,二叉搜索树是每次一分为二,B+ 树是每次一分为多。B+树相对于B树而言,提升了插入、删除和查找的效率。
Mysql作为一个关系型数据库,数据的关联性是非常强的,区间访问是常见的一种情况,B+树由于数据全部存储在叶子节点,并且通过指针串在一起,这样就很容易的进行区间遍历甚至全部遍历。