class RBT:
def __init__(self):
self.root = None
def SUCCESOR(self, root):#右子树的最小结点(最左值),或者左子树的最大结点(最右值)
if root.right:
node = root.right
while node.left: node=node.left
else:
node = root.left
while node.right: node=node.right
return node
def DELETE(self, val):#参照https://iyukiyama.github.io/red-black-tree/
curNode = self.root
while curNode is not None:
if val < curNode.val:
curNode = curNode.left
elif val > curNode.val:
curNode = curNode.right
else:
if curNode.left is not None or curNode.right is not None:
sucNode = self.SUCCESOR(curNode)
curNode.val = sucNode.val
curNode = sucNode#后继或前续,不一定是叶子结点
val = curNode.val#用外层while找到叶子结点
else:
if curNode == self.root:
self.root = None
return
p = curNode.parent
if curNode == p.left:
w = p.right
curNode.parent.left = None
else:
w = p.left
curNode.parent.right = None
if curNode.color == BLACK:
self.DELETE_FIXUP(p,w)
curNode = None
def DELETE_FIXUP(self, p, w):
#1.w是红色:只需对x.p置红及w反色并旋转x.p后转为后续情形
if w and w.color == RED:
p.PAINT(RED)
w.PAINT(BLACK)
if w == p.right:
self.LEFT_ROTATE(p)
w = p.right
elif w == p.left:#镜像情况
self.RIGHT_ROTATE(p)
w = p.left
#2.w为黑色或空,且其孩子左黑右黑
if w == None or (w.left and w.left.color == BLACK and w.right and w.right.color == BLACK):
if w:w.PAINT(RED)
if p.parent:
p.PAINT(BLACK)
if p == p.left:
w = p.right
p = p.parent
else:
w = p.right
p = p.parent
self.DELETE_FIXUP(p,w)
#3.w为黑色,且其孩子左红右黑
if w and w.left and w.left.color == RED and (w.right == None or w.right and w.right.color == BLACK):
w.left.PAINT(BLACK)
w.PAINT(RED)
self.RIGHT_ROTATE(w)
w = p.right
#镜像情况
elif w and w.right and w.right.color == RED and (w.left == None or w.left and w.left.color == BLACK):
w.right.PAINT(BLACK)
w.PAINT(RED)
self.LEFT_ROTATE(w)
w = p.left
#4.w为黑色,且其孩子左黑右红或左红右红
if w and ((w.left and w.left.color == BLACK and w.right and w.right.color == RED )
or (w.left and w.left.color == RED and w.right and w.right.color == RED)):
p.PAINT(BLACK)
if w == p.right:
self.LEFT_ROTATE(p)
w.right.PAINT(BLACK)
elif w == p.left:
self.RIGHT_ROTATE(p)
w.left.PAINT(BLACK)
#镜像情况
elif w and ((w.right and w.right.color == BLACK and w.left and w.left.color == RED )
or (w.right and w.right.color == RED and w.left and w.left.color == RED)):
p.PAINT(BLACK)
if w == p.left:
self.RIGHT_ROTATE(p)
w.left.PAINT(BLACK)
elif w == p.right:
self.LEFT_ROTATE(p)
w.right.PAINT(BLACK)
def INSERT(self, val):
z = RBTnode(val)
y = None
x = self.root
while x is not None:#插入发生在叶子结点
y = x
if z.val < x.val:
x = x.left
else:
x = x.right
z.PAINT(RED)
z.parent = y
if y is None:# 插入z之前为空的RBT
self.root = z
z.PAINT(BLACK)
return
if z.val < y.val:
y.left = z
else:
y.right = z
if y.color == RED:# z的父结点y为红色,需要fixup。
self.INSERT_FIXUP(y,z)
def INSERT_FIXUP(self,p,x):
#1.插入2-结点 & 插入3-结点的黑父结点之下的情形;在黑结点下插入: 直接插入
if p.color == BLACK:
return
#2.插入4-结点;在红结点下插入,且该结点有红色兄弟结点 (插入结点的叔结点)
if p.parent:
g = p.parent
if g.right == p:# 结点w为x叔结点
w = g.left
else:
w = g.right
if w and w.color == RED:#调用回来后,w一定是BLACK的啊
w.PAINT(BLACK)
p.PAINT(BLACK)
g.PAINT(RED)
if g.parent:#回溯后,不能转到下面的情况调整。之前回调的回来后也要不能走下面的情况调整
p = g.parent
x = g
self.INSERT_FIXUP(p,x)
else:#到根了
g.PAINT(BLACK)
return
#3.插入3结点,「<」形;在红结点下插入,无红叔,插入结点为右子结点: 下段左旋>反色>上段右旋
elif w == None or w.color == BLACK:
if p == g.left:#插入结点的父结点为一左子结点
if x == p.right:
self.LEFT_ROTATE(p)
x.left.PAINT(RED)#x作根后3结点的三个key都要反色
x.PAINT(BLACK)
g.PAINT(RED)
self.RIGHT_ROTATE(g)
else:
#4.插入3结点,「/」形,插入结点为左子结点: 反色>上段右旋
p.PAINT(BLACK)
g.PAINT(RED)
self.RIGHT_ROTATE(g)
else:#插入结点的父结点为一右子结点
if x == p.left:#插入结点插入后为左子结点:下段右旋>反色>上段左旋
self.RIGHT_ROTATE(p)
x.right.PAINT(RED)#x作根后3结点的三个key都要反色
x.PAINT(BLACK)
g.PAINT(RED)
self.LEFT_ROTATE(g)
else:
#插入结点插入后为右子结点: 反色>上段左旋
p.PAINT(BLACK)
g.PAINT(RED)
self.LEFT_ROTATE(g)
def LEFT_ROTATE(self, x):
y = x.right
beta = y.left
x.right = beta
if beta is not None:
beta.parent = x
p = x.parent
y.parent = p
if p is None:
# x原来是root
self.root = y
elif x == p.left:
p.left = y
else:
p.right = y
y.left = x
x.parent = y
def RIGHT_ROTATE(self, y):
x = y.left
beta = x.right
y.left = beta
if beta is not None:
beta.parent = y
p = y.parent
x.parent = p
if p is None:
# y原来是root
self.root = x
elif y == p.left:
p.left = x
else:
p.right = x
x.right = y
y.parent = x
RED = 'red'
BLACK = 'black'
class RBTnode:
'''红黑树的结点类型'''
def __init__(self, val):
self.val = val
self.left = None
self.right = None
self.parent = None
def PAINT(self, color):
self.color = color
a = [27, 73, 10, 5, 18, 41, 99, 51, 25]
层序:(27, black) (10, red) (73, red) (5, black) (18, black) (41, black) (99, black) (25, red) (51, red)
删除18:(27, black) (10, red) (73, red) (5, black) (25, black) (41, black) (99, black) (51, red)
删除25:(27, black) (10, red) (73, red) (5, black) (41, black) (99, black) (51, red)
插入90: (27, black) (10, red) (73, red) (5, black) (41, black) (99, black) (51, red) (90, red)