介绍:
红黑树是一种自平衡二进制搜索树,其中的每个节点都有一个额外的位,该位通常被解释为颜色(红色或黑色)。这些颜色用于确保树在插入和删除过程中保持平衡。尽管树的平衡不是完美的,但足以减少搜索时间并将其维持在O(log n)时间左右,其中n是树中元素的总数。这棵树是鲁道夫·拜耳(Rudolf Bayer)于1972年发明的。
必须注意的是,由于每个节点仅需要1位空间来存储颜色信息,因此这些类型的树显示出与经典(无色)二进制搜索树相同的内存占用量。
每棵红黑树遵循的规则:
- 每个节点都有红色或黑色。
- 树的根始终是黑色的。
- 没有两个相邻的红色节点(红色节点不能有红色父节点或红色子节点)。
- 从节点(包括根)到其任何后代NULL节点的每条路径都具有相同数量的黑色节点。
为什么是红黑树?
大多数BST操作(例如,搜索,最大,最小,插入,删除等)花费O(h)时间,其中h是BST的高度。对于偏斜的二叉树,这些操作的成本可能变为O(n)。如果确保每次插入和删除后树的高度都保持O(log n),则可以保证所有这些操作的O(log n)上限。红黑树的高度始终为O(log n),其中n是树中的节点数。
Sr. No. | Algorithm | Time Complexity |
---|---|---|
1. | Search | O(log n) |
2. | Insert | O(log n) |
3. | Delete | O(log n) |
“ n”是红黑树中元素的总数。
与AVL树的比较:
与红黑树相比,AVL树更加平衡,但是它们可能会在插入和删除过程中引起更多旋转。因此,如果您的应用程序涉及频繁的插入和删除操作,则应优先选择Red-Black树。而且,如果插入和删除操作的频率较低,而搜索操作的频率较高,则应优先使用AVL树而不是红黑树。
红黑树如何确保平衡?
一个简单的理解平衡的示例是,在红黑树中不可能有3个节点的链。我们可以尝试颜色的任意组合,并查看它们全部违反了Red-Black树的属性。
A chain of 3 nodes is not possible in Red-Black Trees.
Following are NOT Red-Black Trees
30 30 30
/ \ / \ / \
20 NIL 20 NIL 20 NIL
/ \ / \ / \
10 NIL 10 NIL 10 NIL
Violates Violates Violates
Property 4. Property 4 Property 3
Following are different possible Red-Black Trees with above 3 keys
20 20
/ \ / \
10 30 10 30
/ \ / \ / \ / \
NIL NIL NIL NIL NIL NIL NIL NIL
关于红黑树的有趣之处:
- 红黑树的黑色高度是指从根节点到叶节点的路径上的黑色节点数。叶节点也被视为黑色节点。因此,高度为h的红黑树的黑色高度> = h / 2。
- 具有n个节点的红黑树的高度为h <= 2 log 2 (n + 1)。
- 所有叶子(NIL)均为黑色。
- 节点的黑色深度定义为从根到该节点的黑色节点的数量,即黑色祖先的数量。
- 每棵红黑树都是二叉树的特例。
一棵红黑树的黑高:
黑色高度是指从根到叶的路径上黑色节点的数量。叶节点也算为黑色节点。从上面的属性3和4中,我们可以得出高度为h的红黑树的black-height> = h / 2 。
Number of nodes from a node to its farthest descendant leaf is no more than twice as the number of nodes to the nearest descendant leaf.
每个具有n个节点的红黑树的高度<= 2Log 2 (n + 1)
可以使用以下事实证明这一点:
- 对于一般的二叉树,令k为所有根到NULL路径上的最小节点数,则n> = 2 k – 1(例如,如果k为3,则n至少为7)。该表达式也可以写成k <= Log 2 (n + 1)。
- 从红黑树的属性4以及以上声明,我们可以说在一个具有n个节点的红黑树中,存在一个根到叶路径的根,该路径最多具有Log 2 (n + 1)个黑节点。
- 从红黑树的属性3中,我们可以说红黑树中的黑节点数至少为⌊n / 2⌋,其中n是节点总数。
从以上几点,我们可以得出结论,具有n个节点的Red Black Tree的高度<= 2Log 2 (n + 1)
红黑树中的搜索操作:
由于每个红黑树都是二叉树的特例,因此红黑树的搜索算法与二叉树的搜索算法相似。
算法:
searchElement (tree, val)
Step 1:
If tree -> data = val OR tree = NULL
Return tree
Else
If val data
Return searchElement (tree -> left, val)
Else
Return searchElement (tree -> right, val)
[ End of if ]
[ End of if ]
Step 2: END
对于该程序,您可以将其引用为AVL tree 。
示例:在下面的红黑树中搜索11。
解决方案:
- 从根开始。
- 将插入元素与根进行比较,如果小于根,则向左递归,向右递归。
- 如果在任何位置都可以找到要搜索的元素,则返回true,否则返回false。
在这篇文章中,我们介绍了红黑树,并讨论了如何确保平衡。困难的部分是添加和删除键时要保持平衡。我们还看到了如何从红黑树中搜索元素。我们将很快在Red-Black树上即将发布的帖子中讨论插入和删除操作。
锻炼:
1)是否有可能将所有黑色节点都放在一棵红黑树中?
2)画一棵不是AVL树结构的红黑树吗?
插入和删除
红黑树插入
红黑树删除
应用范围:
- 大多数自平衡BST库功能(例如,在C++中使用map和set( JavaOR TreeSet和TreeMap))都使用Red-Black Tree。
- 它用于实现Linux的CPU调度。完全Fair Scheduler会使用它。
- 此外,它们还用于K均值聚类算法中,以减少时间复杂度。
- 此外,MySQL还使用Red-Black树作为表上的索引。
参考:
- 算法入门第三版,作者:Clifford Stein,Thomas H. Cormen,Charles E. Leiserson,Ronald L. Rivest
- http://en.wikipedia.org/wiki/Red%E2%80%93black_tree
- Tim Roughgarden在红黑树上的视频讲座
- 麻省理工学院关于红黑树的视频讲座
- 麻省理工学院关于红黑树的讲义