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','_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)>0elseNonedef_before(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
def_after(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
@staticmethoddefafter(p):return p.element()._after
@staticmethoddefbefore(p):return p.element()._before
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=None):"""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
after_node = self._after(leaf)
leaf.element()._after = after_node
if after_node:
after_node.element()._before = leaf
before_node = self._before(leaf)
leaf.element()._before = before_node
if before_node:
before_node.element()._after = leaf
# 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)
m, n = y.key(), y.value()
z = self.parent(y)
p, q = z.key(), z.value()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','_num_node'def__init__(self, element, parent=None, left=None, right=None):super().__init__(element, parent, left, right)
self._height =0# will be recomputed during balancing
self._num_node =1defleft_height(self):return self._left._height if self._left isnotNoneelse0defright_height(self):return self._right._height if self._right isnotNoneelse0defleft_num(self):return self._left._num_node if self._left isnotNoneelse0defright_num(self):return self._right._num_node 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_recompute_num_code(p):
p._node._num_node =1+sum([p._node.left_num(), p._node.right_num()])
@staticmethoddef_isbalanced(p):returnabs(p._node.left_height()- p._node.right_height())<=2def_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_num_code(self.left(p))
self._recompute_num_code(self.right(p))
self._recompute_height(p)# adjust for recent changes
self._recompute_num_code(p)if 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)defremove_range(self, start, stop=None):ifnot self.is_empty():if stop isNone:
p, stop = self.first(), start
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):
node = p
p = self.after(node)
self.delete(node)defcount_range(self, start, stop=None)->int:ifnot self.is_empty():if stop isNone:
p, stop = self.first(), start
else:
p = self.find_position(start)if p.key()< start:
p = self.after(p)
count =0
node = p
if node.key()== start:
count +=1if self.right(node):# 检查该点的下面部分
node = self.right(node)while node:if node.key()== stop:
count +=1
count += node._node.left_num()breakelif node.key()< stop:
count +=1
count += node._node.left_num()
node = self.right(node)else:
node = self.left(node)if self.parent(p):
parent = self.parent(p)while parent:# 处理上面部分if self.right(parent)== p:
p = parent
else:
last_node = self._subtree_last_position(parent)if last_node.key()== stop:
count +=1
count += parent._node.right_num()breakelif last_node.key()< stop:
count +=1
count += parent._node.right_num()
p = parent
else:
node = self.right(parent)while node:if node.key()== stop:
count +=1
count += node._node.left_num()breakelif node.key()< stop:
count +=1
count += node._node.left_num()
node = self.right(node)else:
node = self.left(node)break
parent = self.parent(parent)return count
if __name__ =='__main__':
Tree = TreeMap()for index in[30,19,43]:
Tree[index]=1# print(avlTree.count_range(20, 40))for tree in Tree:print(tree)
11.44
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','_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)>0elseNonedef_before(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
def_after(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
@staticmethoddefafter(p):return p.element()._after
@staticmethoddefbefore(p):return p.element()._before
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=None):"""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
after_node = self._after(leaf)
leaf.element()._after = after_node
if after_node:
after_node.element()._before = leaf
before_node = self._before(leaf)
leaf.element()._before = before_node
if before_node:
before_node.element()._after = leaf
# 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)
m, n = y.key(), y.value()
z = self.parent(y)
p, q = z.key(), z.value()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','_num_node'def__init__(self, element, parent=None, left=None, right=None):super().__init__(element, parent, left, right)
self._height =0# will be recomputed during balancing
self._num_node =1defleft_height(self):return self._left._height if self._left isnotNoneelse0defright_height(self):return self._right._height if self._right isnotNoneelse0defleft_num(self):return self._left._num_node if self._left isnotNoneelse0defright_num(self):return self._right._num_node 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_recompute_num_code(p):
p._node._num_node =1+sum([p._node.left_num(), p._node.right_num()])
@staticmethoddef_isbalanced(p):returnabs(p._node.left_height()- p._node.right_height())<=2def_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_num_code(self.left(p))
self._recompute_num_code(self.right(p))
self._recompute_height(p)# adjust for recent changes
self._recompute_num_code(p)if 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)defremove_range(self, start, stop=None):ifnot self.is_empty():if stop isNone:
p, stop = self.first(), start
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):
node = p
p = self.after(node)
self.delete(node)defcount_range(self, start, stop=None)->int:ifnot self.is_empty():if stop isNone:
p, stop = self.first(), start
else:
p = self.find_position(start)if p.key()< start:
p = self.after(p)
count =0
node = p
if node.key()== start:
count +=1if self.right(node):# 检查该点的下面部分
node = self.right(node)while node:if node.key()== stop:
count +=1
count += node._node.left_num()breakelif node.key()< stop:
count +=1
count += node._node.left_num()
node = self.right(node)else:
node = self.left(node)if self.parent(p):
parent = self.parent(p)while parent:# 处理上面部分if self.right(parent)== p:
p = parent
else:
last_node = self._subtree_last_position(parent)if last_node.key()== stop:
count +=1
count += parent._node.right_num()breakelif last_node.key()< stop:
count +=1
count += parent._node.right_num()
p = parent
else:
node = self.right(parent)while node:if node.key()== stop:
count +=1
count += node._node.left_num()breakelif node.key()< stop:
count +=1
count += node._node.left_num()
node = self.right(node)else:
node = self.left(node)break
parent = self.parent(parent)return count
if __name__ =='__main__':
Tree = AVLTreeMap()for index in[30,19,43]:
Tree[index]=1# print(avlTree.count_range(20, 40))for tree in Tree:print(tree)
11.45
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','_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)>0elseNonedef_before(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
def_after(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
@staticmethoddefafter(p):return p.element()._after
@staticmethoddefbefore(p):return p.element()._before
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=None):"""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
after_node = self._after(leaf)
leaf.element()._after = after_node
if after_node:
after_node.element()._before = leaf
before_node = self._before(leaf)
leaf.element()._before = before_node
if before_node:
before_node.element()._after = leaf
# 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.before(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)
m, n = y.key(), y.value()
z = self.parent(y)
p, q = z.key(), z.value()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','_num_node'def__init__(self, element, parent=None, left=None, right=None):super().__init__(element, parent, left, right)
self._height =0# will be recomputed during balancing
self._num_node =1defleft_height(self):return self._left._height if self._left isnotNoneelse0defright_height(self):return self._right._height if self._right isnotNoneelse0defleft_num(self):return self._left._num_node if self._left isnotNoneelse0defright_num(self):return self._right._num_node 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_recompute_num_code(p):
p._node._num_node =1+sum([p._node.left_num(), p._node.right_num()])
@staticmethoddef_isbalanced(p):returnabs(p._node.left_height()- p._node.right_height())<=2def_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_num_code(self.left(p))
self._recompute_num_code(self.right(p))
self._recompute_height(p)# adjust for recent changes
self._recompute_num_code(p)if 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)defremove_range(self, start, stop=None):ifnot self.is_empty():if stop isNone:
p, stop = self.first(), start
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):
node = p
p = self.after(node)
self.delete(node)defcount_range(self, start, stop=None)->int:ifnot self.is_empty():if stop isNone:
p, stop = self.first(), start
else:
p = self.find_position(start)if p.key()< start:
p = self.after(p)
count =0
node = p
if node.key()== start:
count +=1if self.right(node):# 检查该点的下面部分
node = self.right(node)while node:if node.key()== stop:
count +=1
count += node._node.left_num()breakelif node.key()< stop:
count +=1
count += node._node.left_num()
node = self.right(node)else:
node = self.left(node)if self.parent(p):
parent = self.parent(p)while parent:# 处理上面部分if self.right(parent)== p:
p = parent
else:
last_node = self._subtree_last_position(parent)if last_node.key()== stop:
count +=1
count += parent._node.right_num()breakelif last_node.key()< stop:
count +=1
count += parent._node.right_num()
p = parent
else:
node = self.right(parent)while node:if node.key()== stop:
count +=1
count += node._node.left_num()breakelif node.key()< stop:
count +=1
count += node._node.left_num()
node = self.right(node)else:
node = self.left(node)break
parent = self.parent(parent)return count
if __name__ =='__main__':
Tree = AVLTreeMap()for index in[30,19,43]:
Tree[index]=1# print(avlTree.count_range(20, 40))for tree in Tree:print(tree)
11.46
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','_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)>0elseNonedef_before(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
def_after(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
@staticmethoddefafter(p):return p.element()._after
@staticmethoddefbefore(p):return p.element()._before
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=None):"""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
after_node = self._after(leaf)
leaf.element()._after = after_node
if after_node:
after_node.element()._before = leaf
before_node = self._before(leaf)
leaf.element()._before = before_node
if before_node:
before_node.element()._after = leaf
# 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.before(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)
m, n = y.key(), y.value()
z = self.parent(y)
p, q = z.key(), z.value()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 rootdefat_index(self, i):if self.root()isNone:returnNone
node = self.root()while node:if i < node.key():
node = self.left(node)elif i > node.key():
node = self.right(node)else:return node
return node
defindex_of(self, p):
self._validate(p)
node = self.first()while node and node.key()< p.key():
node = self.after(node)if node.key()== p.key():return node.key()returnNoneclassAVLTreeMap(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','_num_node'def__init__(self, element, parent=None, left=None, right=None):super().__init__(element, parent, left, right)
self._height =0# will be recomputed during balancing
self._num_node =1defleft_height(self):return self._left._height if self._left isnotNoneelse0defright_height(self):return self._right._height if self._right isnotNoneelse0defleft_num(self):return self._left._num_node if self._left isnotNoneelse0defright_num(self):return self._right._num_node 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_recompute_num_code(p):
p._node._num_node =1+sum([p._node.left_num(), p._node.right_num()])
@staticmethoddef_isbalanced(p):returnabs(p._node.left_height()- p._node.right_height())<=2def_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_num_code(self.left(p))
self._recompute_num_code(self.right(p))
self._recompute_height(p)# adjust for recent changes
self._recompute_num_code(p)if 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)defremove_range(self, start, stop=None):ifnot self.is_empty():if stop isNone:
p, stop = self.first(), start
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):
node = p
p = self.after(node)
self.delete(node)defcount_range(self, start, stop=None)->int:ifnot self.is_empty():if stop isNone:
p, stop = self.first(), start
else:
p = self.find_position(start)if p.key()< start:
p = self.after(p)
count =0
node = p
if node.key()== start:
count +=1if self.right(node):# 检查该点的下面部分
node = self.right(node)while node:if node.key()== stop:
count +=1
count += node._node.left_num()breakelif node.key()< stop:
count +=1
count += node._node.left_num()
node = self.right(node)else:
node = self.left(node)if self.parent(p):
parent = self.parent(p)while parent:# 处理上面部分if self.right(parent)== p:
p = parent
else:
last_node = self._subtree_last_position(parent)if last_node.key()== stop:
count +=1
count += parent._node.right_num()breakelif last_node.key()< stop:
count +=1
count += parent._node.right_num()
p = parent
else:
node = self.right(parent)while node:if node.key()== stop:
count +=1
count += node._node.left_num()breakelif node.key()< stop:
count +=1
count += node._node.left_num()
node = self.right(node)else:
node = self.left(node)break
parent = self.parent(parent)return count
if __name__ =='__main__':
Tree = TreeMap()for index in[30,19,43,55,12,3,12,55,9]:
Tree[index]=1print(Tree.index_of(Tree.at_index(19)))
11.47
import random
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."""
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 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 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())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))defget_random(m,n,k):return[round(random.random()*(n-m)+m)for i inrange(k)]if __name__ =='__main__':
splayTree = SplayTreeMap()
redBlackTree = RedBlackTreeMap()
index =0while index <1000000:
randomInt = get_random(1,25,10)for i in randomInt:
splayTree[i]=1for j in randomInt:
redBlackTree[j]=1for tree1, tree2 inzip(redBlackTree, splayTree):if tree1[0]== tree2[0]:print(tree1[0], tree2[0])else:breakelse:print(randomInt)break
index +=1
这里写目录标题11.4311.4411.4511.4611.4711.43from abc import ABCfrom collections import MutableMappingclass Tree: """Abstract base class representing a tree structure.""" # ----------------------------nested Position class --------------------------