算法导论 第十四章 数据结构的扩张

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)
    

习题解答


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值