您的位置:首页 > 理论基础 > 数据结构算法

第十四章 数据结构的扩张

2016-01-13 11:17 381 查看
14.1动态顺序统计

def 我们将中序遍历树时输出的位置称为秩。

def 每个节点增加size属性,具有如下性质的红黑树称为红黑树



有了这个属性可以在O(lgn)的时间里确定一个元素的秩(OS_RANK)和查找具有给定秩的元素(OS_SELECT)。通过循环不变式简单的验证他的正确性。为维护这个新增的性质需要对insert和delete操作做一些修改





class COLOR:
RED = "red"
BLACK = "black"

class TREENODE():
def __init__(self, key, color=COLOR.BLACK, parent = None):
self.key = key
self.parent = parent
self.left = None
self.right = None
self.color = color
self.size = 0

class TREE():
def __init__(self):
self.nil = TREENODE(None)
self.root = self.nil

def SET_SIZE(T, x):
if x != T.nil:
leftSize = 0
rightSize = 0
if x.right != T.nil:
rightSize = x.right.size

if x.left != T.nil:
leftSize = x.left.size

x.size = leftSize + rightSize

def OS_SELECT(x, i):
r = x.left.size + 1
if i == r:
return x
elif i < r:
return OS_SELECT(x.left, i)
else:
return OS_SELECT(x.right, i - r)

def OS_RANK(T, x):
r = x.left.size + 1
y = x
while y != T.root:
if y == y.parent.right:
r = r + y.parent.left.size + 1
y = y.parent

return r

def INORDER_TREE_WALK(x):
if x != None:
INORDER_TREE_WALK(x.left)
print( x.key, x.color, x.size)
INORDER_TREE_WALK(x.right)

def LEFT_ROTATE(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

SET_SIZE(T, x)
SET_SIZE(T, y)

def RIGHT_ROTATE(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.left:
x.parent.left = y
else:
x.parent.right = y

y.right = x
x.parent = y

SET_SIZE(T, x)
SET_SIZE(T, y)

def RB_INSERT_FIXUP(T, z):
while z.parent.color == COLOR.RED:
if z.parent == z.parent.parent.left:
y = z.parent.parent.right
if y.color == COLOR.RED:
z.parent.color = COLOR.BLACK
y.color = COLOR.BLACK
z.parent.parent.color = COLOR.RED
z = z.parent.parent
else:
if z == z.parent.right:
z = z.parent
LEFT_ROTATE(T, z)

z.parent.color = COLOR.BLACK
z.parent.parent.color = COLOR.RED
RIGHT_ROTATE(T, z.parent.parent)
else:
y = z.parent.parent.left
if y.color == COLOR.RED:
z.parent.color = COLOR.BLACK
y.color = COLOR.BLACK
z.parent.parent.color = COLOR.RED
z = z.parent.parent
else:
if z == z.parent.left:
z = z.parent
RIGHT_ROTATE(T, z)

z.parent.color = COLOR.BLACK
z.parent.parent.color = COLOR.RED
LEFT_ROTATE(T, z.parent.parent)

T.root.color = COLOR.BLACK

def RB_INSERT(T, z):
z.right = T.nil
z.left = T.nil
z.parent = T.nil
z.size = 1

y = T.nil
x = T.root
while x != T.nil:
y = x
x.size = x.size + 1
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 = COLOR.RED
RB_INSERT_FIXUP(T, z)

def TREE_MINIMUM(T, x):
while x.left != T.nil:
x = x.left
return x

def TREE_MAXIMUM(T, x):
while x.right != T.nil:
x = x.right
return x

def RB_TRANSPLANT(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 RB_DELETE_FIXUP(T, x):
while x != T.root and x.color == COLOR.BLACK:
if x == x.parent.left:
w = x.parent.right
if w.color == COLOR.RED:
w.color = COLOR.BLACK
x.parent.color = COLOR.RED
LEFT_ROTATE(T, x.parent)
w = x.parent.right

if w.left.color == COLOR.BLACK and w.right.color == COLOR.BLACK:
w.color = COLOR.RED
x = x.parent
else:
if w.right.color == COLOR.BLACK:
w.left.color = COLOR.BLACK
w.color = COLOR.RED
RIGHT_ROTATE(T, w)
w = x.parent.right
w.color = x.parent.color
x.parent.color = COLOR.BLACK
w.right.color = COLOR.BLACK
LEFT_ROTATE(T, x.parent)
x = T.root

else:
w = x.parent.left
if w.color == COLOR.RED:
w.color = COLOR.BLACK
x.parent.color = COLOR.RED
RIGHT_ROTATE(T, x.parent)
w = x.parent.left

if w.left.color == COLOR.BLACK and w.right.color == COLOR.BLACK:
w.color = COLOR.RED
x = x.parent
else:
if w.left.color == COLOR.BLACK:
w.right.color = COLOR.BLACK
w.color = COLOR.RED
LEFT_ROTATE(T, w)
w = x.parent.left
w.color = x.parent.color
x.parent.color = COLOR.BLACK
w.left.color = COLOR.BLACK
RIGHT_ROTATE(T, x.parent)
x = T.root
x.color = COLOR.BLACK

def RB_DELETE(T, z):
y = z
y_original_color = y.color
if z.left == T.nil:
x = z.right
RB_TRANSPLANT(T, z, z.right)
elif z.right == T.nil:
x = z.left
RB_TRANSPLANT(T, z, z.left)
else:
y = TREE_MINIMUM(T, z.right)
y_original_color = y.color
x = y.right
if y.parent == z:
x.parent = y
else:
RB_TRANSPLANT(T, y, y.right)
y.right = z.right
y.right.parent = y

RB_TRANSPLANT(T, z, y)
y.left = z.left
y.left.parent = y
y.color = z.color

t = y
while t != T.nil:
t.size = t.size - 1
t = t.parent

if y_original_color == COLOR.BLACK:
RB_DELETE_FIXUP(T, x)


14.2如果扩展数据结构



其中4为目的,2为手段,但是这两则需要通过3进行证明。例如:



14.3区间树

区间树是红黑树扩展的一个实例









class COLOR:
RED = "red"
BLACK = "black"

class INTERVAL:
def __init__(self, low, high):
self.low = low
self.high = high

def __cmp__(self, other):
return self.low == other.low and self.high == other.high

def __lt__(self, other):
if self.low == other.low:
return self.high < other.high
return self.low < other.low

class TREENODE():
def __init__(self, key, color=COLOR.BLACK, parent = None):
self.key = key
self.parent = parent
self.left = None
self.right = None
self.color = color
self.max = key.high

class TREE():
def __init__(self):
self.nil = TREENODE(INTERVAL(0,0))
self.root = self.nil

def SET_MAX(x):
x.max = max(x.key.high, x.left.max, x.right.max)

def INTERVAL_SEARCH(T, i):
x = T.root
while x != T.nil and (x.key.low > i.high or x.key.high < i.low):
if x.left != T.nil and x.left.max >= i.low:
x = x.left
else:
x = x.right
return x

def INORDER_TREE_WALK(x):
if x != None:
INORDER_TREE_WALK(x.left)
print( x.key.low, x.key.high, x.color)
INORDER_TREE_WALK(x.right)

def LEFT_ROTATE(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

SET_MAX(x)
SET_MAX(y)

def RIGHT_ROTATE(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.left:
x.parent.left = y
else:
x.parent.right = y

y.right = x
x.parent = y

SET_MAX(x)
SET_MAX(y)

def RB_INSERT_FIXUP(T, z):
while z.parent.color == COLOR.RED:
if z.parent == z.parent.parent.left:
y = z.parent.parent.right
if y.color == COLOR.RED:
z.parent.color = COLOR.BLACK
y.color = COLOR.BLACK
z.parent.parent.color = COLOR.RED
z = z.parent.parent
else:
if z == z.parent.right:
z = z.parent
LEFT_ROTATE(T, z)

z.parent.color = COLOR.BLACK
z.parent.parent.color = COLOR.RED
RIGHT_ROTATE(T, z.parent.parent)
else:
y = z.parent.parent.left
if y.color == COLOR.RED:
z.parent.color = COLOR.BLACK
y.color = COLOR.BLACK
z.parent.parent.color = COLOR.RED
z = z.parent.parent
else:
if z == z.parent.left:
z = z.parent
RIGHT_ROTATE(T, z)

z.parent.color = COLOR.BLACK
z.parent.parent.color = COLOR.RED
LEFT_ROTATE(T, z.parent.parent)

T.root.color = COLOR.BLACK

def RB_INSERT(T, z):
z.right = T.nil
z.left = T.nil
z.parent = T.nil

y = T.nil
x = T.root
while x != T.nil:
y = x
x.max = max(x.max, z.max)
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 = COLOR.RED
RB_INSERT_FIXUP(T, z)

def TREE_MINIMUM(T, x):
while x.left != T.nil:
x = x.left
return x

def TREE_MAXIMUM(T, x):
while x.right != T.nil:
x = x.right
return x

def RB_TRANSPLANT(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 RB_DELETE_FIXUP(T, x):
while x != T.root and x.color == COLOR.BLACK:
if x == x.parent.left:
w = x.parent.right
if w.color == COLOR.RED:
w.color = COLOR.BLACK
x.parent.color = COLOR.RED
LEFT_ROTATE(T, x.parent)
w = x.parent.right

if w.left.color == COLOR.BLACK and w.right.color == COLOR.BLACK:
w.color = COLOR.RED
x = x.parent
else:
if w.right.color == COLOR.BLACK:
w.left.color = COLOR.BLACK
w.color = COLOR.RED
RIGHT_ROTATE(T, w)
w = x.parent.right
w.color = x.parent.color
x.parent.color = COLOR.BLACK
w.right.color = COLOR.BLACK
LEFT_ROTATE(T, x.parent)
x = T.root

else:
w = x.parent.left
if w.color == COLOR.RED:
w.color = COLOR.BLACK
x.parent.color = COLOR.RED
RIGHT_ROTATE(T, x.parent)
w = x.parent.left

if w.left.color == COLOR.BLACK and w.right.color == COLOR.BLACK:
w.color = COLOR.RED
x = x.parent
else:
if w.left.color == COLOR.BLACK:
w.right.color = COLOR.BLACK
w.color = COLOR.RED
LEFT_ROTATE(T, w)
w = x.parent.left
w.color = x.parent.color
x.parent.color = COLOR.BLACK
w.left.color = COLOR.BLACK
RIGHT_ROTATE(T, x.parent)
x = T.root
x.color = COLOR.BLACK

def RB_DELETE(T, z):
y = z
y_original_color = y.color
if z.left == T.nil:
x = z.right
RB_TRANSPLANT(T, z, z.right)
elif z.right == T.nil:
x = z.left
RB_TRANSPLANT(T, z, z.left)
else:
y = TREE_MINIMUM(T, z.right)
y_original_color = y.color
x = y.right
if y.parent == z:
x.parent = y
else:
RB_TRANSPLANT(T, y, y.right)
y.right = z.right
y.right.parent = y

RB_TRANSPLANT(T, z, y)
y.left = z.left
y.left.parent = y
y.color = z.color

t = y
while t != T.nil:
SET_MAX(t)
t = t.parent

if y_original_color == COLOR.BLACK:
RB_DELETE_FIXUP(T, x)


习题解答
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: