STL-使用红黑树作为底层的原因简单解释

STL-使用红黑树作为底层的原因简单解释

​ 在C++标准模板库中,map\set\mutimap\mutiset均是以红黑树作为底层来实现的。为什么要以红黑树来实现这些容器呢?

二叉搜索树

​ 二叉搜索树(也叫二叉排序树、二叉查找树)。二叉搜索树的定义较为简单。二叉搜索树就是根节点元素与左右子树所有元素的比较关系顺序。具体如大小关系,二叉搜索树就是根节点元素大于左子树的所有元素,小于右子树的所有元素,并且左右子树均为二叉搜索树。

平衡二叉搜索树

​ 二叉搜索树在一些性能上仍然不是很理想,它的查找等一些操作最糟糕情况的时间复杂度仍然有 O ( n ) O(n) O(n),为了降低这些操作的最糟糕时间复杂度,可以在构造二叉搜索树多花点功夫。平衡二叉搜索树,就能解决这个问题。

​ 平衡二叉搜索树是什么呢?平衡二叉搜索树规定,根节点的左右子树高度相差在1以内,也就是说左子树高度-右子树高度 ∈ { − 1 , 0 , 1 } \in \{-1,0,1\} {1,0,1}。插入、删除、查找都为O( l o g 2 n log_2 n log2n) ,而最坏情况为O( n n n)

红黑树

​ 红黑树是一种弱平衡二叉搜索树,他每个节点有额外的一个数据,也就是该节点的颜色(红色或黑色)。他需要满足以下五个性质:

  1. 每个节点是红色或黑色。
  2. 根是黑色的。有时会忽略此规则。由于根始终可以从红色更改为黑色,但反之亦然,因此该规则对分析的影响很小。
  3. 所有叶子(这里的叶子节点是指所有通常说的叶子节点的子节点,是没有数据的节点)均为黑色。
  4. 如果节点为红色,则其两个子节点均为黑色。
  5. 从给定节点到其任何后代NIL节点的每条路径都包含相同数量的黑色节点。

注意,除了第五个约束之外,没有任何限制施加到黑色节点的子节点上。特别地,黑色节点(如叶节点)可以是黑色节点的子节点。例子:

在这里插入图片描述

红黑树与AVL树的比较:

​ 在平均时间复杂度上,无论是红黑树都是AVL树,插入、删除、查找都为O( l o g 2 n log_2 n log2n) ,而最坏情况也为O( l o g 2 n log_2 n log2n) 。AVL树在顺序插入和删除时有20%左右的性能优势,但随机性能反而落后15%左右,现实应用当然一般都是随机情况,所以红黑树得到了更广泛的应用。

​ 在插入、删除后的重新平衡方面:AVL是严格的平衡树,因此在增加或者删除节点的时候,根据不同情况,旋转的次数比红黑树要多;红黑树是用非严格的平衡来换取增删节点时候旋转次数的降低开销;所以简单说,如果你的应用中,搜索的次数远远大于插入和删除,那么选择AVL树,如果搜索,插入删除次数几乎差不多,应选择红黑树。即,有时仅为了排序(建立-遍历-删除),不查找或查找次数很少,R-B树合算一些。

​ 红黑树与AVL树的调整平衡的实现机制不同,AVL靠平衡因子和旋转,红黑树靠节点颜色以及一些约定再加上旋转。因此,存在去掉颜色的红黑树后它不是AVL树,比如左子树都是黑的,右子树都是红黑相间的,这样整个树高度2n的时候,根节点的左右层数差可以到n。

​ 红黑树能够以O( l o g 2 n log_2 n log2n) 的时间复杂度进行搜索、插入、删除操作。此外,由于它的设计,任何不平衡都会在三次旋转之内解决。当然,还有一些更好的,实现起来更复杂的数据结构 能够做到一步旋转之内达到平衡,但红黑树能够给我们一个比较“便宜”的解决方案。红黑树的算法时间复杂度和AVL相同,但统计性能比AVL树更高。当然,红黑树并不适应所有应用树的领域。如果数据基本上是静态的,那么让他们待在他们能够插入,并且不影响平衡的地方会具有更好的性能。如果数据完全是静态的,例如,做一个哈希表,性能可能会更好一些红黑树是牺牲了严格的高度平衡的优越条件为 代价红黑树能够以O( l o g 2 n log_2 n log2n) 的时间复杂度进行搜索、插入、删除操作。此外,由于它的设计,任何不平衡都会在三次旋转之内解决。

​ 总而言之,在插入或删除后的重新“平衡”上,红黑树效率优于AVL树。

Reference

[1]https://en.wikipedia.org/wiki/AVL_tree

[2]https://en.wikipedia.org/wiki/Red%E2%80%93black_tree](https://en.wikipedia.org/wiki/Red–black_tree

[3]https://www.cnblogs.com/rednodel/p/9259134.html

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值