from abc import ABC
from collections import MutableMapping
classTree:"""Abstract base class representing a tree structure."""# ----------------------------nested Position class -----------------------------classPosition:"""An abstraction representing the location of a single element."""defelement(self):"""return the element stored at this Position"""raise NotImplementedError("must be implemented by subclass")def__eq__(self, other):"""Return True if other Position represents the same location."""raise NotImplementedError("must be implemented by subclass")def__ne__(self, other):"""Return True if other does not represent the same location."""returnnot(self == other)# ---------- abstract methods that concrete subclass must support------------defroot(self):"""Return Position representing the tree's root (or None if empty)."""raise NotImplementedError("must be implemented by subclass")defparent(self, p):"""Return Position representing p's parent """return NotImplementedError("must be implemented by subclass")defnum_children(self, p):"""Return the number of children that Position p has."""raise NotImplementedError("must be implemented by subclass")defchildren(self, p):"""Generate an iteration of Positions representing p's children."""raise NotImplementedError("must be implemented by subclass")def__len__(self):"""Return the total number of elements in the tree."""raise NotImplementedError("must be implemented by subclass")# --------------------- concrete methods implemented in this class --------------defis_root(self, p):"Return True if Position p represents the root of the tree."return self.root()== p
defis_leaf(self, p):"""Return True if Position p does not have any children."""return self.num_children(p)==0defis_empty(self):"""Return True if the tree is empty."""returnlen(self)==0defdepth(self, p):"""Return the number of levels separating Position p from the root."""if self.is_root(p):return0else:return1+ self.depth(self.parent(p))# 定义 树的高度等于所有叶子结点的深度中的最大值# 时间复杂度为n**2def_height1(self):"""Return the height of the tree."""returnmax(self.depth(p)for p in self.positions()if self.is_leaf(p))# 从根节点,自顶向下,效率比height快# 时间复杂度为ndef_height2(self, p):if self.is_leaf(p):return0else:return1+max(self._height2(c)for c in self.children(p))defheight(self, p=None):"""Return the height of the subtree rooted at Position p.
If p is None,return height of the entire tree.
"""if p isNone:
p = self.root()return self._height2(p)# start_height2 recursiondef__iter__(self):"""Generate an iteration of the tree's elements."""for p in self.positions():# use same order as positions()yield p.element()# but yield each elementclassBinaryTree(Tree):"""Abstract base class representing a binary tree structure."""# -------------------additional abstract methods -------------------------defleft(self, p):"""Return a Position representing p's left child.
Return None if p does not have a left child.
"""raise NotImplementedError("must be implemented by subclass")defright(self, p):"""Return a Position representing p's right child.
Return None if p does not have a right child.
"""raise NotImplementedError("must be implemented by subclass")# ----------------------------concrete mehtods implemented in this class ===========defsibling(self, p):"""Return a Position representing p's sibling (or None if no sibling)。"""
parent = self.parent(p)if parent isNone:# p must be the rootreturnNone# root has no siblingelse:if p == self.left(parent):return self.right(parent)# possibly Noneelse:return self.left(parent)# possibly Nonedefchildren(self, p):"""Generate an iteraiton of Positions representing p's children."""if self.left(p)isnotNone:yield self.left(p)if self.right(p)isnotNone:yield self.right(p)classLinkedBinaryTree(BinaryTree):"""Linked representation of binary tree structure."""class_Node:# Lightweight ,nonpublic class for storing a node.
__slots__ ="_element","_parent","_left","_right"def__init__(self, element, parent=None, left=None, right=None):
self._element = element
self._parent = parent
self._left = left
self._right = right
classPosition(BinaryTree.Position):""" An abstraction representing the location of a single element."""def__init__(self, container, node):"""Constructor should not be invoked by user."""
self._container = container
self._node = node
defelement(self):"""Return the element stored at this Position."""return self._node._element
def__eq__(self, other):"""Return True if other is a Position representing the same location."""returntype(other)istype(self)and other._node is self._node
def_validate(self, p):"""Return associated node ,if position is valid."""ifnotisinstance(p, self.Position):raise TypeError("p must be proper Position type")if p._container isnot self:raise ValueError("p does not belong to this container")if p._node._parent is p._node:# convention for deprecated nodesraise ValueError("p is no longer valid")return p._node
def_make_position(self, node):"""Return Position instance for given node (or None if no node)."""return self.Position(self, node)if node isnotNoneelseNone# ------------------------ binary tree constructor --------------------def__init__(self):"""Create an initially empty binary tree."""
self._root =None
self._size =0# --------------------public accessors ---------------------def__len__(self):"""return the total number of elements in the tree."""return self._size
defroot(self):"""Return the root Position of the tree(or None if tree is empty)"""return self._make_position(self._root)defparent(self, p):
node = self._validate(p)return self._make_position(node._parent)defleft(self, p):"""Return the Position of p's left child (or None if no left child)."""
node = self._validate(p)return self._make_position(node._left)defright(self, p):"""Return the Position of p's right child (or None if no right child)."""
node = self._validate(p)return self._make_position(node._right)defnum_children(self, p):"""Return the number of children of Position p."""
node = self._validate(p)
count =0if node._left isnotNone:
count +=1if node._right isnotNone:
count +=1return count
def_add_root(self, e):"""Place element e at the root of an empty tree and return new Position.
Raise ValueError if tree nonempty.
"""if self._root isnotNone:raise ValueError("Root exists")
self._size +=1
self._root = self._Node(e)return self._make_position(self._root)def_add_left(self, p, e):"""Create a new left child for Position p,storing element e.
Return the Position of new node.
Raise ValueError if Position p is invalid or p already has a left child.
"""
node = self._validate(p)if node._left isnotNone:raise ValueError("Left child exists.")
self._size +=1
node._left = self._Node(e, node)return self._make_position(node._left)def_add_right(self, p, e):"""Create a new right child for Position p,storing element e.
Return the Position of new node.
Raise ValueError if Position p is invalid or p already has a left child.
"""
node = self._validate(p)if node._right isnotNone:raise ValueError("Right child exists")
self._size +=1
node._right = self._Node(e, node)return self._make_position(node._right)def_replace(self, p, e):"""Replace the element at position p with e , and return old element."""
node = self._validate(p)
old = node._element
node._element = e
return old
def_delete(self, p):"""Delete the node at Position p , and replace it with its child, if any.
Return the element that had been stored at Position p.
Raise ValueError if Position p is invalid or p has two children.
"""
node = self._validate(p)if self.num_children(p)==2:raise ValueError("p has two children")
child = node._left if node._left else node._right # might be Noneif child isnotNone:
child._parent = node._parent # child's grandparent becomes parentif node is self._root:
self._root = child # child becomes rootelse:
parent = node._parent
if node is parent._left:
parent._left = child
else:
parent._right = child
self._size -=1
node._parent = node # convention for deprecated node 丢弃该节点return node._element
def_attach(self, p, t1, t2):"""Attach trees t1 and t2 as left and right subtrees of external p."""
node = self._validate(p)ifnot self.is_leaf(p):raise ValueError('position must be leaf')ifnottype(self)istype(t1)istype(t2):raise TypeError("Tree types must match")
self._size +=len(t1)+len(t2)ifnot t1.is_empty():# attached t1 as left subtree of node
t1._root._parent = node
node._left = t1._root
# t1._root = None# t1._size = 0ifnot t2.is_empty():# attached t2 as right subtree of node
t2._root._parent = node
node._right = t2._root
t2._root =None
t2._size =0
self._root = node
passclassMapBase(MutableMapping, ABC):"""Our own abstract base class that includes a nonpublic _Item class"""# ---------------------nested _Item class ---------------class_Item:"""Lightweight composite to store key-value pairs as map items."""
__slots__ ='_key','_value','_after','_before'def__init__(self, k, v, a=None, b=None):
self._key = k
self._value = v
self._after = a
self._before = b
def__eq__(self, other):return self._key == other._key # compare items based on their keysdef__ne__(self, other):returnnot(self == other)# opposite of __eq__def__lt__(self, other):return self._key < other._key # compare items based on their keysclassTreeMap(LinkedBinaryTree, MapBase):"""Sorted map implementation using a binary search tree."""# ------------override Position class -------------------classPosition(LinkedBinaryTree.Position):defkey(self):"""Return key of map's key-value pair."""return self.element()._key
defvalue(self):"""Return value of map's key-value pair."""return self.element()._value
def_subtree_search(self, p, k):"""Return Position of p's subtree having key k, or last node searched."""if k == p.key():# found matchreturn p
elif k < p.key():if self.left(p)isnotNone:return self._subtree_search(self.left(p), k)else:if self.right(p)isnotNone:return self._subtree_search(self.right(p), k)return p
def_subtree_first_position(self, p):"""Return Position of first item in subtree rooted at p."""
walk = p
while self.left(walk)isnotNone:
walk = self.left(walk)# keep walking leftreturn walk
def_subtree_last_position(self, p):"""Return Position of last item in subtree rooted at p."""
walk = p
while self.right(walk)isnotNone:# walk walking right
walk = self.right(walk)return walk
deffirst(self):"""Return the first Position in the tree(or None if empty)."""return self._subtree_first_position(self.root())iflen(self)>0elseNonedeflast(self):"""Return the last Position in the tree (or None if empty)."""return self._subtree_last_position(self.root())iflen(self)>0elseNonedefbefore(self, p):"""Return the Position just before p in the natural order.
Return None if p is the first position
"""
self._validate(p)# inherited from LinkedBinaryTreeif self.left(p):return self._subtree_last_position(self.left(p))else:# walk upward
walk = p
above = self.parent(walk)while above isnotNoneand walk == self.left(above):
walk = above
above = self.parent(walk)return above
defafter(self, p):"""Return the Position just after p in the natural order.
Return None if p is the last position.
"""# symmetric to before(p)
self._validate(p)if self.right(p):return self._subtree_first_position(self.right(p))else:
walk = p
above = self.parent(walk)while above isnotNoneand self.right(above)== walk:
walk = above
above = self.parent(walk)return above
deffind_position(self, k):"""Return position with key k , or else neighbor (or None if empty)."""if self.is_empty():returnNoneelse:
p = self._subtree_search(self.root(), k)# self._rebalance_access(p) # hook for balanced tree subclassesreturn p
deffind_min(self):"""Return (key,value) pair with minimum key (or None if empty)."""if self.is_empty():returnNoneelse:
p = self.first()return p.key(), p.value()deffind_ge(self, k):"""Return (key,value) pair with least key greater than or equal to k.
Return None if there does not exist such a key.
"""if self.is_empty():returnNoneelse:
p = self.find_position(k)# may not find exact matchif p.key()< k:
p = self.after(p)return(p.key(), p.value())if p isnotNoneelseNonedeffind_range(self, start, stop):"""Iterate all (key , value ) pairs such that start <= key < stop.
If start is None ,iteration begins with minimum key of map.
If stop is None,iteration continues through the maximum key of map.
"""ifnot self.is_empty():if start isNone:
p = self.first()else:# we initialize p with logic similar to find_ge
p = self.find_position(start)if p.key()< start:
p = self.after(p)while p isnotNoneand(stop isNoneor p.key()< stop):yield p.key(), p.value()
p = self.after(p)def__getitem__(self, item):"""Return value associated with key k (raise KeyError if not fount)."""if self.is_empty():raise KeyError("Key Error: "+repr(item))else:
p = self._subtree_search(self.root(), item)# self._rebalance_access(p) # hook for balanced tree subclassedif item != p.key():raise KeyError('Key Error:'+repr(item))return p.value()def__setitem__(self, key, value):"""Assign value v to key k, overwriting existing value if present."""if self.is_empty():
leaf = self._add_root(self._Item(key, value))# from LinkedBinaryTreeelse:
p = self._subtree_search(self.root(), key)if p.key()== key:
p.element()._value = value # replace existing item's value# self._rebalance_access(p) # hook for balanced tree subclassesreturnelse:
item = self._Item(key, value)if p.key()< key:
leaf = self._add_right(p, item)# inherited from LinkedBinaryTreeelse:
leaf = self._add_left(p, item)# inherited from LinkedBinaryTree
self._rebalance_insert(leaf)# hook for balanced tree subclassesdef__iter__(self):"""Generate an iteration of all keys in the map in order."""
stack =[self.root()]whilelen(stack)!=0:
p = stack.pop()yield p.key(), p.value()if self.right(p):
stack.append(self.right(p))if self.left(p):
stack.append(self.left(p))defdelete(self, p):"""Remove the item at given Position."""
self._validate(p)# inherited from LinkedBinaryTreeif self.left(p)and self.right(p):# p has two children
replacement = self._subtree_last_position(self.left(p))
self._replace(p, replacement.element())# from LinkedBinaryTree
p = replacement
# now p has at most one child
parent = self.parent(p)
self._delete(p)# inherited from LinkedBinaryTree
self._rebalance_delete(parent)# if root deleted,parent is Nonereturn p
def__delitem__(self, key):"""Remove item associated with key k (raise KeyError if not found)."""ifnot self.is_empty():
p = self._subtree_search(self.root(), key)if key == p.key():
self.delete(p)# rely on positional versionreturn# successful deletion complete# self._rebalance_access(p) # hook for balanced tree subclassesraise KeyError("Key Error: "+repr(key))def_relink(self, parent, child, make_left_child):"""Relink parent node with child node (we allow child to be None)."""if make_left_child:# make it a left child
parent._left = child
else:# make it a right child
parent._right = child
if child isnotNone:# make child point to parent
child._parent = parent
def_rotate(self, p):"""Rotate Position p above its parent."""
x = p._node
y = x._parent # we assume this exist
z = y._parent # grandparent (possibly None)if z isNone:
self._root = x # x becomes root
x._parent =Noneelse:
self._relink(z, x, y == z._left)# x becomes a direct child of z# now rotate x and y ,including transfer of middle subtreeif x == y._left:
self._relink(y, x._right,True)# x._right becomes left child of y
self._relink(x, y,False)# y becomes right child of xelse:
self._relink(y, x._left,False)# x._left becomes right child of y
self._relink(x, y,True)# y becomes left child of xdef_restructure(self, x):"""Perform trinode restructure of Position x with parent/grandparent."""
y = self.parent(x)
z = self.parent(y)if(x == self.right(y))==(y == self.right(z)):# matching alignments
self._rotate(y)# single rotation (of y)return y
else:
self._rotate(x)
self._rotate(x)return x # x is new subtree rootclassRedBlackTreeMap(TreeMap):"""Sorted map implementation using a red-black tree."""class_Node(TreeMap._Node):"""Node class for red-black tree maintains bit that denotes color."""
__slots__ ='_red'# add additional data member to the Node classdef__init__(self, element, parent=None, left=None, right=None):super().__init__(element, parent, left, right)
self._red =True# new node red by default# --------positional-based utility methods------------------# we consider a nonexistent child to be trivially black
@staticmethoddef_set_red(p):
p._node._red =True
@staticmethoddef_set_black(p):
p._node._red =False
@staticmethoddef_set_color(p, make_red):
p._node._red = make_red
@staticmethoddef_is_red(p):return p isnotNoneand p._node._red
def_is_red_leaf(self, p):return self._is_red(p)and self.is_leaf(p)def_get_red_child(self, p):"""Return a red child of p (or None if no such child)."""for child in(self.left(p), self.right(p)):if self._is_red(child):return child
returnNone# -----------------support for insertions ----------------------------def_rebalance_insert(self, p):
self._resolve_red(p)# new node is always reddef_resolve_red(self, p):if self.is_root(p):
self._set_black(p)# make root blackelse:
parent = self.parent(p)if self._is_red(parent):# double red problem
uncle = self.sibling(parent)ifnot self._is_red(uncle):# Case 1: misshapen 4-node
middle = self._restructure(p)# do trinode restructuring#情况一 父亲的兄弟姐妹都为黑色
self._set_black(middle)# and then fix colors
self._set_red(self.left(middle))
self._set_red(self.right(middle))else:
grand = self.parent(parent)# 情况二,父亲的姐妹是红色,即曾祖父是红色,父亲和姐妹都为黑色
self._set_red(grand)# grandparent becomes red
self._set_black(self.left(grand))# its children become black
self._set_black(self.right(grand))
self._resolve_red(grand)# recur at red grandparent 即这里是防止曾祖父还会出现这种情况,再次迭代# --------------support for deletions --------------------------------def_rebalance_delete(self, p):iflen(self)==1:
self._set_black(self.root())# special case:ensure that root is blackelif p isnotNone:
n = self.num_children(p)if n ==1:# deficit exists unless child is a red leaf
c =next(self.children())ifnot self._is_red_leaf(c):# 情况一,删除后y是黑色,并且不是叶子结点,这时候需要重组操作
self._fix_deficit(p, c)elif n ==2:# 情况三if self._is_red(self.left(p)):
self._set_black(self.left(p))else:
self._set_black(self.right(p))def_fix_deficit(self, z, y):"""Resolve black deficit at z,where y is the root of z's heavier subtree."""ifnot self._is_red(y):# y is black;will apply Case 1 or 2
x = self._get_red_child(y)if x isnotNone:# Case 1: y is black and has red child ;do "transfer"#情况一y是黑色节点,且有一个红色的孩子节点
old_color = self._is_red(z)
middle = self._restructure(x)# 重组x
self._set_color(middle, old_color)# middle gets old color of z#设置x为z的颜色
self._set_black(self.left(middle))# middle gets old color of z#s设置左边为黑色
self._set_black(self.right(middle))# 设置右边为黑色else:# Case 2: y is black , but no red children;recolor as "fusion"#情况二y为黑色,并且没有红色节点,有两个子节点是黑色或无
self._set_red(y)# 将y设置为红色if self._is_red(z):# 如果z是红色,则将它着为黑色
self._set_black(z)elifnot self.is_root(z):# 继续向上迭代
self._fix_deficit(self.parent(z), self.sibling(z))# recur upwardelse:# 情况三,y节点是红色
self._rotate(y)# 旋转y
self._set_black(y)# 重新将y着为黑色
self._set_red(z)# 将z着为红色if z == self.right(y):# 将处理好的z节点再次进行判断
self._fix_deficit(z, self.left(z))else:
self._fix_deficit(z, self.right(z))defattach(self, p):
node = self.delete(self.last())
node._node._parent =None
self._attach(node, self, p)if __name__ =='__main__':
tree1 = RedBlackTreeMap()
tree2 = RedBlackTreeMap()for i in[55,22,66,32,120]:
tree1[i]= i
for j in[76,22,1,42,75,23]:
tree2[j]= j
tree1.attach(tree2)for tree in tree1:print(tree)
11.53
from abc import ABC
from collections import MutableMapping
classTree:"""Abstract base class representing a tree structure."""# ----------------------------nested Position class -----------------------------classPosition:"""An abstraction representing the location of a single element."""defelement(self):"""return the element stored at this Position"""raise NotImplementedError("must be implemented by subclass")def__eq__(self, other):"""Return True if other Position represents the same location."""raise NotImplementedError("must be implemented by subclass")def__ne__(self, other):"""Return True if other does not represent the same location."""returnnot(self == other)# ---------- abstract methods that concrete subclass must support------------defroot(self):"""Return Position representing the tree's root (or None if empty)."""raise NotImplementedError("must be implemented by subclass")defparent(self, p):"""Return Position representing p's parent """return NotImplementedError("must be implemented by subclass")defnum_children(self, p):"""Return the number of children that Position p has."""raise NotImplementedError("must be implemented by subclass")defchildren(self, p):"""Generate an iteration of Positions representing p's children."""raise NotImplementedError("must be implemented by subclass")def__len__(self):"""Return the total number of elements in the tree."""raise NotImplementedError("must be implemented by subclass")# --------------------- concrete methods implemented in this class --------------defis_root(self, p):"Return True if Position p represents the root of the tree."return self.root()== p
defis_leaf(self, p):"""Return True if Position p does not have any children."""return self.num_children(p)==0defis_empty(self):"""Return True if the tree is empty."""returnlen(self)==0defdepth(self, p):"""Return the number of levels separating Position p from the root."""if self.is_root(p):return0else:return1+ self.depth(self.parent(p))# 定义 树的高度等于所有叶子结点的深度中的最大值# 时间复杂度为n**2def_height1(self):"""Return the height of the tree."""returnmax(self.depth(p)for p in self.positions()if self.is_leaf(p))# 从根节点,自顶向下,效率比height快# 时间复杂度为ndef_height2(self, p):if self.is_leaf(p):return0else:return1+max(self._height2(c)for c in self.children(p))defheight(self, p=None):"""Return the height of the subtree rooted at Position p.
If p is None,return height of the entire tree.
"""if p isNone:
p = self.root()return self._height2(p)# start_height2 recursiondef__iter__(self):"""Generate an iteration of the tree's elements."""for p in self.positions():# use same order as positions()yield p.element()# but yield each elementclassBinaryTree(Tree):"""Abstract base class representing a binary tree structure."""# -------------------additional abstract methods -------------------------defleft(self, p):"""Return a Position representing p's left child.
Return None if p does not have a left child.
"""raise NotImplementedError("must be implemented by subclass")defright(self, p):"""Return a Position representing p's right child.
Return None if p does not have a right child.
"""raise NotImplementedError("must be implemented by subclass")# ----------------------------concrete mehtods implemented in this class ===========defsibling(self, p):"""Return a Position representing p's sibling (or None if no sibling)。"""
parent = self.parent(p)if parent isNone:# p must be the rootreturnNone# root has no siblingelse:if p == self.left(parent):return self.right(parent)# possibly Noneelse:return self.left(parent)# possibly Nonedefchildren(self, p):"""Generate an iteraiton of Positions representing p's children."""if self.left(p)isnotNone:yield self.left(p)if self.right(p)isnotNone:yield self.right(p)classLinkedBinaryTree(BinaryTree):"""Linked representation of binary tree structure."""class_Node:# Lightweight ,nonpublic class for storing a node.
__slots__ ="_element","_parent","_left","_right"def__init__(self, element, parent=None, left=None, right=None):
self._element = element
self._parent = parent
self._left = left
self._right = right
classPosition(BinaryTree.Position):""" An abstraction representing the location of a single element."""def__init__(self, container, node):"""Constructor should not be invoked by user."""
self._container = container
self._node = node
defelement(self):"""Return the element stored at this Position."""return self._node._element
def__eq__(self, other):"""Return True if other is a Position representing the same location."""returntype(other)istype(self)and other._node is self._node
def_validate(self, p):"""Return associated node ,if position is valid."""ifnotisinstance(p, self.Position):raise TypeError("p must be proper Position type")if p._container isnot self:raise ValueError("p does not belong to this container")if p._node._parent is p._node:# convention for deprecated nodesraise ValueError("p is no longer valid")return p._node
def_make_position(self, node):"""Return Position instance for given node (or None if no node)."""return self.Position(self, node)if node isnotNoneelseNone# ------------------------ binary tree constructor --------------------def__init__(self):"""Create an initially empty binary tree."""
self._root =None
self._size =0# --------------------public accessors ---------------------def__len__(self):"""return the total number of elements in the tree."""return self._size
defroot(self):"""Return the root Position of the tree(or None if tree is empty)"""return self._make_position(self._root)defparent(self, p):
node = self._validate(p)return self._make_position(node._parent)defleft(self, p):"""Return the Position of p's left child (or None if no left child)."""
node = self._validate(p)return self._make_position(node._left)defright(self, p):"""Return the Position of p's right child (or None if no right child)."""
node = self._validate(p)return self._make_position(node._right)defnum_children(self, p):"""Return the number of children of Position p."""
node = self._validate(p)
count =0if node._left isnotNone:
count +=1if node._right isnotNone:
count +=1return count
def_add_root(self, e):"""Place element e at the root of an empty tree and return new Position.
Raise ValueError if tree nonempty.
"""if self._root isnotNone:raise ValueError("Root exists")
self._size +=1
self._root = self._Node(e)return self._make_position(self._root)def_add_left(self, p, e):"""Create a new left child for Position p,storing element e.
Return the Position of new node.
Raise ValueError if Position p is invalid or p already has a left child.
"""
node = self._validate(p)if node._left isnotNone:raise ValueError("Left child exists.")
self._size +=1
node._left = self._Node(e, node)return self._make_position(node._left)def_add_right(self, p, e):"""Create a new right child for Position p,storing element e.
Return the Position of new node.
Raise ValueError if Position p is invalid or p already has a left child.
"""
node = self._validate(p)if node._right isnotNone:raise ValueError("Right child exists")
self._size +=1
node._right = self._Node(e, node)return self._make_position(node._right)def_replace(self, p, e):"""Replace the element at position p with e , and return old element."""
node = self._validate(p)
old = node._element
node._element = e
return old
def_delete(self, p):"""Delete the node at Position p , and replace it with its child, if any.
Return the element that had been stored at Position p.
Raise ValueError if Position p is invalid or p has two children.
"""
node = self._validate(p)if self.num_children(p)==2:raise ValueError("p has two children")
child = node._left if node._left else node._right # might be Noneif child isnotNone:
child._parent = node._parent # child's grandparent becomes parentif node is self._root:
self._root = child # child becomes rootelse:
parent = node._parent
if node is parent._left:
parent._left = child
else:
parent._right = child
self._size -=1
node._parent = node # convention for deprecated node 丢弃该节点return node._element
def_attach(self, p, t1, t2):"""Attach trees t1 and t2 as left and right subtrees of external p."""
node = self._validate(p)ifnot self.is_leaf(p):raise ValueError('position must be leaf')ifnottype(self)istype(t1)istype(t2):raise TypeError("Tree types must match")
self._size +=len(t1)+len(t2)ifnot t1.is_empty():# attached t1 as left subtree of node
t1._root._parent = node
node._left = t1._root
t1._root =None
t1._size =0ifnot t2.is_empty():# attached t2 as right subtree of node
t2._root._parent = node
node._right = t2._root
t2._root =None
t2._size =0passclassMapBase(MutableMapping, ABC):"""Our own abstract base class that includes a nonpublic _Item class"""# ---------------------nested _Item class ---------------class_Item:"""Lightweight composite to store key-value pairs as map items."""
__slots__ ='_key','_value'def__init__(self, k, v):
self._key = k
self._value = v
def__eq__(self, other):return self._key == other._key # compare items based on their keysdef__ne__(self, other):returnnot(self == other)# opposite of __eq__def__lt__(self, other):return self._key < other._key # compare items based on their keysclassTreeMap(LinkedBinaryTree, MapBase):"""Sorted map implementation using a binary search tree."""# ------------override Position class -------------------classPosition(LinkedBinaryTree.Position):defkey(self):"""Return key of map's key-value pair."""return self.element()._key
defvalue(self):"""Return value of map's key-value pair."""return self.element()._value
def_subtree_search(self, p, k):"""Return Position of p's subtree having key k, or last node searched."""if k == p.key():# found matchreturn p
elif k < p.key():if self.left(p)isnotNone:return self._subtree_search(self.left(p), k)else:if self.right(p)isnotNone:return self._subtree_search(self.right(p), k)return p
def_subtree_first_position(self, p):"""Return Position of first item in subtree rooted at p."""
walk = p
while self.left(walk)isnotNone:
walk = self.left(walk)# keep walking leftreturn walk
def_subtree_last_position(self, p):"""Return Position of last item in subtree rooted at p."""
walk = p
while self.right(walk)isnotNone:# walk walking right
walk = self.right(walk)return walk
deffirst(self):"""Return the first Position in the tree(or None if empty)."""return self._subtree_first_position(self.root())iflen(self)>0elseNonedeflast(self):"""Return the last Position in the tree (or None if empty)."""return self._subtree_last_position(self.root())iflen(self)>0elseNonedefbefore(self, p):"""Return the Position just before p in the natural order.
Return None if p is the first position
"""
self._validate(p)# inherited from LinkedBinaryTreeif self.left(p):return self._subtree_last_position(self.left(p))else:# walk upward
walk = p
above = self.parent(walk)while above isnotNoneand walk == self.left(above):
walk = above
above = self.parent(walk)return above
defafter(self, p):"""Return the Position just after p in the natural order.
Return None if p is the last position.
"""# symmetric to before(p)
self._validate(p)if self.right(p):return self._subtree_first_position(self.right(p))else:
walk = p
above = self.parent(walk)while above isnotNoneand self.right(above)== walk:
walk = above
above = self.parent(walk)return above
deffind_position(self, k):"""Return position with key k , or else neighbor (or None if empty)."""if self.is_empty():returnNoneelse:
p = self._subtree_search(self.root(), k)# self._rebalance_access(p) # hook for balanced tree subclassesreturn p
deffind_min(self):"""Return (key,value) pair with minimum key (or None if empty)."""if self.is_empty():returnNoneelse:
p = self.first()return p.key(), p.value()deffind_ge(self, k):"""Return (key,value) pair with least key greater than or equal to k.
Return None if there does not exist such a key.
"""if self.is_empty():returnNoneelse:
p = self.find_position(k)# may not find exact matchif p.key()< k:
p = self.after(p)return(p.key(), p.value())if p isnotNoneelseNonedeffind_range(self, start, stop):"""Iterate all (key , value ) pairs such that start <= key < stop.
If start is None ,iteration begins with minimum key of map.
If stop is None,iteration continues through the maximum key of map.
"""ifnot self.is_empty():if start isNone:
p = self.first()else:# we initialize p with logic similar to find_ge
p = self.find_position(start)if p.key()< start:
p = self.after(p)while p isnotNoneand(stop isNoneor p.key()< stop):yield p.key(), p.value()
p = self.after(p)def__getitem__(self, item):"""Return value associated with key k (raise KeyError if not fount)."""if self.is_empty():raise KeyError("Key Error: "+repr(item))else:
p = self._subtree_search(self.root(), item)# self._rebalance_access(p) # hook for balanced tree subclassedif item != p.key():raise KeyError('Key Error:'+repr(item))return p.value()def__setitem__(self, key, value):"""Assign value v to key k, overwriting existing value if present."""if self.is_empty():
leaf = self._add_root(self._Item(key, value))# from LinkedBinaryTreeelse:
p = self._subtree_search(self.root(), key)if p.key()== key:
p.element()._value = value # replace existing item's value# self._rebalance_access(p) # hook for balanced tree subclassesreturnelse:
item = self._Item(key, value)if p.key()< key:
leaf = self._add_right(p, item)# inherited from LinkedBinaryTreeelse:
leaf = self._add_left(p, item)# inherited from LinkedBinaryTree# self._rebalance_insert(leaf) # hook for balanced tree subclassesdef__iter__(self):"""Generate an iteration of all keys in the map in order."""
p = self.first()while p isnotNone:yield p.key(),p.value()
p = self.after(p)defdelete(self, p):"""Remove the item at given Position."""
self._validate(p)# inherited from LinkedBinaryTreeif self.left(p)and self.right(p):# p has two children
replacement = self._subtree_last_position(self.left(p))
self._replace(p, replacement.element())# from LinkedBinaryTree
p = replacement
# now p has at most one child
parent = self.parent(p)
self._delete(p)# inherited from LinkedBinaryTree# self._rebalance_delete(parent) # if root deleted,parent is Nonedef__delitem__(self, key):"""Remove item associated with key k (raise KeyError if not found)."""ifnot self.is_empty():
p = self._subtree_search(self.root(), key)if key == p.key():
self.delete(p)# rely on positional versionreturn# successful deletion complete# self._rebalance_access(p) # hook for balanced tree subclassesraise KeyError("Key Error: "+repr(key))def_relink(self, parent, child, make_left_child):"""Relink parent node with child node (we allow child to be None)."""if make_left_child:# make it a left child
parent._left = child
else:# make it a right child
parent._right = child
if child isnotNone:# make child point to parent
child._parent = parent
def_rotate(self, p):"""Rotate Position p above its parent."""
x = p._node
y = x._parent # we assume this exist
z = y._parent # grandparent (possibly None)if z isNone:
self._root = x # x becomes root
x._parent =Noneelse:
self._relink(z, x, y == z._left)# x becomes a direct child of z# now rotate x and y ,including transfer of middle subtreeif x == y._left:
self._relink(y, x._right,True)# x._right becomes left child of y
self._relink(x, y,False)# y becomes right child of xelse:
self._relink(y, x._left,False)# x._left becomes right child of y
self._relink(x, y,True)# y becomes left child of xdef_restructure(self, x):"""Perform trinode restructure of Position x with parent/grandparent."""
y = self.parent(x)
z = self.parent(y)if(x == self.right(y))==(y == self.right(z)):# matching alignments
self._rotate(y)# single rotation (of y)return y
else:
self._rotate(x)
self._rotate(x)return x # x is new subtree rootdefchange_redBlackTree(self):
stack =[self.root()]if __name__ =='__main__':
tree = TreeMap()for i inrange(10):
tree[i]= i
for node in tree:print(node)# print(tree.after(tree.root()).element()._key,tree.after(tree.root()).element()._value)
11.61
import time
import numpy as np
from abc import ABC
from collections import MutableMapping
# import sys# sys.setrecursionlimit(10000)classTree:"""Abstract base class representing a tree structure."""# ----------------------------nested Position class -----------------------------classPosition:"""An abstraction representing the location of a single element."""defelement(self):"""return the element stored at this Position"""raise NotImplementedError("must be implemented by subclass")def__eq__(self, other):"""Return True if other Position represents the same location."""raise NotImplementedError("must be implemented by subclass")def__ne__(self, other):"""Return True if other does not represent the same location."""returnnot(self == other)# ---------- abstract methods that concrete subclass must support------------defroot(self):"""Return Position representing the tree's root (or None if empty)."""raise NotImplementedError("must be implemented by subclass")defparent(self, p):"""Return Position representing p's parent """return NotImplementedError("must be implemented by subclass")defnum_children(self, p):"""Return the number of children that Position p has."""raise NotImplementedError("must be implemented by subclass")defchildren(self, p):"""Generate an iteration of Positions representing p's children."""raise NotImplementedError("must be implemented by subclass")def__len__(self):"""Return the total number of elements in the tree."""raise NotImplementedError("must be implemented by subclass")# --------------------- concrete methods implemented in this class --------------defis_root(self, p):"Return True if Position p represents the root of the tree."return self.root()== p
defis_leaf(self, p):"""Return True if Position p does not have any children."""return self.num_children(p)==0defis_empty(self):"""Return True if the tree is empty."""returnlen(self)==0defdepth(self, p):"""Return the number of levels separating Position p from the root."""if self.is_root(p):return0else:return1+ self.depth(self.parent(p))# 定义 树的高度等于所有叶子结点的深度中的最大值# 时间复杂度为n**2def_height1(self):"""Return the height of the tree."""returnmax(self.depth(p)for p in self.positions()if self.is_leaf(p))# 从根节点,自顶向下,效率比height快# 时间复杂度为ndef_height2(self, p):if self.is_leaf(p):return0else:return1+max(self._height2(c)for c in self.children(p))defheight(self, p=None):"""Return the height of the subtree rooted at Position p.
If p is None,return height of the entire tree.
"""if p isNone:
p = self.root()return self._height2(p)# start_height2 recursiondef__iter__(self):"""Generate an iteration of the tree's elements."""for p in self.positions():# use same order as positions()yield p.element()# but yield each elementclassBinaryTree(Tree):"""Abstract base class representing a binary tree structure."""# -------------------additional abstract methods -------------------------defleft(self, p):"""Return a Position representing p's left child.
Return None if p does not have a left child.
"""raise NotImplementedError("must be implemented by subclass")defright(self, p):"""Return a Position representing p's right child.
Return None if p does not have a right child.
"""raise NotImplementedError("must be implemented by subclass")# ----------------------------concrete mehtods implemented in this class ===========defsibling(self, p):"""Return a Position representing p's sibling (or None if no sibling)。"""
parent = self.parent(p)if parent isNone:# p must be the rootreturnNone# root has no siblingelse:if p == self.left(parent):return self.right(parent)# possibly Noneelse:return self.left(parent)# possibly Nonedefchildren(self, p):"""Generate an iteraiton of Positions representing p's children."""if self.left(p)isnotNone:yield self.left(p)if self.right(p)isnotNone:yield self.right(p)classLinkedBinaryTree(BinaryTree):"""Linked representation of binary tree structure."""class_Node:# Lightweight ,nonpublic class for storing a node.
__slots__ ="_element","_parent","_left","_right"def__init__(self, element, parent=None, left=None, right=None):
self._element = element
self._parent = parent
self._left = left
self._right = right
classPosition(BinaryTree.Position):""" An abstraction representing the location of a single element."""def__init__(self, container, node):"""Constructor should not be invoked by user."""
self._container = container
self._node = node
defelement(self):"""Return the element stored at this Position."""return self._node._element
def__eq__(self, other):"""Return True if other is a Position representing the same location."""returntype(other)istype(self)and other._node is self._node
def_validate(self, p):"""Return associated node ,if position is valid."""ifnotisinstance(p, self.Position):raise TypeError("p must be proper Position type")if p._container isnot self:raise ValueError("p does not belong to this container")if p._node._parent is p._node:# convention for deprecated nodesraise ValueError("p is no longer valid")return p._node
def_make_position(self, node):"""Return Position instance for given node (or None if no node)."""return self.Position(self, node)if node isnotNoneelseNone# ------------------------ binary tree constructor --------------------def__init__(self):"""Create an initially empty binary tree."""
self._root =None
self._size =0# --------------------public accessors ---------------------def__len__(self):"""return the total number of elements in the tree."""return self._size
defroot(self):"""Return the root Position of the tree(or None if tree is empty)"""return self._make_position(self._root)defparent(self, p):
node = self._validate(p)return self._make_position(node._parent)defleft(self, p):"""Return the Position of p's left child (or None if no left child)."""
node = self._validate(p)return self._make_position(node._left)defright(self, p):"""Return the Position of p's right child (or None if no right child)."""
node = self._validate(p)return self._make_position(node._right)defnum_children(self, p):"""Return the number of children of Position p."""
node = self._validate(p)
count =0if node._left isnotNone:
count +=1if node._right isnotNone:
count +=1return count
def_add_root(self, e):"""Place element e at the root of an empty tree and return new Position.
Raise ValueError if tree nonempty.
"""if self._root isnotNone:raise ValueError("Root exists")
self._size +=1
self._root = self._Node(e)return self._make_position(self._root)def_add_left(self, p, e):"""Create a new left child for Position p,storing element e.
Return the Position of new node.
Raise ValueError if Position p is invalid or p already has a left child.
"""
node = self._validate(p)if node._left isnotNone:raise ValueError("Left child exists.")
self._size +=1
node._left = self._Node(e, node)return self._make_position(node._left)def_add_right(self, p, e):"""Create a new right child for Position p,storing element e.
Return the Position of new node.
Raise ValueError if Position p is invalid or p already has a left child.
"""
node = self._validate(p)if node._right isnotNone:raise ValueError("Right child exists")
self._size +=1
node._right = self._Node(e, node)return self._make_position(node._right)def_replace(self, p, e):"""Replace the element at position p with e , and return old element."""
node = self._validate(p)
old = node._element
node._element = e
return old
def_delete(self, p):"""Delete the node at Position p , and replace it with its child, if any.
Return the element that had been stored at Position p.
Raise ValueError if Position p is invalid or p has two children.
"""
node = self._validate(p)if self.num_children(p)==2:raise ValueError("p has two children")
child = node._left if node._left else node._right # might be Noneif child isnotNone:
child._parent = node._parent # child's grandparent becomes parentif node is self._root:
self._root = child # child becomes rootelse:
parent = node._parent
if node is parent._left:
parent._left = child
else:
parent._right = child
self._size -=1
node._parent = node # convention for deprecated node 丢弃该节点return node._element
def_attach(self, p, t1, t2):"""Attach trees t1 and t2 as left and right subtrees of external p."""
node = self._validate(p)ifnot self.is_leaf(p):raise ValueError('position must be leaf')ifnottype(self)istype(t1)istype(t2):raise TypeError("Tree types must match")
self._size +=len(t1)+len(t2)ifnot t1.is_empty():# attached t1 as left subtree of node
t1._root._parent = node
node._left = t1._root
t1._root =None
t1._size =0ifnot t2.is_empty():# attached t2 as right subtree of node
t2._root._parent = node
node._right = t2._root
t2._root =None
t2._size =0passclassMapBase(MutableMapping, ABC):"""Our own abstract base class that includes a nonpublic _Item class"""# ---------------------nested _Item class ---------------class_Item:"""Lightweight composite to store key-value pairs as map items."""
__slots__ ='_key','_value'def__init__(self, k, v):
self._key = k
self._value = v
def__eq__(self, other):return self._key == other._key # compare items based on their keysdef__ne__(self, other):returnnot(self == other)# opposite of __eq__def__lt__(self, other):return self._key < other._key # compare items based on their keysclassTreeMap(LinkedBinaryTree, MapBase):"""Sorted map implementation using a binary search tree."""# ------------override Position class -------------------classPosition(LinkedBinaryTree.Position):defkey(self):"""Return key of map's key-value pair."""return self.element()._key
defvalue(self):"""Return value of map's key-value pair."""return self.element()._value
def_subtree_search(self, p, k):"""Return Position of p's subtree having key k, or last node searched."""if k == p.key():# found matchreturn p
elif k < p.key():if self.left(p)isnotNone:return self._subtree_search(self.left(p), k)else:if self.right(p)isnotNone:return self._subtree_search(self.right(p), k)return p
def_subtree_first_position(self, p):"""Return Position of first item in subtree rooted at p."""
walk = p
while self.left(walk)isnotNone:
walk = self.left(walk)# keep walking leftreturn walk
def_subtree_last_position(self, p):"""Return Position of last item in subtree rooted at p."""
walk = p
while self.right(walk)isnotNone:# walk walking right
walk = self.right(walk)return walk
deffirst(self):"""Return the first Position in the tree(or None if empty)."""return self._subtree_first_position(self.root())iflen(self)>0elseNonedeflast(self):"""Return the last Position in the tree (or None if empty)."""return self._subtree_last_position(self.root())iflen(self)>0elseNonedefbefore(self, p):"""Return the Position just before p in the natural order.
Return None if p is the first position
"""
self._validate(p)# inherited from LinkedBinaryTreeif self.left(p):return self._subtree_last_position(self.left(p))else:# walk upward
walk = p
above = self.parent(walk)while above isnotNoneand walk == self.left(above):
walk = above
above = self.parent(walk)return above
defafter(self, p):"""Return the Position just after p in the natural order.
Return None if p is the last position.
"""# symmetric to before(p)
self._validate(p)if self.right(p):return self._subtree_first_position(self.right(p))else:
walk = p
above = self.parent(walk)while above isnotNoneand self.right(above)== walk:
walk = above
above = self.parent(walk)return above
deffind_position(self, k):"""Return position with key k , or else neighbor (or None if empty)."""if self.is_empty():returnNoneelse:
p = self._subtree_search(self.root(), k)# self._rebalance_access(p) # hook for balanced tree subclassesreturn p
deffind_min(self):"""Return (key,value) pair with minimum key (or None if empty)."""if self.is_empty():returnNoneelse:
p = self.first()return p.key(), p.value()deffind_ge(self, k):"""Return (key,value) pair with least key greater than or equal to k.
Return None if there does not exist such a key.
"""if self.is_empty():returnNoneelse:
p = self.find_position(k)# may not find exact matchif p.key()< k:
p = self.after(p)return(p.key(), p.value())if p isnotNoneelseNonedeffind_range(self, start, stop):"""Iterate all (key , value ) pairs such that start <= key < stop.
If start is None ,iteration begins with minimum key of map.
If stop is None,iteration continues through the maximum key of map.
"""ifnot self.is_empty():if start isNone:
p = self.first()else:# we initialize p with logic similar to find_ge
p = self.find_position(start)if p.key()< start:
p = self.after(p)while p isnotNoneand(stop isNoneor p.key()< stop):yield p.key(), p.value()
p = self.after(p)def__getitem__(self, item):"""Return value associated with key k (raise KeyError if not fount)."""if self.is_empty():raise KeyError("Key Error: "+repr(item))else:
p = self._subtree_search(self.root(), item)try:
self._rebalance_access(p)# hook for balanced tree subclassedexcept Exception as e:passif item != p.key():raise KeyError('Key Error:'+repr(item))return p.value()def__setitem__(self, key, value):"""Assign value v to key k, overwriting existing value if present."""if self.is_empty():
leaf = self._add_root(self._Item(key, value))# from LinkedBinaryTreeelse:
p = self._subtree_search(self.root(), key)if p.key()== key:
p.element()._value = value # replace existing item's valuetry:
self._rebalance_access(p)# hook for balanced tree subclassesexcept Exception as e:passreturnelse:
item = self._Item(key, value)if p.key()< key:
leaf = self._add_right(p, item)# inherited from LinkedBinaryTreeelse:
leaf = self._add_left(p, item)# inherited from LinkedBinaryTree
self._rebalance_insert(leaf)# hook for balanced tree subclassesdef__iter__(self):"""Generate an iteration of all keys in the map in order."""
p = self.first()while p isnotNone:yield p.key(), p.value()
p = self.after(p)defdelete(self, p):"""Remove the item at given Position."""
self._validate(p)# inherited from LinkedBinaryTreeif self.left(p)and self.right(p):# p has two children
replacement = self._subtree_last_position(self.left(p))
self._replace(p, replacement.element())# from LinkedBinaryTree
p = replacement
# now p has at most one child
parent = self.parent(p)
self._delete(p)# inherited from LinkedBinaryTree
self._rebalance_delete(parent)# if root deleted,parent is Nonedef__delitem__(self, key):"""Remove item associated with key k (raise KeyError if not found)."""ifnot self.is_empty():
p = self._subtree_search(self.root(), key)if key == p.key():
self.delete(p)# rely on positional versionreturn# successful deletion completetry:
self._rebalance_access(p)# hook for balanced tree subclassesexcept Exception as e:passraise KeyError("Key Error: "+repr(key))def_relink(self, parent, child, make_left_child):"""Relink parent node with child node (we allow child to be None)."""if make_left_child:# make it a left child
parent._left = child
else:# make it a right child
parent._right = child
if child isnotNone:# make child point to parent
child._parent = parent
def_rotate(self, p):"""Rotate Position p above its parent."""
x = p._node
y = x._parent # we assume this exist
z = y._parent # grandparent (possibly None)if z isNone:
self._root = x # x becomes root
x._parent =Noneelse:
self._relink(z, x, y == z._left)# x becomes a direct child of z# now rotate x and y ,including transfer of middle subtreeif x == y._left:
self._relink(y, x._right,True)# x._right becomes left child of y
self._relink(x, y,False)# y becomes right child of xelse:
self._relink(y, x._left,False)# x._left becomes right child of y
self._relink(x, y,True)# y becomes left child of xdef_restructure(self, x):"""Perform trinode restructure of Position x with parent/grandparent."""
y = self.parent(x)
z = self.parent(y)if(x == self.right(y))==(y == self.right(z)):# matching alignments
self._rotate(y)# single rotation (of y)return y
else:
self._rotate(x)
self._rotate(x)return x # x is new subtree rootclassAVLTreeMap(TreeMap):"""Sorted map implementation using an AVL tree."""# ------------------ nested _Node class -------------------class_Node(TreeMap._Node):"""Node class for AVL maintains height value for balancing."""
__slots__ ='_height'def__init__(self, element, parent=None, left=None, right=None):super().__init__(element, parent, left, right)
self._height =0# will be recomputed during balancingdefleft_height(self):return self._left._height if self._left isnotNoneelse0defright_height(self):return self._right._height if self._right isnotNoneelse0# --------------positional-based utility methods ---------------------
@staticmethoddef_recompute_height(p):
p._node._height =1+max(p._node.left_height(), p._node.right_height())
@staticmethoddef_isbalanced(p):returnabs(p._node.left_height()- p._node.right_height())<=1def_tall_child(self, p, favorleft=False):# parameter controls tiebreakerif p._node.left_height()+(1if favorleft else0)> p._node.right_height():return self.left(p)else:return self.right(p)def_tall_grandchild(self, p):
child = self._tall_child(p)# if child is on left, favor left grandchild ; else favor right grandchild
alignment =(child == self.left(p))return self._tall_child(child, alignment)def_rebalance(self, p):while p isnotNone:
old_height = p._node._height # trivially 0 if new nodeifnot self._isbalanced(p):# imbalance detected!# perform trinode restructuring,setting p to resulting root,# and recompute new local heights after the restructuring
p = self._restructure(self._tall_grandchild(p))
self._recompute_height(self.left(p))
self._recompute_height(self.right(p))
self._recompute_height(p)# adjust for recent changesif p._node._height == old_height:# has height changed?
p =None# no further changes neededelse:
p = self.parent(p)# repeat with parent# ----------- override balancing hooks ------------------------def_rebalance_insert(self, p):
self._rebalance(p)def_rebalance_delete(self, p):
self._rebalance(p)classSplayTreeMap(TreeMap):"""Sorted map implementation using a splay tree."""# -----------------splay operation ---------------def_splay(self, p):while p != self.root():
parent = self.parent(p)
grand = self.parent(parent)if grand isNone:# zig case
self._rotate(p)elif(parent == self.left(grand))==(p == self.left(parent)):# zig-zig case
self._rotate(parent)# move PARENT up
self._rotate(p)# then move p upelse:# zig-zag case
self._rotate(p)# move p up
self._rotate(p)# move p up again# _------------------override balancing hooks----------------------def_rebalance_insert(self, p):
self._splay(p)def_rebalance_delete(self, p):if p isnotNone:
self._splay(p)def_rebalance_access(self, p):
self._splay(p)classRedBlackTreeMap(TreeMap):"""Sorted map implementation using a red-black tree."""class_Node(TreeMap._Node):"""Node class for red-black tree maintains bit that denotes color."""
__slots__ ='_red'# add additional data member to the Node classdef__init__(self, element, parent=None, left=None, right=None):super().__init__(element, parent, left, right)
self._red =True# new node red by default# --------positional-based utility methods------------------# we consider a nonexistent child to be trivially blackdef_set_red(self, p):
p._node._red =Truedef_set_black(self, p):
p._node._red =Falsedef_set_color(self, p, make_red):
p._node._red = make_red
def_is_red(self, p):return p isnotNoneand p._node._red
def_is_red_leaf(self, p):return self._is_red(p)and self.is_leaf(p)def_get_red_child(self, p):"""Return a red child of p (or None if no such child)."""for child in(self.left(p), self.right(p)):if self._is_red(child):return child
returnNone# -----------------support for insertions ----------------------------def_rebalance_insert(self, p):
self._resolve_red(p)# new node is always reddef_resolve_red(self, p):if self.is_root(p):
self._set_black(p)# make root blackelse:
parent = self.parent(p)if self._is_red(parent):# double red problem
uncle = self.sibling(parent)ifnot self._is_red(uncle):# Case 1: misshapen 4-node
middle = self._restructure(p)# do trinode restructuring#情况一 父亲的兄弟姐妹都为黑色
self._set_black(middle)# and then fix colors
self._set_red(self.left(middle))
self._set_red(self.right(middle))else:
grand = self.parent(parent)# 情况二,父亲的姐妹是红色,即曾祖父是红色,父亲和姐妹都为黑色
self._set_red(grand)# grandparent becomes red
self._set_black(self.left(grand))# its children become black
self._set_black(self.right(grand))
self._resolve_red(grand)# recur at red grandparent 即这里是防止曾祖父还会出现这种情况,再次迭代# --------------support for deletions --------------------------------def_rebalance_delete(self, p):iflen(self)==1:
self._set_black(self.root())# special case:ensure that root is blackelif p isnotNone:
n = self.num_children(p)if n ==1:# deficit exists unless child is a red leaf
c =next(self.children(p))ifnot self._is_red_leaf(c):# 情况一,删除后y是黑色,并且不是叶子结点,这时候需要重组操作
self._fix_deficit(p, c)elif n ==2:# 情况三if self._is_red(self.left(p)):
self._set_black(self.left(p))else:
self._set_black(self.right(p))def_fix_deficit(self, z, y):"""Resolve black deficit at z,where y is the root of z's heavier subtree."""ifnot self._is_red(y):# y is black;will apply Case 1 or 2if y isnotNone:
x = self._get_red_child(y)if x isnotNone:# Case 1: y is black and has red child ;do "transfer"#情况一y是黑色节点,且有一个红色的孩子节点
old_color = self._is_red(z)
middle = self._restructure(x)# 重组x
self._set_color(middle, old_color)# middle gets old color of z#设置x为z的颜色
self._set_black(self.left(middle))# middle gets old color of z#s设置左边为黑色
self._set_black(self.right(middle))# 设置右边为黑色else:# Case 2: y is black , but no red children;recolor as "fusion"#情况二y为黑色,并且没有红色节点,有两个子节点是黑色或无
self._set_red(y)# 将y设置为红色if self._is_red(z):# 如果z是红色,则将它着为黑色
self._set_black(z)elifnot self.is_root(z):# 继续向上迭代
self._fix_deficit(self.parent(z), self.sibling(z))# recur upwardelse:# 情况三,y节点是红色
self._rotate(y)# 旋转y
self._set_black(y)# 重新将y着为黑色
self._set_red(z)# 将z着为红色if z == self.right(y):# 将处理好的z节点再次进行判断
self._fix_deficit(z, self.left(z))else:
self._fix_deficit(z, self.right(z))if __name__ =='__main__':
avlTree = AVLTreeMap()
splayTree = SplayTreeMap()
redBlackTree = RedBlackTreeMap()
N =100000
now = time.time()for i inrange(N):
avlTree[i]= i
print(f'AVL树顺序存储{N}条数据花费时间{time.time() - now}')
now = time.time()for i inrange(N):
var = avlTree[i]print(f'AVL树顺序查找{N}条数据花费时间{time.time() - now}')
now = time.time()for i inrange(N):del avlTree[i]print(f'AVL树顺序删除{N}条数据花费时间{time.time() - now}')# now = time.time()# for i in range(N):# splayTree[i] = i# print(f'伸展树顺序存储{N}条数据花费时间{time.time() - now}')# now = time.time()# for i in range(N):# var = splayTree[i]# print(f'伸展树顺序查找{N}条数据花费时间{time.time() - now}')# now = time.time()# for i in range(N):# del splayTree[i]# print(f'伸展树顺序删除{N}条数据花费时间{time.time() - now}')
now = time.time()for i inrange(N):
redBlackTree[i]= i
print(f'RedBlackTree顺序存储{N}条数据花费时间{time.time() - now}')
now = time.time()for i inrange(N):
var = redBlackTree[i]print(f'RedBlackTree顺序查找{N}条数据花费时间{time.time() - now}')
now = time.time()for i inrange(N):del redBlackTree[i]print(f'RedBlackTree顺序删除{N}条数据花费时间{time.time() - now}')
avlTree = AVLTreeMap()
splayTree = SplayTreeMap()
redBlackTree = RedBlackTreeMap()
randInt =set(np.random.randint(1,10000000, N))
now = time.time()for i in randInt:
avlTree[i]= i
print(f'AVL树随机存储{N}条数据花费时间{time.time() - now}')
now = time.time()for i in randInt:
var = avlTree[i]print(f'AVL树随机查找{N}条数据花费时间{time.time() - now}')
now = time.time()for i in randInt:del avlTree[i]print(f'AVL树随机删除{N}条数据花费时间{time.time() - now}')# now = time.time()# for i in randInt:# splayTree[i] = i# print(f'伸展树随机存储{N}条数据花费时间{time.time() - now}')# now = time.time()# for i in randInt:# var = splayTree[i]# print(f'伸展树随机查找{N}条数据花费时间{time.time() - now}')# now = time.time()# for i in randInt:# del splayTree[i]# print(f'伸展树随机删除{N}条数据花费时间{time.time() - now}')
now = time.time()for i in randInt:
redBlackTree[i]= i
print(f'RedBlackTree随机存储{N}条数据花费时间{time.time() - now}')
now = time.time()for i in randInt:
var = redBlackTree[i]print(f'RedBlackTree随机查找{N}条数据花费时间{time.time() - now}')
now = time.time()for i in randInt:del redBlackTree[i]print(f'RedBlackTree随机删除{N}条数据花费时间{time.time() - now}')
11.62
import time
import math
import random
import numpy as np
from abc import ABC
from collections import MutableMapping
# import sys# sys.setrecursionlimit(10000)classTree:"""Abstract base class representing a tree structure."""# ----------------------------nested Position class -----------------------------classPosition:"""An abstraction representing the location of a single element."""defelement(self):"""return the element stored at this Position"""raise NotImplementedError("must be implemented by subclass")def__eq__(self, other):"""Return True if other Position represents the same location."""raise NotImplementedError("must be implemented by subclass")def__ne__(self, other):"""Return True if other does not represent the same location."""returnnot(self == other)# ---------- abstract methods that concrete subclass must support------------defroot(self):"""Return Position representing the tree's root (or None if empty)."""raise NotImplementedError("must be implemented by subclass")defparent(self, p):"""Return Position representing p's parent """return NotImplementedError("must be implemented by subclass")defnum_children(self, p):"""Return the number of children that Position p has."""raise NotImplementedError("must be implemented by subclass")defchildren(self, p):"""Generate an iteration of Positions representing p's children."""raise NotImplementedError("must be implemented by subclass")def__len__(self):"""Return the total number of elements in the tree."""raise NotImplementedError("must be implemented by subclass")# --------------------- concrete methods implemented in this class --------------defis_root(self, p):"Return True if Position p represents the root of the tree."return self.root()== p
defis_leaf(self, p):"""Return True if Position p does not have any children."""return self.num_children(p)==0defis_empty(self):"""Return True if the tree is empty."""returnlen(self)==0defdepth(self, p):"""Return the number of levels separating Position p from the root."""if self.is_root(p):return0else:return1+ self.depth(self.parent(p))# 定义 树的高度等于所有叶子结点的深度中的最大值# 时间复杂度为n**2def_height1(self):"""Return the height of the tree."""returnmax(self.depth(p)for p in self.positions()if self.is_leaf(p))# 从根节点,自顶向下,效率比height快# 时间复杂度为ndef_height2(self, p):if self.is_leaf(p):return0else:return1+max(self._height2(c)for c in self.children(p))defheight(self, p=None):"""Return the height of the subtree rooted at Position p.
If p is None,return height of the entire tree.
"""if p isNone:
p = self.root()return self._height2(p)# start_height2 recursiondef__iter__(self):"""Generate an iteration of the tree's elements."""for p in self.positions():# use same order as positions()yield p.element()# but yield each elementclassBinaryTree(Tree):"""Abstract base class representing a binary tree structure."""# -------------------additional abstract methods -------------------------defleft(self, p):"""Return a Position representing p's left child.
Return None if p does not have a left child.
"""raise NotImplementedError("must be implemented by subclass")defright(self, p):"""Return a Position representing p's right child.
Return None if p does not have a right child.
"""raise NotImplementedError("must be implemented by subclass")# ----------------------------concrete mehtods implemented in this class ===========defsibling(self, p):"""Return a Position representing p's sibling (or None if no sibling)。"""
parent = self.parent(p)if parent isNone:# p must be the rootreturnNone# root has no siblingelse:if p == self.left(parent):return self.right(parent)# possibly Noneelse:return self.left(parent)# possibly Nonedefchildren(self, p):"""Generate an iteraiton of Positions representing p's children."""if self.left(p)isnotNone:yield self.left(p)if self.right(p)isnotNone:yield self.right(p)classLinkedBinaryTree(BinaryTree):"""Linked representation of binary tree structure."""class_Node:# Lightweight ,nonpublic class for storing a node.
__slots__ ="_element","_parent","_left","_right"def__init__(self, element, parent=None, left=None, right=None):
self._element = element
self._parent = parent
self._left = left
self._right = right
classPosition(BinaryTree.Position):""" An abstraction representing the location of a single element."""def__init__(self, container, node):"""Constructor should not be invoked by user."""
self._container = container
self._node = node
defelement(self):"""Return the element stored at this Position."""return self._node._element
def__eq__(self, other):"""Return True if other is a Position representing the same location."""returntype(other)istype(self)and other._node is self._node
def_validate(self, p):"""Return associated node ,if position is valid."""ifnotisinstance(p, self.Position):raise TypeError("p must be proper Position type")if p._container isnot self:raise ValueError("p does not belong to this container")if p._node._parent is p._node:# convention for deprecated nodesraise ValueError("p is no longer valid")return p._node
def_make_position(self, node):"""Return Position instance for given node (or None if no node)."""return self.Position(self, node)if node isnotNoneelseNone# ------------------------ binary tree constructor --------------------def__init__(self):"""Create an initially empty binary tree."""
self._root =None
self._size =0# --------------------public accessors ---------------------def__len__(self):"""return the total number of elements in the tree."""return self._size
defroot(self):"""Return the root Position of the tree(or None if tree is empty)"""return self._make_position(self._root)defparent(self, p):
node = self._validate(p)return self._make_position(node._parent)defleft(self, p):"""Return the Position of p's left child (or None if no left child)."""
node = self._validate(p)return self._make_position(node._left)defright(self, p):"""Return the Position of p's right child (or None if no right child)."""
node = self._validate(p)return self._make_position(node._right)defnum_children(self, p):"""Return the number of children of Position p."""
node = self._validate(p)
count =0if node._left isnotNone:
count +=1if node._right isnotNone:
count +=1return count
def_add_root(self, e):"""Place element e at the root of an empty tree and return new Position.
Raise ValueError if tree nonempty.
"""if self._root isnotNone:raise ValueError("Root exists")
self._size +=1
self._root = self._Node(e)return self._make_position(self._root)def_add_left(self, p, e):"""Create a new left child for Position p,storing element e.
Return the Position of new node.
Raise ValueError if Position p is invalid or p already has a left child.
"""
node = self._validate(p)if node._left isnotNone:raise ValueError("Left child exists.")
self._size +=1
node._left = self._Node(e, node)return self._make_position(node._left)def_add_right(self, p, e):"""Create a new right child for Position p,storing element e.
Return the Position of new node.
Raise ValueError if Position p is invalid or p already has a left child.
"""
node = self._validate(p)if node._right isnotNone:raise ValueError("Right child exists")
self._size +=1
node._right = self._Node(e, node)return self._make_position(node._right)def_replace(self, p, e):"""Replace the element at position p with e , and return old element."""
node = self._validate(p)
old = node._element
node._element = e
return old
def_delete(self, p):"""Delete the node at Position p , and replace it with its child, if any.
Return the element that had been stored at Position p.
Raise ValueError if Position p is invalid or p has two children.
"""
node = self._validate(p)if self.num_children(p)==2:raise ValueError("p has two children")
child = node._left if node._left else node._right # might be Noneif child isnotNone:
child._parent = node._parent # child's grandparent becomes parentif node is self._root:
self._root = child # child becomes rootelse:
parent = node._parent
if node is parent._left:
parent._left = child
else:
parent._right = child
self._size -=1
node._parent = node # convention for deprecated node 丢弃该节点return node._element
def_attach(self, p, t1, t2):"""Attach trees t1 and t2 as left and right subtrees of external p."""
node = self._validate(p)ifnot self.is_leaf(p):raise ValueError('position must be leaf')ifnottype(self)istype(t1)istype(t2):raise TypeError("Tree types must match")
self._size +=len(t1)+len(t2)ifnot t1.is_empty():# attached t1 as left subtree of node
t1._root._parent = node
node._left = t1._root
t1._root =None
t1._size =0ifnot t2.is_empty():# attached t2 as right subtree of node
t2._root._parent = node
node._right = t2._root
t2._root =None
t2._size =0passclassMapBase(MutableMapping, ABC):"""Our own abstract base class that includes a nonpublic _Item class"""# ---------------------nested _Item class ---------------class_Item:"""Lightweight composite to store key-value pairs as map items."""
__slots__ ='_key','_value'def__init__(self, k, v):
self._key = k
self._value = v
def__eq__(self, other):return self._key == other._key # compare items based on their keysdef__ne__(self, other):returnnot(self == other)# opposite of __eq__def__lt__(self, other):return self._key < other._key # compare items based on their keysclassTreeMap(LinkedBinaryTree, MapBase):"""Sorted map implementation using a binary search tree."""# ------------override Position class -------------------classPosition(LinkedBinaryTree.Position):defkey(self):"""Return key of map's key-value pair."""return self.element()._key
defvalue(self):"""Return value of map's key-value pair."""return self.element()._value
def_subtree_search(self, p, k):"""Return Position of p's subtree having key k, or last node searched."""if k == p.key():# found matchreturn p
elif k < p.key():if self.left(p)isnotNone:return self._subtree_search(self.left(p), k)else:if self.right(p)isnotNone:return self._subtree_search(self.right(p), k)return p
def_subtree_first_position(self, p):"""Return Position of first item in subtree rooted at p."""
walk = p
while self.left(walk)isnotNone:
walk = self.left(walk)# keep walking leftreturn walk
def_subtree_last_position(self, p):"""Return Position of last item in subtree rooted at p."""
walk = p
while self.right(walk)isnotNone:# walk walking right
walk = self.right(walk)return walk
deffirst(self):"""Return the first Position in the tree(or None if empty)."""return self._subtree_first_position(self.root())iflen(self)>0elseNonedeflast(self):"""Return the last Position in the tree (or None if empty)."""return self._subtree_last_position(self.root())iflen(self)>0elseNonedefbefore(self, p):"""Return the Position just before p in the natural order.
Return None if p is the first position
"""
self._validate(p)# inherited from LinkedBinaryTreeif self.left(p):return self._subtree_last_position(self.left(p))else:# walk upward
walk = p
above = self.parent(walk)while above isnotNoneand walk == self.left(above):
walk = above
above = self.parent(walk)return above
defafter(self, p):"""Return the Position just after p in the natural order.
Return None if p is the last position.
"""# symmetric to before(p)
self._validate(p)if self.right(p):return self._subtree_first_position(self.right(p))else:
walk = p
above = self.parent(walk)while above isnotNoneand self.right(above)== walk:
walk = above
above = self.parent(walk)return above
deffind_position(self, k):"""Return position with key k , or else neighbor (or None if empty)."""if self.is_empty():returnNoneelse:
p = self._subtree_search(self.root(), k)# self._rebalance_access(p) # hook for balanced tree subclassesreturn p
deffind_min(self):"""Return (key,value) pair with minimum key (or None if empty)."""if self.is_empty():returnNoneelse:
p = self.first()return p.key(), p.value()deffind_ge(self, k):"""Return (key,value) pair with least key greater than or equal to k.
Return None if there does not exist such a key.
"""if self.is_empty():returnNoneelse:
p = self.find_position(k)# may not find exact matchif p.key()< k:
p = self.after(p)return(p.key(), p.value())if p isnotNoneelseNonedeffind_range(self, start, stop):"""Iterate all (key , value ) pairs such that start <= key < stop.
If start is None ,iteration begins with minimum key of map.
If stop is None,iteration continues through the maximum key of map.
"""ifnot self.is_empty():if start isNone:
p = self.first()else:# we initialize p with logic similar to find_ge
p = self.find_position(start)if p.key()< start:
p = self.after(p)while p isnotNoneand(stop isNoneor p.key()< stop):yield p.key(), p.value()
p = self.after(p)def__getitem__(self, item):"""Return value associated with key k (raise KeyError if not fount)."""if self.is_empty():raise KeyError("Key Error: "+repr(item))else:
p = self._subtree_search(self.root(), item)try:
self._rebalance_access(p)# hook for balanced tree subclassedexcept Exception as e:passif item != p.key():raise KeyError('Key Error:'+repr(item))return p.value()def__setitem__(self, key, value):"""Assign value v to key k, overwriting existing value if present."""if self.is_empty():
leaf = self._add_root(self._Item(key, value))# from LinkedBinaryTreeelse:
p = self._subtree_search(self.root(), key)if p.key()== key:
p.element()._value = value # replace existing item's valuetry:
self._rebalance_access(p)# hook for balanced tree subclassesexcept Exception as e:passreturnelse:
item = self._Item(key, value)if p.key()< key:
leaf = self._add_right(p, item)# inherited from LinkedBinaryTreeelse:
leaf = self._add_left(p, item)# inherited from LinkedBinaryTree
self._rebalance_insert(leaf)# hook for balanced tree subclassesdef__iter__(self):"""Generate an iteration of all keys in the map in order."""
p = self.first()while p isnotNone:yield p.key(), p.value()
p = self.after(p)defdelete(self, p):"""Remove the item at given Position."""
self._validate(p)# inherited from LinkedBinaryTreeif self.left(p)and self.right(p):# p has two children
replacement = self._subtree_last_position(self.left(p))
self._replace(p, replacement.element())# from LinkedBinaryTree
p = replacement
# now p has at most one child
parent = self.parent(p)
self._delete(p)# inherited from LinkedBinaryTree
self._rebalance_delete(parent)# if root deleted,parent is Nonedef__delitem__(self, key):"""Remove item associated with key k (raise KeyError if not found)."""ifnot self.is_empty():
p = self._subtree_search(self.root(), key)if key == p.key():
self.delete(p)# rely on positional versionreturn# successful deletion completetry:
self._rebalance_access(p)# hook for balanced tree subclassesexcept Exception as e:passraise KeyError("Key Error: "+repr(key))def_relink(self, parent, child, make_left_child):"""Relink parent node with child node (we allow child to be None)."""if make_left_child:# make it a left child
parent._left = child
else:# make it a right child
parent._right = child
if child isnotNone:# make child point to parent
child._parent = parent
def_rotate(self, p):"""Rotate Position p above its parent."""
x = p._node
y = x._parent # we assume this exist
z = y._parent # grandparent (possibly None)if z isNone:
self._root = x # x becomes root
x._parent =Noneelse:
self._relink(z, x, y == z._left)# x becomes a direct child of z# now rotate x and y ,including transfer of middle subtreeif x == y._left:
self._relink(y, x._right,True)# x._right becomes left child of y
self._relink(x, y,False)# y becomes right child of xelse:
self._relink(y, x._left,False)# x._left becomes right child of y
self._relink(x, y,True)# y becomes left child of xdef_restructure(self, x):"""Perform trinode restructure of Position x with parent/grandparent."""
y = self.parent(x)
z = self.parent(y)if(x == self.right(y))==(y == self.right(z)):# matching alignments
self._rotate(y)# single rotation (of y)return y
else:
self._rotate(x)
self._rotate(x)return x # x is new subtree rootclassAVLTreeMap(TreeMap):"""Sorted map implementation using an AVL tree."""# ------------------ nested _Node class -------------------class_Node(TreeMap._Node):"""Node class for AVL maintains height value for balancing."""
__slots__ ='_height'def__init__(self, element, parent=None, left=None, right=None):super().__init__(element, parent, left, right)
self._height =0# will be recomputed during balancingdefleft_height(self):return self._left._height if self._left isnotNoneelse0defright_height(self):return self._right._height if self._right isnotNoneelse0# --------------positional-based utility methods ---------------------
@staticmethoddef_recompute_height(p):
p._node._height =1+max(p._node.left_height(), p._node.right_height())
@staticmethoddef_isbalanced(p):returnabs(p._node.left_height()- p._node.right_height())<=1def_tall_child(self, p, favorleft=False):# parameter controls tiebreakerif p._node.left_height()+(1if favorleft else0)> p._node.right_height():return self.left(p)else:return self.right(p)def_tall_grandchild(self, p):
child = self._tall_child(p)# if child is on left, favor left grandchild ; else favor right grandchild
alignment =(child == self.left(p))return self._tall_child(child, alignment)def_rebalance(self, p):while p isnotNone:
old_height = p._node._height # trivially 0 if new nodeifnot self._isbalanced(p):# imbalance detected!# perform trinode restructuring,setting p to resulting root,# and recompute new local heights after the restructuring
p = self._restructure(self._tall_grandchild(p))
self._recompute_height(self.left(p))
self._recompute_height(self.right(p))
self._recompute_height(p)# adjust for recent changesif p._node._height == old_height:# has height changed?
p =None# no further changes neededelse:
p = self.parent(p)# repeat with parent# ----------- override balancing hooks ------------------------def_rebalance_insert(self, p):
self._rebalance(p)def_rebalance_delete(self, p):
self._rebalance(p)classSplayTreeMap(TreeMap):"""Sorted map implementation using a splay tree."""# -----------------splay operation ---------------def_splay(self, p):while p != self.root():
parent = self.parent(p)
grand = self.parent(parent)if grand isNone:# zig case
self._rotate(p)elif(parent == self.left(grand))==(p == self.left(parent)):# zig-zig case
self._rotate(parent)# move PARENT up
self._rotate(p)# then move p upelse:# zig-zag case
self._rotate(p)# move p up
self._rotate(p)# move p up again# _------------------override balancing hooks----------------------def_rebalance_insert(self, p):
self._splay(p)def_rebalance_delete(self, p):if p isnotNone:
self._splay(p)def_rebalance_access(self, p):
self._splay(p)classRedBlackTreeMap(TreeMap):"""Sorted map implementation using a red-black tree."""class_Node(TreeMap._Node):"""Node class for red-black tree maintains bit that denotes color."""
__slots__ ='_red'# add additional data member to the Node classdef__init__(self, element, parent=None, left=None, right=None):super().__init__(element, parent, left, right)
self._red =True# new node red by default# --------positional-based utility methods------------------# we consider a nonexistent child to be trivially blackdef_set_red(self, p):
p._node._red =Truedef_set_black(self, p):
p._node._red =Falsedef_set_color(self, p, make_red):
p._node._red = make_red
def_is_red(self, p):return p isnotNoneand p._node._red
def_is_red_leaf(self, p):return self._is_red(p)and self.is_leaf(p)def_get_red_child(self, p):"""Return a red child of p (or None if no such child)."""for child in(self.left(p), self.right(p)):if self._is_red(child):return child
returnNone# -----------------support for insertions ----------------------------def_rebalance_insert(self, p):
self._resolve_red(p)# new node is always reddef_resolve_red(self, p):if self.is_root(p):
self._set_black(p)# make root blackelse:
parent = self.parent(p)if self._is_red(parent):# double red problem
uncle = self.sibling(parent)ifnot self._is_red(uncle):# Case 1: misshapen 4-node
middle = self._restructure(p)# do trinode restructuring#情况一 父亲的兄弟姐妹都为黑色
self._set_black(middle)# and then fix colors
self._set_red(self.left(middle))
self._set_red(self.right(middle))else:
grand = self.parent(parent)# 情况二,父亲的姐妹是红色,即曾祖父是红色,父亲和姐妹都为黑色
self._set_red(grand)# grandparent becomes red
self._set_black(self.left(grand))# its children become black
self._set_black(self.right(grand))
self._resolve_red(grand)# recur at red grandparent 即这里是防止曾祖父还会出现这种情况,再次迭代# --------------support for deletions --------------------------------def_rebalance_delete(self, p):iflen(self)==1:
self._set_black(self.root())# special case:ensure that root is blackelif p isnotNone:
n = self.num_children(p)if n ==1:# deficit exists unless child is a red leaf
c =next(self.children(p))ifnot self._is_red_leaf(c):# 情况一,删除后y是黑色,并且不是叶子结点,这时候需要重组操作
self._fix_deficit(p, c)elif n ==2:# 情况三if self._is_red(self.left(p)):
self._set_black(self.left(p))else:
self._set_black(self.right(p))def_fix_deficit(self, z, y):"""Resolve black deficit at z,where y is the root of z's heavier subtree."""ifnot self._is_red(y):# y is black;will apply Case 1 or 2if y isnotNone:
x = self._get_red_child(y)if x isnotNone:# Case 1: y is black and has red child ;do "transfer"#情况一y是黑色节点,且有一个红色的孩子节点
old_color = self._is_red(z)
middle = self._restructure(x)# 重组x
self._set_color(middle, old_color)# middle gets old color of z#设置x为z的颜色
self._set_black(self.left(middle))# middle gets old color of z#s设置左边为黑色
self._set_black(self.right(middle))# 设置右边为黑色else:# Case 2: y is black , but no red children;recolor as "fusion"#情况二y为黑色,并且没有红色节点,有两个子节点是黑色或无
self._set_red(y)# 将y设置为红色if self._is_red(z):# 如果z是红色,则将它着为黑色
self._set_black(z)elifnot self.is_root(z):# 继续向上迭代
self._fix_deficit(self.parent(z), self.sibling(z))# recur upwardelse:# 情况三,y节点是红色
self._rotate(y)# 旋转y
self._set_black(y)# 重新将y着为黑色
self._set_red(z)# 将z着为红色if z == self.right(y):# 将处理好的z节点再次进行判断
self._fix_deficit(z, self.left(z))else:
self._fix_deficit(z, self.right(z))classSkiplist:class_Node:
__slots__ ='_element','_right','_down'def__init__(self, element, right, down):
self._element = element
self._right = right
self._down = down
def__init__(self):
self._maxLevel =16# 边界的最大范围
self._power =2# 阶乘
self._MaxRand = self._power ** self._maxLevel -1# 随机数区间
self._randLevel =lambda: self._maxLevel -int(math.log(random.randint(1, self._MaxRand),2))# 随机范围
self._left =[self._Node(float('-inf'),None,None)for _ inrange(self._maxLevel)]# 定义左边界
self._right =[self._Node(float('inf'),None,None)for _ inrange(self._maxLevel)]# 定义右边界for i inrange(self._maxLevel -1):# 左右边界连接,并排除最后一列
self._left[i]._right = self._right[i]# 左右连接
self._left[i]._down = self._left[i +1]# 左边界自顶向下连接
self._right[i]._down = self._right[i +1]# 右边界自顶向下连接
self._left[-1]._right = self._right[-1]# 底层边界连接
self._head = self._left[0]# 定义头部位置defSkipSearch(self, target):
node = self._head # 从头开始检索while node:if node._right._element > target:# 如果右边的值大于左边界则下降
node = node._down
elif node._right._element < target:# 如果右边的值小于左边界,则继续搜索
node = node._right
else:returnTruereturnFalsedefSkipInset(self, k):
temp =[]# 存储检索过程中的边界问题,用于直接连接
node = self._head # 定义头,每次从头部开始检索while node:if node._right._element >= k:# 如果左边大于右边则下降,同时等于时收敛
temp.append(node)
node = node._down
else:# 不满足时继续向右搜索,并且不需要记录向右的路线,因为我们只需要跳跃表的边
node = node._right
array =[self._Node(k,None,None)for _ inrange(self._randLevel())]# 定义此时随机长度的数组并放入目标值k
head = self._Node(None,None,None)# 定义一个空节点,为了后面自定向下连接节点for oldNode, newNode inzip(temp[self._maxLevel -len(array):], array):# 这样做是为了方便旧数组连接新数组
newNode._right = oldNode._right # 新节点连接原节点的右边
oldNode._right = newNode # 原节点连接新节点
head._down = newNode # 自顶向下连接
head = newNode
defdelete(self, k):
sign =False# 删除标记
node = self._head # 定义检索位置while node:if node._right._element > k:
node = node._down
elif node._right._element < k:
node = node._right
else:
sign =True# 找到目标位置
node._right = node._right._right # 连接右边的节点
node = node._down # 当前节点向下继续删除return sign
if __name__ =='__main__':
avlTree = AVLTreeMap()
splayTree = SplayTreeMap()
redBlackTree = RedBlackTreeMap()
skipList = Skiplist()
N =100000
now = time.time()for i inrange(N):
avlTree[i]= i
print(f'AVL树顺序存储{N}条数据花费时间{time.time() - now}')
now = time.time()for i inrange(N):
var = avlTree[i]print(f'AVL树顺序查找{N}条数据花费时间{time.time() - now}')
now = time.time()for i inrange(N):del avlTree[i]print(f'AVL树顺序删除{N}条数据花费时间{time.time() - now}')
now = time.time()for i inrange(N):
redBlackTree[i]= i
print(f'RedBlackTree顺序存储{N}条数据花费时间{time.time() - now}')
now = time.time()for i inrange(N):
var = redBlackTree[i]print(f'RedBlackTree顺序查找{N}条数据花费时间{time.time() - now}')
now = time.time()for i inrange(N):del redBlackTree[i]print(f'RedBlackTree顺序删除{N}条数据花费时间{time.time() - now}')
now = time.time()for i inrange(N):
skipList.SkipInset(i)print(f'SkipList顺序存储{N}条数据花费时间{time.time() - now}')
now = time.time()for i inrange(N):
skipList.SkipSearch(i)print(f'SkipList顺序查找{N}条数据花费时间{time.time() - now}')
now = time.time()for i inrange(N):
skipList.delete(i)print(f'skipList顺序删除{N}条数据花费时间{time.time() - now}')
avlTree = AVLTreeMap()
splayTree = SplayTreeMap()
redBlackTree = RedBlackTreeMap()
skipList = Skiplist()
randInt =set(np.random.randint(1,10000000, N))
now = time.time()for i in randInt:
avlTree[i]= i
print(f'AVL树随机存储{N}条数据花费时间{time.time() - now}')
now = time.time()for i in randInt:
var = avlTree[i]print(f'AVL树随机查找{N}条数据花费时间{time.time() - now}')
now = time.time()for i in randInt:del avlTree[i]print(f'AVL树随机删除{N}条数据花费时间{time.time() - now}')
now = time.time()for i in randInt:
redBlackTree[i]= i
print(f'RedBlackTree随机存储{N}条数据花费时间{time.time() - now}')
now = time.time()for i in randInt:
var = redBlackTree[i]print(f'RedBlackTree随机查找{N}条数据花费时间{time.time() - now}')
now = time.time()for i in randInt:del redBlackTree[i]print(f'RedBlackTree随机删除{N}条数据花费时间{time.time() - now}')
now = time.time()for i in randInt:
skipList.SkipInset(i)print(f'SkipList随机存储{N}条数据花费时间{time.time() - now}')
now = time.time()for i in randInt:
skipList.SkipSearch(i)print(f'SkipList随机查找{N}条数据花费时间{time.time() - now}')
now = time.time()for i in randInt:
skipList.delete(i)print(f'skipList随机删除{N}条数据花费时间{time.time() - now}')
这里写目录标题11.5111.5311.6111.6211.51from abc import ABCfrom collections import MutableMappingclass Tree: """Abstract base class representing a tree structure.""" # ----------------------------nested Position class -----------------------------