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

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

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

二叉搜索树

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

平衡二叉搜索树

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

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

红黑树

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

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

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

在这里插入图片描述

红黑树与AVL树的比较:

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

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

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

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

​ 总而言之,在插入或删除后的重新“平衡”上,红黑树效率优于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

©️2020 CSDN 皮肤主题: 编程工作室 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值