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
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
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
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
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
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)
@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)
def insert(self, e: Entry): """基于合并操作的词条插入算法""" v = BinNode(e) self._root = self._merge(self._root, v) self._root.parent = None self._size += 1
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
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)
def attachAsRChild(p: BinNode, rc: BinNode): p.rc = rc if rc: rc.parent = p
def _updateHeight(self, x: BinNode): """更新节点高度""" x.height = max(stature(x.lc), stature(x.rc)) if RedBlack.IsBlack(x): x.height += 1 return x.height
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