Algorithm 将AVL树转换为红黑树
我在某个地方读到这句话,任何AVL树T的节点都可以被涂成“红色”和“黑色”,这样T就变成了红黑树 这句话似乎很有说服力,但我不明白如何正式证明这句话 根据wiki,红黑树应满足以下五个属性: a、 节点为红色或黑色 b、 根是黑色的。这条规则有时被省略。因为根总是可以从红色变为黑色,但不一定相反 c。所有的叶子(无)都是黑色的 d、 如果节点为红色,则其两个子节点均为黑色 e、 从给定节点到其任何子代NIL节点的每条路径都包含相同数量的黑色节点 这四个条件很简单,我被困在了如何证明语句5的问题上。好吧,5的简单例子是一个单一的后代,它是一片叶子,由3变黑 否则,子体节点为红色,需要有2个黑色的子体乘以#4 然后这两种情况递归地应用于每个节点,因此在每个路径中始终有相同数量的黑色节点 首先,定义树的高度(用于AVL树): 另外,将路径的深度(如用于红黑树,路径是从给定节点到某个叶的子体链)定义为路径上的黑色节点数Algorithm 将AVL树转换为红黑树,algorithm,data-structures,tree,avl-tree,red-black-tree,Algorithm,Data Structures,Tree,Avl Tree,Red Black Tree,我在某个地方读到这句话,任何AVL树T的节点都可以被涂成“红色”和“黑色”,这样T就变成了红黑树 这句话似乎很有说服力,但我不明白如何正式证明这句话 根据wiki,红黑树应满足以下五个属性: a、 节点为红色或黑色 b、 根是黑色的。这条规则有时被省略。因为根总是可以从红色变为黑色,但不一定相反 c。所有的叶子(无)都是黑色的 d、 如果节点为红色,则其两个子节点均为黑色 e、 从给定节点到其任何子代NIL节点的每条路径都包含相同数量的黑色节点 这四个条件很简单,我被困在了如何证明语句5的问题上
正如您所指出的,将AVL树着色为红黑树的技巧在于确保每条路径具有相同的深度。您需要使用AVL不变量:任何给定节点的子树在高度上最多可以相差一个 直观地说,诀窍是使用一种着色算法,其深度在给定高度下是可预测的,这样您就不需要进行任何进一步的全局协调。然后,可以局部调整颜色,以确保每个节点的子节点具有相同的深度;这是可能的,因为AVL条件严格限制了它们的高度差
此树着色算法实现以下功能:
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)
黑色(x):
x、 颜色=黑色;
如果x是一个节点:
彩色儿童(x左,x右)
红色(x)://高度(x)必须均匀
x、 颜色=红色
color\u子节点(x.left,x.right)//x将始终是一个节点
儿童(a、b)的颜色:
如果高度(a)<高度(b)或高度(a)为奇数:
黑色(a)
其他:
红色(a)
如果高度(b)<高度(a)或高度(b)为奇数:
黑色(b)
其他:
红色(b)
对于AVL树的根,请调用color\u black(root)
以确保b。
请注意,树是按深度优先顺序遍历的,这也确保了
请注意,红色节点的高度都相等。叶子的高度为1,因此它们将被染成黑色,以确保c。红色节点的子节点将具有奇数高度或比其兄弟节点短,并将标记为黑色,以确保d
最后,展示e。(从根开始的所有路径具有相同的深度),
使用n>=1的归纳法证明:
- 对于奇数
高度=2*n-1
,
- color_black()创建一棵红黑树,深度
n
- 对于偶数
高度=2*n
,
- color_red()将所有路径设置为深度
n
- color_black()创建一棵红黑树,深度
n+1
基本情况,对于n=1
:
- 对于奇数
高度=1
,树是一片叶子;
- color_black()将叶子设置为黑色;唯一路径的深度为1
- 对于偶数
height=2
,根是一个节点,两个子节点都是叶子,上面标记为黑色;
- color_red()将节点设置为红色;两条路径的深度均为1
- color_black()将节点设置为黑色;两条路径都有深度2
归纳步骤是我们使用AVL不变量的地方:兄弟树的高度最多可以相差1。对于具有给定高度的节点
:
- 子类A:两个子树都是
(高度-1)
- 子类B:一个子树是
,另一个子树是(高度-1)
(高度-2)
n
的假设为真,则表明它适用于n+1
:
对于奇数高度=2*(n+1)-1=2*n+1
- 子类A:两个子树的高度均为偶数
2*n
- color\u children()为两个子项调用color\u red()
- 通过归纳假设,两个孩子都有深度
n
- 对于父级,color_black()添加一个黑色节点,用于深度
n+1
- 子类B:子树具有高度
和2*n
2*n-1
- color_children()分别调用color_red()和color_black()李>
- 对于均匀高度
,颜色_red()产生深度2*n
(感应高度)n
- 对于奇数高度
,黑色()产生深度2*n-1
(感应高度)n
- 对于父级,color_black()添加一个黑色节点,用于深度
n+1
height=2*(n+1)=2*n+2
- 子类A:两个子树的奇数高度
2*n+1=2*(n+1)-1
- color_children()为两个子项调用color_black(),表示深度
n+1
- 从上面的奇数高度案例来看,两个孩子都有深度
n+1
- 对于父级,color_red()添加了一个红色节点,用于未更改的深度
n+1
- 对于父级,color_black()添加一个黑色节点,用于深度
n+2
- color_children()为两个子项调用color_black(),表示深度
- 子类B:子树的高度
和2*n+1=2*(n+1)-1
2*n
- color_children()为两个子项调用color_black(),表示深度
n+1
- 对于奇数高度
,黑色()产生深度2*n+1
(见上文)n+1
- 对于均匀高度
,黑色()产生深度2*n
(感应高度)n+1
- 帕伦
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)
- color_children()为两个子项调用color_black(),表示深度