Example #1
0
    def insert(self, e: Any):
        """插入"""
        x = self.search(e)
        if x:
            return x

        x = BinNode(e, parent=self._hot, lc=None,
                    rc=None)  # 创立红节点x:以self._hot为父节点,黑高度为-1
        x.height = -1

        if not self._hot:
            self._root = x

        else:

            if e < self._hot.data:
                self._hot.lc = x
            else:
                self._hot.rc = x

        self._size += 1
        self._solveDoubleRed(x)

        if x:
            return x
        else:
            return self._hot.parent
Example #2
0
    def _solveDoubleBlack(self, r: BinNode):
        """
            双黑修正: 解决节点x与被其替代的节点均为黑色的问题
        """
        p = r.parent if r else self._hot  # r的父亲
        if not p:
            return
        s = p.rc if r == p.lc else p.lc  # r的兄弟
        if RedBlack.IsBlack(s):
            t = None
            if BinNode.HasLChild(s) and RedBlack.IsRed(s.lc):
                t = s.lc
            elif BinNode.HasRChild(s) and RedBlack.IsRed(s.rc):
                t = s.rc
            if t is not None:
                oldColor = p.color
                p = super()._rotateAt(t)
                if p.parent is None:
                    self.root = p
                else:
                    if p.parent.data <= p.data:
                        p.parent.rc = p
                    else:
                        p.parent.lc = p

                b = p
                if BinNode.HasLChild(b):
                    b.lc.color = RBColor.RB_BLACK
                    self._updateHeight(b.lc)
                if BinNode.HasRChild(b):
                    b.rc.color = RBColor.RB_BLACK
                    self._updateHeight(b.rc)

                b.color = oldColor
                self._updateHeight(b)
            else:
                s.color = RBColor.RB_RED
                s.height -= 1
                if RedBlack.IsRed(p):
                    p.color = RBColor.RB_BLACK
                else:
                    p.height -= 1
                    self._solveDoubleBlack(p)

        else:
            s.color = RBColor.RB_BLACK
            p.color = RBColor.RB_RED
            t = s.lc if BinNode.IsLChild(s) else s.rc

            self._hot = p
            p = super()._rotateAt(t)
            if p.parent is None:
                self.root = p
            else:
                if p.parent.data <= p.data:
                    p.parent.rc = p
                else:
                    p.parent.lc = p

            self._solveDoubleBlack(r)
    def removeAt(self, x: BinNode):

        w = x  # 实际被摘除的节点,初值同x
        succ = None  # 实际被删除节点的接替者
        if not BinNode.HasLChild(x):  # 若x的左子树为空,则可直接将x替换为其右子树
            succ = x = x.rc

        elif not BinNode.HasRChild(x):  # 若x的右子树为空,对称处理 此时succ != None
            succ = x = x.lc
        else:
            w = w.succ()
            x.data, w.data = w.data, x.data
            u = w.parent
            succ = w.rc
            if u == x:
                u.rc = succ
            else:
                u.lc = succ
        self._hot = w.parent

        if succ:
            succ.parent = self._hot
            if self._hot.data <= succ.data:
                self._hot.rc = succ
            else:
                self._hot.lc = succ
        w.data = None
        del w
        return succ
Example #4
0
    def insert(self, e: Any):
        """将关键码e插入伸展树中"""
        if not self.root:  # 处理原树为空的退化情况
            self._size += 1
            self.root = BinNode(e, parent=None)
            return self.root

        x = self.search(e)
        if x:
            if e == x.data:
                return self.root

        self._size += 1
        t = self.root
        if self.root.data < e:
            self.root = BinNode(e, parent=None, lc=t, rc=t.rc)
            t.parent = self.root
            if BinNode.HasRChild(t):
                t.rc.parent = self.root
                t.rc = None
        else:
            self.root = BinNode(e, parent=None, lc=t.lc, rc=t)
            t.parent = self.root
            if BinNode.HasLChild(t):
                t.lc.parent = self.root
                t.lc = None

        super()._updateHeightAbove(t)
        return self.root
Example #5
0
    def _merge(self, a: BinNode, b: BinNode):
        """合并算法: 不失一般性 npl(a)>= npl(b)"""
        if not a:
            return b
        if not b:
            return a
        if npl(a) < npl(b):
            a, b = b, a
        a.npl = npl(a.rc) + 1 if a.rc else 1

        if a.data < b.data:
            a.data, b.data = b.data, a.data  # 一般情况: 首先确保b不大

        a.rc = self._merge(a.rc, b)  # 将a的右子堆,与b合并
        a.rc.parent = a  # 并更新父子关系
        return a  # 返回合并后的堆顶
    def _rotateAt(self, v: BinNode):
        """v为非空孙辈节点"""
        p = v.parent
        g = p.parent  # 视v, p, g相对位置分四种情况

        if BinNode.IsLChild(p):
            if BinNode.IsLChild(v):
                p.parent = g.parent  # 向上联接

                return self._connect34(v, p, g, v.lc, v.rc, p.rc, g.rc)
            else:
                v.parent = g.parent
                return self._connect34(p, v, g, p.lc, v.lc, v.rc, g.rc)
        else:
            if BinNode.IsRchild(v):
                p.parent = g.parent
                return self._connect34(g, p, v, g.lc, p.lc, v.lc, v.rc)
            else:
                v.parent = g.parent
                return self._connect34(g, v, p, g.lc, v.lc, v.rc, p.rc)
 def tallerChild(x):
     """在左,右孩子中取更高者"""
     if stature(x.lc) > stature(x.rc):
         return x.lc
     elif stature(x.lc) < stature(x.rc):
         return x.rc
     else:
         if BinNode.IsLChild(x):
             return x.lc
         else:
             return x.rc
Example #8
0
    def remove(self, e: Any):
        """从伸展树中删除关键码e"""
        if not self.root:
            return False

        x = self.search(e)
        if not x:
            return False

        if e != x.data:
            return False

        w = self.root
        if not BinNode.HasLChild(self.root):
            self.root = self.root.rc
            if self.root:
                self.root.parent = None

        elif not BinNode.HasRChild(self.root):
            self.root = self.root.lc
            if self.root:
                self.root.parent = None
        else:
            lTree = self.root.lc
            lTree.parent = None
            self.root.lc = None
            self.root = self.root.rc
            self.root.parent = None
            self.search(w.data)

            self.root.lc = lTree
            lTree.parent = self.root

        w.data = None
        del w
        self._size -= 1
        if self.root:
            super()._updateHeight(self.root)
        return True
Example #9
0
    def _solveDoubleRed(self, x: BinNode):
        """双红修正"""
        if BinNode.IsRoot(x):
            self._root.color = RBColor.RB_BLACK
            self._root.height += 1
            return
        p = x.parent
        if RedBlack.IsBlack(p):
            return
        g = p.parent
        u = BinNode.uncle(x)

        if RedBlack.IsBlack(u):
            if BinNode.IsLChild(x) == BinNode.IsLChild(p):
                p.color = RBColor.RB_BLACK
            else:
                x.color = RBColor.RB_BLACK

            g.color = RBColor.RB_RED

            gg = g.parent

            g = super()._rotateAt(x)  # 旋转后 需要定位 顶部节点 与父节点的关系
            if gg is None:
                self.root = g
            else:
                if gg.data <= g.data:
                    gg.rc = g
                else:
                    gg.lc = g

            g.parent = gg

        else:
            p.color = RBColor.RB_BLACK
            p.height += 1
            u.color = RBColor.RB_BLACK
            u.height += 1

            if not BinNode.IsRoot(g):
                g.color = RBColor.RB_RED

            self._solveDoubleRed(g)
Example #10
0
    @staticmethod
    def BlackHeightUpdated(x):
        """RedBlack高度更新条件"""
        t1 = stature(x.lc) == stature(x.rc)
        if RedBlack.IsRed(x):
            t = stature(x.lc)
        else:
            t = stature(x.lc) + 1
        t2 = (x.height == t)
        return t1 and t2


if __name__ == '__main__':
    # 1. 伸展树 例子
    root = BinNode(36, parent=None)
    # T = Splay(root=None)
    # T.insert(27)
    # T.insert(6)
    # T.insert(58)
    # T.insert(53)
    # T.insert(64)
    # T.insert(40)
    # T.insert(46)
    # print(T)
    # T.insert(39)
    # print(T)
    # T.remove(39)
    # T.remove(46)
    # print(T)
Example #11
0
 def insert(self, e: Entry):
     """基于合并操作的词条插入算法"""
     v = BinNode(e)
     self._root = self._merge(self._root, v)
     self._root.parent = None
     self._size += 1
Example #12
0
        a.rc = self._merge(a.rc, b)  # 将a的右子堆,与b合并
        a.rc.parent = a  # 并更新父子关系
        return a  # 返回合并后的堆顶


if __name__ == '__main__':
    pq = PQ_ComplHeap(data=[17, 13, 12, 15, 10, 8, 6, 45, 28, 74])

    print(pq.delMax(), pq.getMax())
    print(pq.delMax(), pq.getMax())
    print(pq.delMax(), pq.getMax())
    print(pq.delMax(), pq.getMax())
    print(pq.delMax(), pq.getMax())
    print(pq.delMax(), pq.getMax())
    print(pq.delMax(), pq.getMax())
    print(pq.delMax(), pq.getMax())
    print(pq.delMax(), pq.getMax())
    print(pq.delMax())
    print(pq)

    lpq = PQ_LeftHeap(root=BinNode(19), data=[17, 13, 12, 15, 10, 8, 6, 45, 28, 74])
    print(lpq.delMax(), lpq.getMax())
    print(lpq.delMax(), lpq.getMax())
    print(lpq.delMax(), lpq.getMax())
    print(lpq.delMax(), lpq.getMax())
    print(lpq.delMax(), lpq.getMax())
    print(lpq.delMax(), lpq.getMax())
    print(lpq.delMax(), lpq.getMax())
    print(lpq.delMax(), lpq.getMax())
    print(lpq)
 def _connect34(self, a: BinNode, b: BinNode, c: BinNode, T0: BinNode,
                T1: BinNode, T2: BinNode, T3: BinNode):
     """按照3+4连接3个节点和4个子树,返回重组之后局部子树根节点位置"""
     a.lc = T0
     if T0:
         T0.parent = a
     a.rc = T1
     if T1:
         T1.parent = a
     super(BST, self)._updateHeight(a)
     c.lc = T2
     if T2:
         T2.parent = c
     c.rc = T3
     if T3:
         T3.parent = c
     super(BST, self)._updateHeight(c)
     b.lc = a
     a.parent = b
     b.rc = c
     c.parent = b
     super(BST, self)._updateHeight(b)
     return b
Example #14
0
    def attachAsLChild(p: BinNode, lc: BinNode):

        p.lc = lc
        if lc:
            lc.parent = p
    @staticmethod
    def tallerChild(x):
        """在左,右孩子中取更高者"""
        if stature(x.lc) > stature(x.rc):
            return x.lc
        elif stature(x.lc) < stature(x.rc):
            return x.rc
        else:
            if BinNode.IsLChild(x):
                return x.lc
            else:
                return x.rc


if __name__ == '__main__':
    x = BinNode(data=36, parent=None)
    # T = BST(x)
    # T.insert(27)
    # T.insert(6)
    # T.insert(58)
    # T.insert(53)
    # T.insert(64)
    # T.insert(40)
    # T.insert(46)
    # T.insert(39)
    # print(T)
    # print(AVL.AvlBalanced(x))

    # T = AVL(x)
    # T.insert(27)
    # print(AVL.AvlBalanced(T.root), T.root)
Example #16
0
    def attachAsRChild(p: BinNode, rc: BinNode):

        p.rc = rc
        if rc:
            rc.parent = p
Example #17
0
 def _updateHeight(self, x: BinNode):
     """更新节点高度"""
     x.height = max(stature(x.lc), stature(x.rc))
     if RedBlack.IsBlack(x):
         x.height += 1
     return x.height
Example #18
0
    def _splay(self, v: BinNode):
        """Splay树伸展算法, 从节点v出发逐层伸展"""
        if not v:
            return

        while v.parent and v.parent.parent:

            p = v.parent
            g = p.parent

            gg = g.parent  # 每轮之后v都以原曾祖父为父
            if BinNode.IsLChild(v):
                if BinNode.IsLChild(p):
                    Splay.attachAsLChild(g, p.rc)
                    Splay.attachAsLChild(p, v.rc)

                    Splay.attachAsRChild(p, g)
                    Splay.attachAsRChild(v, p)

                else:
                    Splay.attachAsLChild(p, v.rc)
                    Splay.attachAsRChild(g, v.lc)

                    Splay.attachAsLChild(v, g)
                    Splay.attachAsRChild(v, p)

            elif BinNode.IsRchild(p):
                Splay.attachAsRChild(g, p.lc)
                Splay.attachAsRChild(p, v.rc)

                Splay.attachAsLChild(p, g)
                Splay.attachAsLChild(v, p)

            else:
                Splay.attachAsRChild(p, v.lc)
                Splay.attachAsLChild(g, v.rc)

                Splay.attachAsRChild(v, g)
                Splay.attachAsLChild(v, p)

            if not gg:
                v.parent = None
            else:
                if g == gg.lc:
                    Splay.attachAsLChild(gg, v)
                else:
                    Splay.attachAsRChild(gg, v)
            super()._updateHeight(g)
            super()._updateHeight(p)
            super()._updateHeight(v)

        p = v.parent
        if p:  # 如果p果真非空,则额外再做一次单旋
            if BinNode.IsLChild(v):
                Splay.attachAsLChild(p, v.rc)
                Splay.attachAsRChild(v, p)
            else:
                Splay.attachAsRChild(p, v.lc)
                Splay.attachAsLChild(v, p)

            super()._updateHeight(p)
            super()._updateHeight(v)

        v.parent = None
        return v