简体   繁体   English

将 AVL 树转换为红黑树

[英]Convert AVL Trees to Red Black tree

I read this statement somewhere that the nodes of any AVL tree T can be colored “red” and “black” so that T becomes a red-black tree.我在某处读到过这个声明,任何 AVL 树 T 的节点都可以被着色为“红色”和“黑色”,这样 T 就变成了红黑树。

This statement seems quite convincing but I didn't understand how to formally proof this statement.这个陈述看起来很有说服力,但我不明白如何正式证明这个陈述。

According to wiki, A red black tree should satisfy these five properties:根据wiki,一棵红黑树应该满足这五个属性:

aA node is either red or black. a节点是红色或黑色。

b.The root is black. b.根是黑色的。 This rule is sometimes omitted.有时会省略此规则。 Since the root can always be changed from red to black, but not necessarily vice versa,由于根总是可以从红色变为黑色,但不一定反之亦然,

c. C。 All leaves (NIL) are black.所有叶子 (NIL) 都是黑色的。

d.If a node is red, then both its children are black. d.如果一个节点是红色的,那么它的两个孩子都是黑色的。

e.Every path from a given node to any of its descendant NIL nodes contains,the same number of black nodes. e.从给定节点到其任何后代 NIL 节点的每条路径都包含相同数量的黑色节点。

The four conditions is quite simple, I got stuck how to proof statement 5四个条件很简单,我被卡住了如何证明陈述5

First, define the height of a tree (as used for AVL trees): 首先,定义树的高度 (用于AVL树):

height(leaf) = 1
height(node) = 1 + max(height(node.left), height(node.right))

Also, define the depth of a path (as used for red-black trees, a path is the chain of descendants from a given node to some leaf) to be the number of black nodes on the path. 另外,将路径的深度 (如用于红黑树的路径定义为从给定节点到某个叶子的后代链)为路径上黑色节点的数量。


As you point out, the tricky bit about coloring an AVL tree as a red-black tree is making sure that every path has the same depth. 如您所指出的,将AVL树着色为红黑树的棘手问题是要确保每个路径的深度相同。 You will need to use the AVL invariant: that the subtrees of any given node can differ in height by at most one. 您将需要使用AVL不变式:任何给定节点的子树的高度最多可以相差一。

Intuitively, the trick is to use a coloring algorithm whose depth is predictable for a given height, such that you don't need to do any further global coordination. 直观地,诀窍是使用一种着色算法,该算法的深度对于给定的高度是可以预测的,这样您就无需进行任何进一步的全局协调。 Then, you can tweak the coloring locally, to ensure the children of each node have the same depth; 然后,您可以在本地调整颜色,以确保每个节点的子级具有相同的深度; this is possible only because the AVL condition puts strict limits on their height difference. 这仅是因为AVL条件对其高度差设置了严格的限制。


This tree-coloring algorithm does the trick: 这种树着色算法可以达到以下目的:

color_black(x):
  x.color = black;
  if x is a node:
    color_children(x.left, x.right)

color_red(x):  // height(x) must be even
  x.color = red
  color_children(x.left, x.right)  // x will always be a node

color_children(a,b):
  if height(a) < height(b) or height(a) is odd:
    color_black(a)
  else:
    color_red(a)
  if height(b) < height(a) or height(b) is odd:
    color_black(b)
  else:
    color_red(b)

For the root of the AVL tree, call color_black(root) to ensure b. 对于AVL树的根,调用color_black(root)以确保b。 Note that the tree is traversed in depth-first order, also ensuring a. 注意,树以深度优先顺序遍历,也确保a。

Note that red nodes all have even height. 请注意,红色节点的高度均相等。 Leaves have height 1, so they will be colored black, ensuring c. 叶子的高度为1,因此将其染成黑色,从而确保c。 Children of red nodes will either have odd height or will be shorter than their sibling, and will be marked black, ensuring d. 红色节点的子节点的高度或为奇数,或短于其兄弟节点,并标记为黑色,确保d。

Finally, to show e. 最后,展示e。 (that all paths from root have the same depth), use induction on n>=1 to prove: (从根开始的所有路径都具有相同的深度),对n>=1使用归纳法来证明:

  • for odd height = 2*n-1 , 对于奇数height = 2*n-1
    • color_black() creates a red-black tree, with depth n color_black()创建深度为n的红黑树
  • for even height = 2*n , 对于均匀height = 2*n
    • color_red() sets all paths to depth n color_red()将所有路径设置为深度n
    • color_black() creates a red-black tree with depth n+1 color_black()创建深度为n+1红黑树

Base case, for n = 1 : 基本情况,对于n = 1

  • for odd height = 1 , the tree is a leaf; 对于奇数height = 1 ,树是叶子;
    • color_black() sets the leaf to black; color_black()将叶子设置为黑色; the sole path has depth 1, 唯一路径的深度为1,
  • for even height = 2 , the root is a node, and both children are leaves, marked black as above; 对于偶数height = 2 ,根是一个节点,两个子代都是叶子,如上标记为黑色;
    • color_red() sets node to red; color_red()将节点设置为红色; both paths have depth 1 两条路径的深度均为1
    • color_black() sets node to black; color_black()将节点设置为黑色; both paths have depth 2 两条路径的深度均为2

The induction step is where we use the AVL invariant: sibling trees can differ in height by at most 1. For a node with a given height : 归纳步骤是我们使用AVL不变式的地方:同级树的高度最多可以相差1。对于具有给定height的节点:

  • subcase A: both subtrees are (height-1) 子情况A:两个子树都是(height-1)
  • subcase B: one subtree is (height-1) , and the other is (height-2) 子情况B:一个子树是(height-1) ,另一个子树是(height-2)

Induction step: given the hypothesis is true for n , show that it holds for n+1 : 归纳步骤:假设n ,则证明它适用于n+1

for odd height = 2*(n+1)-1 = 2*n+1 , 对于奇数height = 2*(n+1)-1 = 2*n+1

  • subcase A: both subtrees have even height 2*n 子情况A:两个子树的高度均为偶数2*n
    • color_children() calls color_red() for both children, color_children()为两个孩子都调用color_red(),
    • via induction hypothesis, both children have depth n 通过归纳假设,两个孩子都有深度n
    • for parent, color_black() adds a black node, for depth n+1 对于父级,color_black()添加一个黑色节点,深度为n+1
  • subcase B: subtrees have heights 2*n and 2*n-1 子情况B:子树的高度为2*n2*n-1
    • color_children() calls color_red() and color_black(), resp; color_children()分别调用color_red()和color_black();
    • for even height 2*n , color_red() yields depth n (induction hyp.) 对于偶数高度2*n ,color_red()产生深度n (归纳hyp。)
    • for odd height 2*n-1 , color_black() yields depth n (induction hyp.) 对于奇数高度2*n-1 ,color_black()产生深度n (归纳hyp)。
    • for parent, color_black() adds a black node, for depth n+1 对于父级,color_black()添加一个黑色节点,深度为n+1

for even height = 2*(n+1) = 2*n + 2 对于均匀height = 2*(n+1) = 2*n + 2

  • subcase A: both subtrees have odd height 2*n+1 = 2*(n+1)-1 子情况A:两个子树的奇数高度均为2*n+1 = 2*(n+1)-1
    • color_children() calls color_black() for both children, for depth n+1 color_children()为两个孩子都调用color_black(),深度为n+1
    • from odd height case above, both children have depth n+1 从上面的奇数高度情况来看,两个孩子的深度均为n+1
    • for parent, color_red() adds a red node, for unchanged depth n+1 对于父级,color_red()添加一个红色节点,深度n+1不变
    • for parent, color_black() adds a black node, for depth n+2 对于父级,color_black()添加一个黑色节点,深度为n+2
  • subcase B: subtrees have heights 2*n+1 = 2*(n+1)-1 and 2*n 子情况B:子树的高度为2*n+1 = 2*(n+1)-12*n
    • color_children() calls color_black() for both children, for depth n+1 color_children()为两个孩子都调用color_black(),深度为n+1
    • for odd height 2*n+1 , color_black() yields depth n+1 (see above) 对于奇数高度2*n+1 ,color_black()产生深度n+1 (请参见上文)
    • for even height 2*n , color_black() yields depth n+1 (induction hyp.) 对于偶数高度2*n ,color_black()产生深度n+1 (归纳hyp。)
    • for parent, color_red() adds a red node, for depth n+1 对于父级,color_red()为深度n+1添加一个红色节点
    • for parent, color_black() adds a black node, for depth n+2 = (n+1)+1 对于父级,color_black()添加一个黑色节点,深度为n+2 = (n+1)+1

Well, simple case for #5 is a single descendant, which is a leaf, which is black by #3. 好吧,#5的简单情况是单个后代,它是一片叶子,在#3之前是黑色的。

Otherwise, the descendant node is red, which is required to have 2 black descendants by #4. 否则,后代节点为红色,由#4要求具有2个黑色后代。

Then these two cases recursively apply at each node, so you'll always have the same amount of black nodes in each path. 然后,这两种情况将递归地应用于每个节点,因此您在每个路径中始终会有相同数量的黑色节点。

It is (almost always) completely impossible to convert an AVL tree to a Red-Black tree;将 AVL 树转换为红黑树是(几乎总是)完全不可能的; Of course, both are trees and the shape can be (sometimes) the same, but the cost is too large and you may need extra height restriction/conversion.当然,两者都是树,形状可以(有时)相同,但成本太大,您可能需要额外的高度限制/转换。

A red-black tree has an explicit black tree height, which is a global height information all the tree-tops share.红黑树有一个明确的黑树高度,它是所有树顶共享的全局高度信息。

An AVL tree has no global height information at all. AVL 树根本没有全局高度信息。 The difference is represented by a very simple example;差异由一个非常简单的示例表示; an almost perfect tree with one hole(one empty node).一棵几乎完美的树,有一个洞(一个空节点)。 The red-black tree can absorb a single error node near the tree-top;红黑树可以吸收树顶附近的单个错误节点; the AVL tree can't. AVL 树不能。

The balance 0 means that the Nth 2-adic decision is lost.余额 0 表示第 N 个 2-adic 决策丢失。 The more the tree gets balanced, the harder it gets to find the height information.树越平衡,就越难找到高度信息。

The ability to rebalance the whole tree is equivalent to the claim that you can find that single hole in a speed that is logically impossible.重新平衡整棵树的能力相当于声称您可以以逻辑上不可能的速度找到单个洞。 The red-black tree spends extra swapping cost to maintain the quasi-perfect black tree height, which is a global quasi-perfect balance;红黑树花费额外的交换成本来维持准完美黑树的高度,这是一个全局的准完美平衡; An AVL tree has no such global restrictions. AVL 树没有这样的全局限制。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM