红黑树的特性:
(1)每个节点或者是黑色,或者是红色。
(2)根节点是黑色。
(3)每个叶子节点(NIL)是黑色。 [注意:这里叶子节点,是指为空(NIL或NULL)的叶子节点!]
(4)如果一个节点是红色的,则它的子节点必须是黑色的。
(5)从一个节点到该节点的子孙节点的所有路径上包含相同数目的黑节点。
from random import randint
RED = 'red'
BLACK = 'black'
class RBT:
def __init__(self):
# self.items = []
self.root = None
self.zlist = []
def LEFT_ROTATE(self, x):
# x是一个RBTnode
y = x.right
if y is None:
# 右节点为空,不旋转
return
else:
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):
# y是一个节点
x = y.left
if x is None:
# 右节点为空,不旋转
return
else:
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
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
self.INSERT_FIXUP(z)
return
if z.val < y.val:
y.left = z
else:
y.right = z
if y.color == RED:
# z的父节点y为红色,需要fixup。
# 如果z的父节点y为黑色,则不用调整
self.INSERT_FIXUP(z)
else:
return
def INSERT_FIXUP(self, z):
# case 1:z为root节点
if z.parent is None:
z.PAINT(BLACK)
self.root = z
return
# case 2:z的父节点为黑色
if z.parent.color == BLACK:
# 包括了z处于第二层的情况
# 这里感觉不必要啊。。似乎z.parent为黑色则不会进入fixup阶段
return
# 下面的几种情况,都是z.parent.color == RED:
# 节点y为z的uncle
p = z.parent
g = p.parent # g为x的grandpa
if g is None:
return
# return 这里不能return的。。。
if g.right == p:
y = g.left
else:
y = g.right
# case 3-0:z没有叔叔。即:y为NIL节点
# 注意,此时z的父节点一定是RED
if y == None:
if z == p.right and p == p.parent.left:
# 3-0-0:z为右儿子,且p为左儿子,则把p左旋
# 转化为3-0-1或3-0-2的情况
self.LEFT_ROTATE(p)
p, z = z, p
g = p.parent
elif z == p.left and p == p.parent.right:
self.RIGHT_ROTATE(p)
p, z = z, p
g.PAINT(RED)
p.PAINT(BLACK)
if p == g.left:
# 3-0-1:p为g的左儿子
self.RIGHT_ROTATE(g)
else:
# 3-0-2:p为g的右儿子
self.LEFT_ROTATE(g)
return
# case 3-1:z有黑叔
elif y.color == BLACK:
if p.right == z and p.parent.left == p:
# 3-1-0:z为右儿子,且p为左儿子,则左旋p
# 转化为3-1-1或3-1-2
self.LEFT_ROTATE(p)
p, z = z, p
elif p.left == z and p.parent.right == p:
self.RIGHT_ROTATE(p)
p, z = z, p
p = z.parent
g = p.parent
p.PAINT(BLACK)
g.PAINT(RED)
if p == g.left:
# 3-1-1:p为g的左儿子,则右旋g
self.RIGHT_ROTATE(g)
else:
# 3-1-2:p为g的右儿子,则左旋g
self.LEFT_ROTATE(g)
return
# case 3-2:z有红叔
# 则涂黑父和叔,涂红爷,g作为新的z,递归调用
else:
y.PAINT(BLACK)
p.PAINT(BLACK)
g.PAINT(RED)
new_z = g
self.INSERT_FIXUP(new_z)
def DELETE(self, val):
curNode = self.root
while curNode is not None:
if val < curNode.val:
curNode = curNode.left
elif val > curNode.val:
curNode = curNode.right
else:
# 找到了值为val的元素,正式开始删除
if curNode.left is None and curNode.right is None:
# case1:curNode为叶子节点:直接删除即可
if curNode == self.root:
self.root = None
else:
p = curNode.parent
if curNode == p.left:
p.left = None
else:
p.right = None
elif curNode.left is not None and curNode.right is not None:
sucNode = self.SUCCESOR(curNode)
curNode.val, sucNode.val = sucNode.val, curNode.val
self.DELETE(sucNode.val)
else:
p = curNode.parent
if curNode.left is None:
x = curNode.right
else:
x = curNode.left
if curNode == p.left:
p.left = x
else:
p.right = x
x.parent = p
if curNode.color == BLACK:
self.DELETE_FIXUP(x)
curNode = None
return False
def DELETE_FIXUP(self, x):
p = x.parent
# w:x的兄弟结点
if x == p.left:
w = x.right
else:
w = x.left
# case1:x的兄弟w是红色的
if w.color == RED:
p.PAINT(RED)
w.PAINT(BLACK)
if w == p.right:
self.LEFT_ROTATE(p)
else:
self.RIGHT_ROTATE(p)
if w.color == BLACK:
# case2:x的兄弟w是黑色的,而且w的两个孩子都是黑色的
if w.left.color == BLACK and w.right.color == BLACK:
w.PAINT(RED)
if p.color == BLACK:
return
else:
p.color = BLACK
self.DELETE_FIXUP(p)
# case3:x的兄弟w是黑色的,而且w的左儿子是红色的,右儿子是黑色的
if w.left.color == RED and w.color == BLACK:
w.left.PAINT(BLACK)
w.PAINT(RED)
self.RIGHT_ROTATE(w)
# case4:x的兄弟w是黑色的,而且w的右儿子是红
if w.right.color == RED:
p.PAINT(BLACK)
w.PAINT(RED)
if w == p.right:
self.LEFT_ROTATE(p)
else:
self.RIGHT_ROTATE(p)
def SHOW(self):
self.DISPLAY1(self.root)
return self.zlist
def DISPLAY1(self, node):
if node is None:
return
self.DISPLAY1(node.left)
self.zlist.append(node.val)
self.DISPLAY1(node.right)
def DISPLAY2(self, node):
if node is None:
return
self.DISPLAY2(node.left)
print node.val,
self.DISPLAY2(node.right)
def DISPLAY3(self, node):
if node is None:
return
self.DISPLAY3(node.left)
self.DISPLAY3(node.right)
print node.val,
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
def zuoxuan(b, c):
a = b.parent
a.left = c
c.parent = a
b.parent = c
c.left = b
if __name__ == '__main__':
rbt=RBT()
b = []
for i in range(100):
m = randint(0, 500)
rbt.INSERT(m)
b.append(m)
a = rbt.SHOW()
b.sort()
equal = True
for i in range(100):
if a[i] != b[i]:
equal = False
break
if not equal:
print 'wrong'
else:
print 'OK!'
TArr = [80,60,120,40,70,140,20,50]
for i in range(len(TArr)):
m = TArr[i]
rbt.INSERT(m)
b.append(m)
当插入到40这个值得时候,发现,root是黑色,root的左右两个儿子节点也是黑色,
class RBTree:
def __init__(self):
self.nil = RBTreeNode(0)
self.root = self.nil
class RBTreeNode:
def __init__(self, x):
self.key = x
self.left = None
self.right = None
self.parent = None
self.color = 'black'
class Solution:
def InorderTreeWalk(self, x):
if x != None:
self.InorderTreeWalk(x.left)
if x.key != 0:
print 'key:', x.key, 'parent:', x.parent.key, 'color:', x.color
self.InorderTreeWalk(x.right)
def LeftRotate(self, T, x):
y = x.right
x.right = y.left
if y.left != T.nil:
y.left.parent = x
y.parent = x.parent
if x.parent == T.nil:
T.root = y
elif x == x.parent.left:
x.parent.left = y
else:
x.parent.right = y
y.left = x
x.parent = y
def RightRotate(self, T, x):
y = x.left
x.left = y.right
if y.right != T.nil:
y.right.parent = x
y.parent = x.parent
if x.parent == T.nil:
T.root = y
elif x == x.parent.right:
x.parent.right = y
else:
x.parent.left = y
y.right = x
x.parent = y
def RBInsert(self, T, z):
# init z
z.left = T.nil
z.right = T.nil
z.parent = T.nil
y = T.nil
x = T.root
while x != T.nil:
y = x
if z.key < x.key:
x = x.left
else:
x = x.right
z.parent = y
if y == T.nil:
T.root = z
elif z.key < y.key:
y.left = z
else:
y.right = z
z.left = T.nil
z.right = T.nil
z.color = 'red'
self.RBInsertFixup(T,z)
def RBInsertFixup(self, T, z):
while z.parent.color == 'red':
if z.parent == z.parent.parent.left:
y = z.parent.parent.right
if y.color == 'red':
z.parent.color = 'black'
y.color = 'black'
z.parent.parent.color = 'red'
z = z.parent.parent
else:
if z == z.parent.right:
z = z.parent
self.LeftRotate(T, z)
z.parent.color = 'black'
z.parent.parent.color = 'red'
self.RightRotate(T,z.parent.parent)
else:
y = z.parent.parent.left
if y.color == 'red':
z.parent.color = 'black'
y.color = 'black'
z.parent.parent.color = 'red'
z = z.parent.parent
else:
if z == z.parent.left:
z = z.parent
self.RightRotate(T, z)
z.parent.color = 'black'
z.parent.parent.color = 'red'
self.LeftRotate(T, z.parent.parent)
T.root.color = 'black'
def RBTransplant(self, T, u, v):
if u.parent == T.nil:
T.root = v
elif u == u.parent.left:
u.parent.left = v
else:
u.parent.right = v
v.parent = u.parent
def RBDelete(self, T, z):
y = z
y_original_color = y.color
if z.left == T.nil:
x = z.right
self.RBTransplant(T, z, z.right)
elif z.right == T.nil:
x = z.left
self.RBTransplant(T, z, z.left)
else:
y = self.TreeMinimum(z.right)
y_original_color = y.color
x = y.right
if y.parent == z:
x.parent = y
else:
self.RBTransplant(T, y, y.right)
y.right = z.right
y.right.parent = y
self.RBTransplant(T, z, y)
y.left = z.left
y.left.parent = y
y.color = z.color
if y_original_color == 'black':
self.RBDeleteFixup(T, x)
def RBDeleteFixup(self, T, x):
while x != T.root and x.color == 'black':
if x == x.parent.left:
w = x.parent.right
if w.color == 'red':
w.color = 'black'
x.parent.color = 'red'
self.LeftRotate(T, x.parent)
w = x.parent.right
if w.left.color == 'black' and w.right.color == 'black':
w.color = 'red'
x = x.parent
else:
if w.right.color == 'black':
w.left.color = 'black'
w.color = 'red'
self.RightRotate(T, w)
w = x.parent.right
w.color = x.parent.color
x.parent.color = 'black'
w.right.color = 'black'
self.LeftRotate(T, x.parent)
x = T.root
else:
w = x.parent.left
if w.color == 'red':
w.color = 'black'
x.parent.color = 'red'
self.RightRotate(T, x.parent)
w = x.parent.left
if w.right.color == 'black' and w.left.color == 'black':
w.color = 'red'
x = x.parent
else:
if w.left.color == 'black':
w.right.color = 'black'
w.color = 'red'
self.LeftRotate(T, w)
w = x.parent.left
w.color = x.parent.color
x.parent.color = 'black'
w.left.color = 'black'
self.RightRotate(T, x.parent)
x = T.root
x.color = 'black'
def TreeMinimum(self, x):
while x.left != T.nil:
x = x.left
return x
nodes = [11,2,14,1,7,15,5,8,4]
T = RBTree()
s = Solution()
for node in nodes:
s.RBInsert(T,RBTreeNode(node))
s.InorderTreeWalk(T.root)
s.RBDelete(T,T.root)
print 'after delete'
s.InorderTreeWalk(T.root)