赤黒木
赤黒木は二分探索木であり、各ノードにストレージビットを追加して、ノードの色(赤または黒)を示します。ツリーの各ノードには、color、key、left、right、pの5つの属性が含まれています。ノードに子または親がない場合、ノードの対応するポインタ属性の値はNILであり、赤黒木は次の赤と黒のバイナリ検索ツリーの性質:
- 各ノードは赤または黒のいずれかです
- ルートノードは黒です
- 各リーフノード(NIL)は黒です
- ノードが赤の場合、その2つの子ノードは黒です。
- 各ノードについて、そのノードからそのすべての子孫リーフノードへの単純なパスには、同じ数の黒いノードが含まれます。
次の図(a)は赤黒木を示し、図(b)では、NILを1つずつ使用する代わりに、黒の歩哨T.nilに置き換えられ、黒の高さも省略されています。親ノードルートノードのもこの歩哨です。
ノードxxからx(このノードを除く)からリーフノードまでの単純なパス上の黒いノードの数は、ノードの黒い高さと呼ばれ、bh(x)bh(x)で表されます。b h (x )。赤黒木の性質から、1本の木にはnnがありますn個の内部ノードを持つ赤黒木の高さは最大で2lg(n + 1)2lg(n + 1)2 l g (n+1 )
スピン
検索ツリー操作の挿入と削除にはnnが含まれますn個のキーワードを持つ赤黒木では、実行時間はO(lgn)O(lgn)です。O (l g n )。これらの2つの操作はツリーを変更するため、赤黒の性質に違反する可能性があります。これらのプロパティを維持するには、ツリー内の一部のノードの色とポインター構造を変更する必要があります。ポインター構造の変更は、二分探索木の性質を維持できる探索木のローカル操作である回転(比率)によって行われます。下の図に示すように、左手と右手の2種類の回転が与えられます。xxへの左手X到YYyのチェーンは「ピボット」として実行され、yyが作成されます。yはサブツリーxxの新しいルートノードになりますxはyyになりますyの左の子、yyyの左の子はxxになりますxの右の子。
Pythonは次のようにローテーションを実装します。
#左旋转
def left_rotate(self, x):
# set y
y = x.rchild
# turn y left subtree into x right subtree
x.rchild = y.lchild
if y.lchild != self.nil:
y.lchild.parent = x
# link x parent to y
y.parent = x.parent
if x.parent == self.nil:
# x is root
self.root = y
elif x == x.parent.lchild:
x.parent.lchild = y
else:
x.parent.rchild = y
# put x on y left
y.lchild = x
x.parent = y
#右旋转
def right_rotate(self, y):
# set x
x = y.lchild
# turn x right subtree into y left subtree
y.lchild = x.rchild
if x.rchild != self.nil:
x.rchild.parent = y
# link y parent to x
x.parent = y.parent
if y.parent == self.nil:
# x is root
self.root = x
elif y == y.parent.lchild:
y.parent.lchild = x
else:
y.parent.rchild = x
# put y on x right
x.rchild = y
y.parent = x