二叉查找/搜索/排序树 BST (binary search/sort tree)
有序二叉树(ordered binary tree),或已排序二叉树(sorted binary tree),是指一棵空树或者具有下列性质的二叉树:
若任意节点的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
若任意节点的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
任意节点的左、右子树也分别为二叉查找树。
没有键值相等的节点
n个节点->树高lgn
正常查找时间O(lgn)
如果二叉树线性了,查找时间为O(n)
对二叉查找树进行中序遍历,得到有序集合。
上图为一个普通的二叉查找树,按照中序遍历的方式可以从小到大的顺序排序输出:2、3、5、6、7、8。
平衡二叉查找树 AVL树
性质
它的左右子树树高差绝对值不超过1
目的
AVL树降低树高,提高查询速度
红黑树规则(RB-tree)
节点不是红就是黑
根节点黑色
叶子节点都是空黑节点
红节点下必须是两个黑节点==从叶子到根的任意路径不能有两个相同的红色节点
从任一节点到其每个叶子节点的所有路径都包含相同数目的黑色节点
正是红黑树的这5条性质,使一棵n个结点的红黑树始终保持了logn的高度,从而也就解释了上面所说的“红黑树的查找、插入、删除的时间复杂度最坏为O(log n)
Java集合中的TreeSet和TreeMap,C++ STL中的set、map,以及Linux虚拟内存的管理
1、广泛用于C++的STL中,Map和Set都是用红黑树实现的;
2、著名的Linux进程调度Completely Fair Scheduler,用红黑树管理进程控制块,进程的虚拟内存区域都存储在一颗红黑树上,每个虚拟地址区域都对应红黑树的一个节点,左指针指向相邻的地址虚拟存储区域,右指针指向相邻的高地址虚拟地址空间;
3、IO多路复用epoll的实现采用红黑树组织管理sockfd,以支持快速的增删改查;
4、Nginx中用红黑树管理timer,因为红黑树是有序的,可以很快的得到距离当前最小的定时器;
5、Java中TreeMap的实现;
红黑树插入重排原理
-
新节点默认为红色插入,如果其父节点为红色,则对其递归向上换色,如果根节点由此变为红色,则对根节点进行左旋(右侧过深)或右旋(左侧过深)
-
从根节点检查红色节点是否符合路径上的黑色节点数量一致,如果不一致,对该节点进行左旋(右侧黑色节点数量更多)或右旋(左侧黑色节点数量更多),并变换颜色,重复2操作直到符合红黑树规则。
左旋
B-树 注意B-树就是B树,-只是一个符号。
多路搜索树,是多叉的平衡二叉树
所有关键字在整颗树中出现,且只出现一次,非叶子结点可以命中;
B+树
在B-树基础上,为叶子结点增加链表指针,所有关键字都在叶子结点
中出现,非叶子结点作为叶子结点的索引;B+树总是到叶子结点才命中;
B*树
在B+树基础上,为非叶子结点也增加链表指针
首先要明白三种树名中的“-”起到的是分隔的作用,并不是“减”的意思。
因此正确的翻译应该是B树,B+树,B树。而不是B-树,B+树,B树。因此,当你听到别人说“B减树”的时候,要明白它指的是B-Tree。即B树和B-树是同一种树。
参考文献
MySQL索引背后的数据结构及算法原理
从B树、B+树、B*树谈到R 树
1、红黑树应用于哪些数据结构
c++集合类 set,map,1.8后的hashMap,linux虚拟内存管理,java中的treeSet和treeMap
2、红黑树的性质(规则)
5点
3、红黑树的各种操作的时间复杂度是多少?
由于没有倾斜(一边树高偏高)的情况,最好情况都为O(lgn)
hashmap的查找时间复杂度?
O(1)
4、.红黑树相比于BST和AVL树有什么优点?
时间复杂度
5、数据库索引为什么要用 B+ 树而不用红黑树呢?
红黑树和avl树是内存中的数据常用的数据结构,本质是为了更快的查询
b+树是多路平衡树
a、多路,一个页空间能够存更多的数据,保证磁盘旋转时能够获取更多数据,减少io
b、平衡,树高是相同的,保证每次查找的大体时间相同
6、为什么说B+树比B树更适合数据库索引?
a\ b+树的节点中不存储指向数据的指针,节点占空间更小,读取数据所需的磁盘io更小
b、b+树具体数据的指针存放在叶子节点,所以每次查询都必须走完所有树高
7、为什么插入时设置为红色节点
红黑树的特性决定,黑色节点的数量几乎是红色节点的2倍,所以插入红色节点,很大概率其父节点是黑色,减少调整的次数,效率高 这就是红黑树比AVL树插入效率高的原因!
参考彻底搞懂红黑树插入删除步骤
红黑树是如何实现自平衡的?
通过着色和左旋右旋