from abc import ABC
from collections import MutableMapping
classTree:"""Abstract base class representing a tree structure."""# ----------------------------nested Position class -----------------------------classPosition:"""An abstraction representing the location of a single element."""defelement(self):"""return the element stored at this Position"""raise NotImplementedError("must be implemented by subclass")def__eq__(self, other):"""Return True if other Position represents the same location."""raise NotImplementedError("must be implemented by subclass")def__ne__(self, other):"""Return True if other does not represent the same location."""returnnot(self == other)# ---------- abstract methods that concrete subclass must support------------defroot(self):"""Return Position representing the tree's root (or None if empty)."""raise NotImplementedError("must be implemented by subclass")defparent(self, p):"""Return Position representing p's parent """return NotImplementedError("must be implemented by subclass")defnum_children(self, p):"""Return the number of children that Position p has."""raise NotImplementedError("must be implemented by subclass")defchildren(self, p):"""Generate an iteration of Positions representing p's children."""raise NotImplementedError("must be implemented by subclass")def__len__(self):"""Return the total number of elements in the tree."""raise NotImplementedError("must be implemented by subclass")# --------------------- concrete methods implemented in this class --------------defis_root(self, p):"Return True if Position p represents the root of the tree."return self.root()== p
defis_leaf(self, p):"""Return True if Position p does not have any children."""return self.num_children(p)==0defis_empty(self):"""Return True if the tree is empty."""returnlen(self)==0defdepth(self, p):"""Return the number of levels separating Position p from the root."""if self.is_root(p):return0else:return1+ self.depth(self.parent(p))# 定义 树的高度等于所有叶子结点的深度中的最大值# 时间复杂度为n**2def_height1(self):"""Return the height of the tree."""returnmax(self.depth(p)for p in self.positions()if self.is_leaf(p))# 从根节点,自顶向下,效率比height快# 时间复杂度为ndef_height2(self, p):if self.is_leaf(p):return0else:return1+max(self._height2(c)for c in self.children(p))defheight(self, p=None):"""Return the height of the subtree rooted at Position p.
If p is None,return height of the entire tree.
"""if p isNone:
p = self.root()return self._height2(p)# start_height2 recursiondef__iter__(self):"""Generate an iteration of the tree's elements."""for p in self.positions():# use same order as positions()yield p.element()# but yield each elementclassBinaryTree(Tree):"""Abstract base class representing a binary tree structure."""# -------------------additional abstract methods -------------------------defleft(self, p):"""Return a Position representing p's left child.
Return None if p does not have a left child.
"""raise NotImplementedError("must be implemented by subclass")defright(self, p):"""Return a Position representing p's right child.
Return None if p does not have a right child.
"""raise NotImplementedError("must be implemented by subclass")# ----------------------------concrete mehtods implemented in this class ===========defsibling(self, p):"""Return a Position representing p's sibling (or None if no sibling)。"""
parent = self.parent(p)if parent isNone:# p must be the rootreturnNone# root has no siblingelse:if p == self.left(parent):return self.right(parent)# possibly Noneelse:return self.left(parent)# possibly Nonedefchildren(self, p):"""Generate an iteraiton of Positions representing p's children."""if self.left(p)isnotNone:yield self.left(p)if self.right(p)isnotNone:yield self.right(p)classLinkedBinaryTree(BinaryTree):"""Linked representation of binary tree structure."""class_Node:# Lightweight ,nonpublic class for storing a node.
__slots__ ="_element","_parent","_left","_right"def__init__(self, element, parent=None, left=None, right=None):
self._element = element
self._parent = parent
self._left = left
self._right = right
classPosition(BinaryTree.Position):""" An abstraction representing the location of a single element."""def__init__(self, container, node):"""Constructor should not be invoked by user."""
self._container = container
self._node = node
defelement(self):"""Return the element stored at this Position."""return self._node._element
def__eq__(self, other):"""Return True if other is a Position representing the same location."""returntype(other)istype(self)and other._node is self._node
def_validate(self, p):"""Return associated node ,if position is valid."""ifnotisinstance(p, self.Position):raise TypeError("p must be proper Position type")if p._container isnot self:raise ValueError("p does not belong to this container")if p._node._parent is p._node:# convention for deprecated nodesraise ValueError("p is no longer valid")return p._node
def_make_position(self, node):"""Return Position instance for given node (or None if no node)."""return self.Position(self, node)if node isnotNoneelseNone# ------------------------ binary tree constructor --------------------def__init__(self):"""Create an initially empty binary tree."""
self._root =None
self._size =0# --------------------public accessors ---------------------def__len__(self):"""return the total number of elements in the tree."""return self._size
defroot(self):"""Return the root Position of the tree(or None if tree is empty)"""return self._make_position(self._root)defparent(self, p):
node = self._validate(p)return self._make_position(node._parent)defleft(self, p):"""Return the Position of p's left child (or None if no left child)."""
node = self._validate(p)return self._make_position(node._left)defright(self, p):"""Return the Position of p's right child (or None if no right child)."""
node = self._validate(p)return self._make_position(node._right)defnum_children(self, p):"""Return the number of children of Position p."""
node = self._validate(p)
count =0if node._left isnotNone:
count +=1if node._right isnotNone:
count +=1return count
def_add_root(self, e):"""Place element e at the root of an empty tree and return new Position.
Raise ValueError if tree nonempty.
"""if self._root isnotNone:raise ValueError("Root exists")
self._size +=1
self._root = self._Node(e)return self._make_position(self._root)def_add_left(self, p, e):"""Create a new left child for Position p,storing element e.
Return the Position of new node.
Raise ValueError if Position p is invalid or p already has a left child.
"""
node = self._validate(p)if node._left isnotNone:raise ValueError("Left child exists.")
self._size +=1
node._left = self._Node(e, node)return self._make_position(node._left)def_add_right(self, p, e):"""Create a new right child for Position p,storing element e.
Return the Position of new node.
Raise ValueError if Position p is invalid or p already has a left child.
"""
node = self._validate(p)if node._right isnotNone:raise ValueError("Right child exists")
self._size +=1
node._right = self._Node(e, node)return self._make_position(node._right)def_replace(self, p, e):"""Replace the element at position p with e , and return old element."""
node = self._validate(p)
old = node._element
node._element = e
return old
def_delete(self, p):"""Delete the node at Position p , and replace it with its child, if any.
Return the element that had been stored at Position p.
Raise ValueError if Position p is invalid or p has two children.
"""
node = self._validate(p)if self.num_children(p)==2:raise ValueError("p has two children")
child = node._left if node._left else node._right # might be Noneif child isnotNone:
child._parent = node._parent # child's grandparent becomes parentif node is self._root:
self._root = child # child becomes rootelse:
parent = node._parent
if node is parent._left:
parent._left = child
else:
parent._right = child
self._size -=1
node._parent = node # convention for deprecated node 丢弃该节点return node._element
def_attach(self, p, t1, t2):"""Attach trees t1 and t2 as left and right subtrees of external p."""
node = self._validate(p)ifnot self.is_leaf(p):raise ValueError('position must be leaf')ifnottype(self)istype(t1)istype(t2):raise TypeError("Tree types must match")
self._size +=len(t1)+len(t2)ifnot t1.is_empty():# attached t1 as left subtree of node
t1._root._parent = node
node._left = t1._root
t1._root =None
t1._size =0ifnot t2.is_empty():# attached t2 as right subtree of node
t2._root._parent = node
node._right = t2._root
t2._root =None
t2._size =0passclassMapBase(MutableMapping, ABC):"""Our own abstract base class that includes a nonpublic _Item class"""# ---------------------nested _Item class ---------------class_Item:"""Lightweight composite to store key-value pairs as map items."""
__slots__ ='_key','_value'def__init__(self, k, v):
self._key = k
self._value = v
def__eq__(self, other):return self._key == other._key # compare items based on their keysdef__ne__(self, other):returnnot(self == other)# opposite of __eq__def__lt__(self, other):return self._key < other._key # compare items based on their keysclassTreeMap(LinkedBinaryTree, MapBase):"""Sorted map implementation using a binary search tree."""# ------------override Position class -------------------classPosition(LinkedBinaryTree.Position):defkey(self):"""Return key of map's key-value pair."""return self.element()._key
defvalue(self):"""Return value of map's key-value pair."""return self.element()._value
def_subtree_search(self, p, k):"""Return Position of p's subtree having key k, or last node searched."""if k == p.key():# found matchreturn p
elif k < p.key():if self.left(p)isnotNone:return self._subtree_search(self.left(p), k)else:if self.right(p)isnotNone:return self._subtree_search(self.right(p), k)return p
def_subtree_first_position(self, p):"""Return Position of first item in subtree rooted at p."""
walk = p
while self.left(walk)isnotNone:
walk = self.left(walk)# keep walking leftreturn walk
def_subtree_last_position(self, p):"""Return Position of last item in subtree rooted at p."""
walk = p
while self.right(walk)isnotNone:# walk walking right
walk = self.right(walk)return walk
deffirst(self):"""Return the first Position in the tree(or None if empty)."""return self._subtree_first_position(self.root())iflen(self)>0elseNonedeflast(self):"""Return the last Position in the tree (or None if empty)."""return self._subtree_last_position(self.root())iflen(self)>0elseNonedefbefore(self, p):"""Return the Position just before p in the natural order.
Return None if p is the first position
"""
self._validate(p)# inherited from LinkedBinaryTreeif self.left(p):return self._subtree_last_position(self.left(p))else:# walk upward
walk = p
above = self.parent(walk)while above isnotNoneand walk == self.left(above):
walk = above
above = self.parent(walk)return above
defafter(self, p):"""Return the Position just after p in the natural order.
Return None if p is the last position.
"""# symmetric to before(p)
self._validate(p)if self.right(p):return self._subtree_first_position(self.right(p))else:
walk = p
above = self.parent(walk)while above isnotNoneand self.right(above)== walk:
walk = above
above = self.parent(walk)return above
deffind_position(self, k):"""Return position with key k , or else neighbor (or None if empty)."""if self.is_empty():returnNoneelse:
p = self._subtree_search(self.root(), k)# self._rebalance_access(p) # hook for balanced tree subclassesreturn p
deffind_min(self):"""Return (key,value) pair with minimum key (or None if empty)."""if self.is_empty():returnNoneelse:
p = self.first()return p.key(), p.value()deffind_ge(self, k):"""Return (key,value) pair with least key greater than or equal to k.
Return None if there does not exist such a key.
"""if self.is_empty():returnNoneelse:
p = self.find_position(k)# may not find exact matchif p.key()< k:
p = self.after(p)return(p.key(), p.value())if p isnotNoneelseNonedeffind_range(self, start, stop):"""Iterate all (key , value ) pairs such that start <= key < stop.
If start is None ,iteration begins with minimum key of map.
If stop is None,iteration continues through the maximum key of map.
"""ifnot self.is_empty():if start isNone:
p = self.first()else:# we initialize p with logic similar to find_ge
p = self.find_position(start)if p.key()< start:
p = self.after(p)while p isnotNoneand(stop isNoneor p.key()< stop):yield p.key(), p.value()
p = self.after(p)def__getitem__(self, item):"""Return value associated with key k (raise KeyError if not fount)."""if self.is_empty():raise KeyError("Key Error: "+repr(item))else:
p = self._subtree_search(self.root(), item)# self._rebalance_access(p) # hook for balanced tree subclassedif item != p.key():raise KeyError('Key Error:'+repr(item))return p.value()def__setitem__(self, key, value):"""Assign value v to key k, overwriting existing value if present."""if self.is_empty():
leaf = self._add_root(self._Item(key, value))# from LinkedBinaryTreeelse:
p = self._subtree_search(self.root(), key)if p.key()== key:
p.element()._value = value # replace existing item's value# self._rebalance_access(p) # hook for balanced tree subclassesreturnelse:
item = self._Item(key, value)if p.key()< key:
leaf = self._add_right(p, item)# inherited from LinkedBinaryTreeelse:
leaf = self._add_left(p, item)# inherited from LinkedBinaryTree# self._rebalance_insert(leaf) # hook for balanced tree subclassesdef__iter__(self):"""Generate an iteration of all keys in the map in order."""
p = self.first()while p isnotNone:yield p.key(), p.value()
p = self.after(p)defdelete(self, p):"""Remove the item at given Position."""
self._validate(p)# inherited from LinkedBinaryTreeif self.left(p)and self.right(p):# p has two children
replacement = self._subtree_last_position(self.left(p))
self._replace(p, replacement.element())# from LinkedBinaryTree
p = replacement
# now p has at most one child
parent = self.parent(p)
self._delete(p)# inherited from LinkedBinaryTree# self._rebalance_delete(parent) # if root deleted,parent is Nonedef__delitem__(self, key):"""Remove item associated with key k (raise KeyError if not found)."""ifnot self.is_empty():
p = self._subtree_search(self.root(), key)if key == p.key():
self.delete(p)# rely on positional versionreturn# successful deletion complete# self._rebalance_access(p) # hook for balanced tree subclassesraise KeyError("Key Error: "+repr(key))if __name__ =='__main__':
tree = TreeMap()
tree[1]='A'
tree[2]='B'
tree[3]='C'
tree[4]='D'
tree[5]='E'for leaf in tree:print(leaf)
11.2
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."""
node = p
while node:if k == node.key():return node
elif k < node.key():if self.left(node)isnotNone:
node = self.left(node)else:breakelse:if self.right(node)isnotNone:
node = self.right(node)else:breakreturn node
def_subtree_first_position(self, p):"""Return Position of first item in subtree rooted at p."""
walk = p
while self.left(walk)isnotNone:
walk = self.left(walk)# keep walking leftreturn walk
def_subtree_last_position(self, p):"""Return Position of last item in subtree rooted at p."""
walk = p
while self.right(walk)isnotNone:# walk walking right
walk = self.right(walk)return walk
deffirst(self):"""Return the first Position in the tree(or None if empty)."""return self._subtree_first_position(self.root())iflen(self)>0elseNonedeflast(self):"""Return the last Position in the tree (or None if empty)."""return self._subtree_last_position(self.root())iflen(self)>0elseNonedefbefore(self, p):"""Return the Position just before p in the natural order.
Return None if p is the first position
"""
self._validate(p)# inherited from LinkedBinaryTreeif self.left(p):return self._subtree_last_position(self.left(p))else:# walk upward
walk = p
above = self.parent(walk)while above isnotNoneand walk == self.left(above):
walk = above
above = self.parent(walk)return above
defafter(self, p):"""Return the Position just after p in the natural order.
Return None if p is the last position.
"""# symmetric to before(p)
self._validate(p)if self.right(p):return self._subtree_first_position(self.right(p))else:
walk = p
above = self.parent(walk)while above isnotNoneand self.right(above)== walk:
walk = above
above = self.parent(walk)return above
deffind_position(self, k):"""Return position with key k , or else neighbor (or None if empty)."""if self.is_empty():returnNoneelse:
p = self._subtree_search(self.root(), k)# self._rebalance_access(p) # hook for balanced tree subclassesreturn p
deffind_min(self):"""Return (key,value) pair with minimum key (or None if empty)."""if self.is_empty():returnNoneelse:
p = self.first()return p.key(), p.value()deffind_ge(self, k):"""Return (key,value) pair with least key greater than or equal to k.
Return None if there does not exist such a key.
"""if self.is_empty():returnNoneelse:
p = self.find_position(k)# may not find exact matchif p.key()< k:
p = self.after(p)return(p.key(), p.value())if p isnotNoneelseNonedeffind_range(self, start, stop):"""Iterate all (key , value ) pairs such that start <= key < stop.
If start is None ,iteration begins with minimum key of map.
If stop is None,iteration continues through the maximum key of map.
"""ifnot self.is_empty():if start isNone:
p = self.first()else:# we initialize p with logic similar to find_ge
p = self.find_position(start)if p.key()< start:
p = self.after(p)while p isnotNoneand(stop isNoneor p.key()< stop):yield p.key(), p.value()
p = self.after(p)def__getitem__(self, item):"""Return value associated with key k (raise KeyError if not fount)."""if self.is_empty():raise KeyError("Key Error: "+repr(item))else:
p = self._subtree_search(self.root(), item)# self._rebalance_access(p) # hook for balanced tree subclassedif item != p.key():raise KeyError('Key Error:'+repr(item))return p.value()def__setitem__(self, key, value):"""Assign value v to key k, overwriting existing value if present."""if self.is_empty():
leaf = self._add_root(self._Item(key, value))# from LinkedBinaryTreeelse:
p = self._subtree_search(self.root(), key)if p.key()== key:
p.element()._value = value # replace existing item's value# self._rebalance_access(p) # hook for balanced tree subclassesreturnelse:
item = self._Item(key, value)if p.key()< key:
leaf = self._add_right(p, item)# inherited from LinkedBinaryTreeelse:
leaf = self._add_left(p, item)# inherited from LinkedBinaryTree# self._rebalance_insert(leaf) # hook for balanced tree subclassesdef__iter__(self):"""Generate an iteration of all keys in the map in order."""
p = self.first()while p isnotNone:yield p.key(), p.value()
p = self.after(p)defdelete(self, p):"""Remove the item at given Position."""
self._validate(p)# inherited from LinkedBinaryTreeif self.left(p)and self.right(p):# p has two children
replacement = self._subtree_last_position(self.left(p))
self._replace(p, replacement.element())# from LinkedBinaryTree
p = replacement
# now p has at most one child
parent = self.parent(p)
self._delete(p)# inherited from LinkedBinaryTree# self._rebalance_delete(parent) # if root deleted,parent is Nonedef__delitem__(self, key):"""Remove item associated with key k (raise KeyError if not found)."""ifnot self.is_empty():
p = self._subtree_search(self.root(), key)if key == p.key():
self.delete(p)# rely on positional versionreturn# successful deletion complete# self._rebalance_access(p) # hook for balanced tree subclassesraise KeyError("Key Error: "+repr(key))if __name__ =='__main__':
tree = TreeMap()
tree[1]='A'
tree[2]='B'
tree[3]='C'
tree[4]='D'
tree[5]='E'for leaf in tree:print(leaf)
11.31
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()defsetdefault(self, key, value):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 subclassespassdef__setitem__(self, key, value):"""Assign value v to key k, overwriting existing value if present."""if self.is_empty():
leaf = self._add_root(self._Item(key, value))# from LinkedBinaryTreeelse:
p = self._subtree_search(self.root(), key)if p.key()== key:
p.element()._value = value # replace existing item's value# self._rebalance_access(p) # hook for balanced tree subclassesreturnelse:
item = self._Item(key, value)if p.key()< key:
leaf = self._add_right(p, item)# inherited from LinkedBinaryTreeelse:
leaf = self._add_left(p, item)# inherited from LinkedBinaryTree# self._rebalance_insert(leaf) # hook for balanced tree subclassesdef__iter__(self):"""Generate an iteration of all keys in the map in order."""
p = self.first()while p isnotNone:yield p.key(), p.value()
p = self.after(p)defdelete(self, p):"""Remove the item at given Position."""
self._validate(p)# inherited from LinkedBinaryTreeif self.left(p)and self.right(p):# p has two children
replacement = self._subtree_last_position(self.left(p))
self._replace(p, replacement.element())# from LinkedBinaryTree
p = replacement
# now p has at most one child
parent = self.parent(p)
self._delete(p)# inherited from LinkedBinaryTree# self._rebalance_delete(parent) # if root deleted,parent is Nonedef__delitem__(self, key):"""Remove item associated with key k (raise KeyError if not found)."""ifnot self.is_empty():
p = self._subtree_search(self.root(), key)if key == p.key():
self.delete(p)# rely on positional versionreturn# successful deletion complete# self._rebalance_access(p) # hook for balanced tree subclassesraise KeyError("Key Error: "+repr(key))def_relink(self, parent, child, make_left_child):"""Relink parent node with child node (we allow child to be None)."""if make_left_child:# make it a left child
parent._left = child
else:# make it a right child
parent._right = child
if child isnotNone:# make child point to parent
child._parent = parent
def_rotate(self, p):"""Rotate Position p above its parent."""
x = p._node
y = x._parent # we assume this exist
z = y._parent # grandparent (possibly None)if z isNone:
self._root = x # x becomes root
x._parent =Noneelse:
self._relink(z, x, y == z._left)# x becomes a direct child of z# now rotate x and y ,including transfer of middle subtreeif x == y._left:
self._relink(y, x._right,True)# x._right becomes left child of y
self._relink(x, y,False)# y becomes right child of xelse:
self._relink(y, x._left,False)# x._left becomes right child of y
self._relink(x, y,True)# y becomes left child of xdef_restructure(self, x):"""Perform trinode restructure of Position x with parent/grandparent."""
y = self.parent(x)
z = self.parent(y)if(x == self.right(y))==(y == self.right(z)):# matching alignments
self._rotate(y)# single rotation (of y)return y
else:
self._rotate(x)
self._rotate(x)return x # x is new subtree rootif __name__ =='__main__':
tree = TreeMap()for i inrange(10):
tree.setdefault(i,i)for node in tree:print(node)
11.35
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=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
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'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)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)if __name__ =='__main__':
avlTree = AVLTreeMap()for index in[62,44,78,17,50,88,48,54,52]:
avlTree[index]=1
avlTree.remove_range(50,60)for tree in avlTree:print(tree)# for tree in avlTree.find_range(50):# print(tree)
11.37
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=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
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())<=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_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__':
avlTree = AVLTreeMap()for index in[30,19,43,12,21,35,67,14,20,28,41]:
avlTree[index]=1print(avlTree.count_range(20,40))# for tree in avlTree:# print(tree)
11.40
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=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
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__':
avlTree = AVLTreeMap()for index in[30,19,43,12,21,35,67,14,20,28,41]:
avlTree[index]=1print(avlTree.count_range(20,40))for tree in avlTree:print(tree)
11.41
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__init__(self):super().__init__()
self.min_node =Nonedef_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:return self.min_node.key(), self.min_node.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
parent = self.parent(leaf)
node = leaf
while parent:if node != self.left(parent):break
node = parent
parent = self.parent(node)else:
self.min_node = 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())<=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_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__':
avlTree = AVLTreeMap()for index in[30,19,43,12,21,35,67,14,20,28,41]:
avlTree[index]=1print(avlTree.find_min())