大部分学习所得来自:《STL源码剖析》侯捷
首先,STL中的容器分为序列式容器和关联式容器。在后者中set、map、multiset、multimap,底层机制以RB-tree(红黑树)完成;hash_set、hash_map、hash_multiset、hash_multimap,底层机制由hashtable完成。
一般而言,关联式容器的内部结构是一个balanced binary tree(平衡二叉树:一棵空树或者它的左右子树的高度差的绝对值超过1,并且它的左右子树都为二叉平衡树)。二叉平衡树有很多类型,包括AVL-tree、RB-tree、AA-tree,其中最被广泛运用于STL的是RB-tree。
1、二叉搜索树:任何节点的键值一定大于其左子树中的每一个节点的键值,并小于其右子树中的每一个节点的键值。可提供对数时间的元素插入和查询。
2、AVL tree(Adelson-Velskii-Landis tree):是一个“加上了额外平衡条件”的二叉搜索树,其平衡条件的建立是为了确保整棵树的深度为O(logN)。它要求任何节点的左右子树高度相差最多为1,可保证“对数深度”平衡状态。
在平衡被破坏时,采用“单旋转”修正外侧插入导致的不平衡,采用“双旋转”修正内侧插入导致的不平衡。
3、红黑树:
红黑树的平衡性相比AVL树弱,但是红黑树通常能够导致良好的平衡状态,其搜寻平均效率和AVL树几乎相等。
红黑树从根到叶子的最长路径不会超过最短路径的2倍。
不仅仅是一个二叉搜索树,还必须满足以下规则
(1)每个节点不是红色就是黑色
(2)根节点为黑色
(3)如果节点为红,其子节点必须为黑
(4)任一节点至NULL(树尾端)的任何路径,所含之黑节点数必须相同。
根据规则4,新增节点必须为红;根据规则3,新增节点的父节点必须为黑。当新节点根据二叉搜索树的规则到达插入点时,却不符合上述条件,那么就必须调整颜色并旋转树形。
4、红黑树与AVL树的比较:
AVL是严格的平衡树,因此在增加或者删除节点的时候,根据不同情况,旋转的次数比红黑树要多;
红黑树是用非严格的平衡来换取增删节点时候旋转次数的降低开销;
所以简单说,如果你的应用中,搜索的次数远远大于插入和删除,那么选择AVL树,
如果搜索,插入删除次数几乎差不多,应选择红黑树。即,有时仅为了排序(建立-遍历-删除),不查找或查找次数很少,R-B树合算一些。
红黑树与AVL树的调整平衡的实现机制不同,AVL靠平衡因子和旋转,红黑树靠节点颜色以及一些约定再加上旋转。因此,存在去掉颜色的红黑树后它不是AVL树,比如左子树都是黑的,右子树都是红黑相间的,这样整个树高度2n的时候,根节点的左右层数差可以到n。
红黑树能够以O(log2 n) 的时间复杂度进行搜索、插入、删除操作。此外,由于它的设计,任何不平衡都会在三次旋转之内解决。当然,还有一些更好的,但实现起来更复杂的数据结构 能够做到一步旋转之内达到平衡,但红黑树能够给我们一个比较“便宜”的解决方案。红黑树的算法时间复杂度和AVL相同,但统计性能比AVL树更高。当然,红黑树并不适应所有应用树的领域。如果数据基本上是静态的,那么让他们待在他们能够插入,并且不影响平衡的地方会具有更好的性能。如果数据完全是静态的,例如,做一个哈希表,性能可能会更好一些。
AVL树在顺序插入和删除时有20%左右的性能优势,但随机性能反而落后15%左右,现实应用当然一般都是随机情况,所以红黑树得到了更广泛的应用。
5万+

被折叠的 条评论
为什么被折叠?



