from typing import List, Any
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 elementdefpreorder(self):"""Generate a preorder iteratiom of positions in the tree."""ifnot self.is_empty():for p in self._subtree_preorder(self.root()):yield p
def_subtree_preorder(self, p):"""Generate a preorder iteration of positions in subtree rooted at p."""yield p # visit p before its subtreesfor c in self.children(p):# for each child cfor other in self._subtree_preorder(c):# do preorder of c's subtreeyield other # yielding each to our callerdefpositions(self):"""Generate an iteration of the tree's positions."""return self.preorder()# return entire preorder iterationdefpreorder_indent(self, T, p, d):"""
缩进版本
:param T:树
:param p:根节点
:param d:路径
:return:
""""""Print preorder representation of subtree of T rooted at p at depth d."""print(d,str(p.element()))# use depth for indentationfor c in T.children(p):
self.preorder_indent(T, c, d +1)# child depth is d + 1classBinaryTree(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):""" An abstraction representing the location of a single element."""def__init__(self, container, node):"""Constructor should not be invoked by yser."""
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 =0passdefglobal_variable():global count
count =0defdepth_route(Tree, p, d):"""
:param Tree:
:param p:
:return:
"""global count
count = count + d
for children in Tree.children(p):
depth_route(Tree, children, d +1)if __name__ =="__main__":
linkTree = LinkedBinaryTree()
linkTree._add_root(1)
linkTree._add_left(linkTree.root(),2)
linkTree._add_right(linkTree.root(),3)
linkTree._add_left(linkTree.left(linkTree.root()),4)
linkTree._add_right(linkTree.left(linkTree.root()),5)
global_variable()
depth_route(linkTree, linkTree.root(),0)print(f'The tree depth route count : {count}')
8.47
from abc import ABC
classEmpty(Exception):passclassLinkQueue:"""FIFO queue implementation using a singly linked list for storage."""
__slots__ ="_head","_tail","_size"class_Node:"""Lightweight,nonpublic class for storing a singly linked node."""
__slots__ ="_element","_next"# streamline memory usagedef__init__(self, element,next):# initialize node's fields
self._element = element # reference to user's element
self._next =next# reference to next nodedef__init__(self):"""Create an empty queue."""
self._head =None
self._tail =None
self._size =0# number of queue elementsdef__len__(self):"""Return the number of elements in the queue."""return self._size
defis_empty(self):"""Return True if the queue is emtpy."""return self._size ==0deffirst(self):"""Return (but do not remove) the element at the front of the queue."""if self.is_empty():raise Empty("Queue is empty")return self._head._element
defdequeue(self):"""Remove and return the first element of the queue.
Raise Emtpy exception if the queue is empty.
"""if self.is_empty():raise Empty("Queue is empty")
answer = self._head._element
self._head = self._head._next
self._size -=1if self.is_empty():# special case as queue is empty
self._tail =None# remove head had been the tailreturn answer
defenqueue(self, item):"""Add an element to the back of queue."""
newest = self._Node(item,None)# node will be new tail nodeif self.is_empty():
self._head = newest # special case : perviously emptyelse:
self._tail._next = newest
self._tail = newest # update reference to tail node
self._size +=1classTree:"""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 elementdefpostorder(self):"""Generate a postorder iteration of positions in the tree."""ifnot self.is_empty():for p in self._subtree_postorder(self.root()):# start recursionyield p
def_subtree_preorder(self, p):"""Generate a preorder iteration of positions in subtree rooted at p."""yield p # visit p before its subtreesfor c in self.children(p):# for each child cfor other in self._subtree_preorder(c):# do preorder of c's subtreeyield other # yielding each to our callerdefpositions(self):"""Generate an iteration of the tree's positions."""return self._subtree_preorder(self.root())# return entire preorder iterationdefbreadthfirst(self):"""Generate a breadth-first iteration of the positions of thr tree."""ifnot self.is_empty():
fringe = LinkQueue()# known positions not yet yielded
fringe.enqueue(self.root())# starting with the rootwhilenot fringe.is_empty():
p = fringe.dequeue()# remove from front of the queueyield p
for c in self.children(p):
fringe.enqueue(c)# add children to back of queueclassBinaryTree(Tree, ABC):"""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, ABC):""" An abstraction representing the location of a single element."""def__init__(self, container, node):"""Constructor should not be invoked by yser."""
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 =0passclassEulerTour:"""Abstract base class for performing Euler tour of a tree.
_hook_previsit and _hook_postvisit may be overridden by subclasses.
"""def__init__(self, tree):"""Prepare an Euler tour template for given tree."""
self._tree = tree
deftree(self):"""Return reference to the tree being traversed."""return self._tree
defexecute(self):"""Perform the tour and return any result from post visit of root."""iflen(self._tree)>0:return self._tour(self._tree.root(),0,[])# start the recursiondef_tour(self, p, d, path):"""
perform tour of subtree rooted at Position p.
:param p: Position of current node being visited
:param d: depth of p in the tree
:param path: list of indices of children on path from root to p
:return:
"""
self._hook_previsit(p, d, path)# print(p.element())
results =[]
path.append(0)# add new index to end of path before recursionfor c in self._tree.children(p):
results.append(self._tour(c, d +1, path))# recur on child's subtree
path[-1]+=1# increment index
path.pop()# remove extraneous index from end of path.def_hook_previsit(self, p, d, path):if self._tree.is_leaf(p)isFalse:if self._tree.height(self._tree.left(p))> self._tree.height(self._tree.right(p)):
v_height = self._tree.height(self._tree.left(p))+1else:
v_height = self._tree.height(self._tree.right(p))+1
v_balance =abs(self._tree.height(self._tree.left(p))- self._tree.height(self._tree.right(p)))if v_balance ==0:print(p.element())passdef_hook_postvisit(self, p, d, path, results):return self._tree.height(p)passclassPreorderPrintIndentedTour(EulerTour):def_hook_previsit(self, p, d, path):print(2* d *" "+str(p.element()))if __name__ =="__main__":
linkTree = LinkedBinaryTree()
linkTree._add_root(1)
linkTree._add_left(linkTree.root(),2)
linkTree._add_right(linkTree.root(),3)
linkTree._add_left(linkTree.left(linkTree.root()),4)
linkTree._add_right(linkTree.left(linkTree.root()),5)for leaf in linkTree:print(leaf, end=' ')print('')
eulerTour = EulerTour(linkTree)
eulerTour.execute()
8.50
from abc import ABC
from typing import List, Any
from collections import deque
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 elementdefpreorder(self):"""Generate a preorder iteratiom of positions in the tree."""ifnot self.is_empty():for p in self._subtree_preorder(self.root()):yield p
def_subtree_preorder(self, p):"""Generate a preorder iteration of positions in subtree rooted at p."""yield p # visit p before its subtreesfor c in self.children(p):# for each child cfor other in self._subtree_preorder(c):# do preorder of c's subtreeyield other # yielding each to our callerdefpositions(self):"""Generate an iteration of the tree's positions."""return self.preorder()# return entire preorder iterationdefpreorder_indent(self, T, p, d):"""
缩进版本
:param T:树
:param p:根节点
:param d:路径
:return:
""""""Print preorder representation of subtree of T rooted at p at depth d."""print(d,str(p.element()))# use depth for indentationfor c in T.children(p):
self.preorder_indent(T, c, d +1)# child depth is d + 1classBinaryTree(Tree, ABC):"""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, ABC):""" An abstraction representing the location of a single element."""def__init__(self, container, node):"""Constructor should not be invoked by yser."""
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 =0defpreorder_next(self, p):print(p.element(), end=' ')for children in self.children(p):
self.preorder_next(children)definorder_next(self, p):if self.left(p)isnotNone:
self.inorder_next(self.left(p))print(p.element(),end=' ')if self.right(p)isnotNone:
self.inorder_next(self.right(p))passdefpostorder_next(self, p):for children in self.children(p):
self.postorder_next(children)print(p.element(), end=' ')defbreadth_first(self, p):
linkqueue = deque()
linkqueue.append(p)whilelen(linkqueue)!=0:
node = linkqueue.popleft()print(node.element(),end=' ')for children in self.children(node):
linkqueue.append(children)defglobal_variable():global count
count =0defdepth_route(Tree, p, d):"""
:param Tree:
:param p:
:return:
"""global count
count = count + d
for children in Tree.children(p):
depth_route(Tree, children, d +1)if __name__ =="__main__":
linkTree = LinkedBinaryTree()
linkTree._add_root(1)
linkTree._add_left(linkTree.root(),2)
linkTree._add_right(linkTree.root(),3)
linkTree._add_left(linkTree.left(linkTree.root()),4)
linkTree._add_right(linkTree.left(linkTree.root()),5)
linkTree._add_left(linkTree.right(linkTree.root()),6)
linkTree._add_right(linkTree.right(linkTree.root()),7)print("先序遍历", end=' ')
linkTree.preorder_next(linkTree.root())print()print("中序遍历",end=' ')
linkTree.inorder_next(linkTree.root())print()print('后序遍历',end=' ')
linkTree.postorder_next(linkTree.root())print()print("层次遍历(广度优先)",end=' ')
linkTree.breadth_first(linkTree.root())
8.51
from abc import ABC
from collections import deque
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 elementdefpreorder(self):"""Generate a preorder iteratiom of positions in the tree."""ifnot self.is_empty():for p in self._subtree_preorder(self.root()):yield p
def_subtree_preorder(self, p):"""Generate a preorder iteration of positions in subtree rooted at p."""yield p # visit p before its subtreesfor c in self.children(p):# for each child cfor other in self._subtree_preorder(c):# do preorder of c's subtreeyield other # yielding each to our callerdefpositions(self):"""Generate an iteration of the tree's positions."""return self.preorder()# return entire preorder iterationdefpreorder_indent(self, T, p, d):"""
缩进版本
:param T:树
:param p:根节点
:param d:路径
:return:
""""""Print preorder representation of subtree of T rooted at p at depth d."""print(d,str(p.element()))# use depth for indentationfor c in T.children(p):
self.preorder_indent(T, c, d +1)# child depth is d + 1classBinaryTree(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, ABC):""" An abstraction representing the location of a single element."""def__init__(self, container, node):"""Constructor should not be invoked by yser."""
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
classiterator:def__init__(self, root):
self.__root = root
self.__sequence =[]
self.__k =-1
self.preorder_next(self.__root._node)defpreorder_next(self, p):
self.__sequence.append(p._element)if p._left isnotNone:
self.preorder_next(p._left)if p._right isnotNone:
self.preorder_next(p._right)def__next__(self):
self.__k +=1# advance to next indexif self.__k <len(self.__sequence):return self.__sequence[self.__k]# return the data elementelse:raise StopIteration()# there are no more elementsdef__iter__(self):return self
def__iter__(self):return self.iterator(self.root())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 =0defpreorder_next(self, p):yield p.element()for children in self.children(p):for other in self.preorder_next(children):yield other
definorder_next(self, p):if self.left(p)isnotNone:for other in self.inorder_next(self.left(p)):yield other
yield p.element()if self.right(p)isnotNone:for other in self.inorder_next(self.right(p)):yield other
passdefpostorder_next(self, p):for children in self.children(p):for other in self.postorder_next(children):yield other
yield p.element()defbreadth_first(self, p):
linkqueue = deque()
linkqueue.append(p)whilelen(linkqueue)!=0:
node = linkqueue.popleft()yield node.element()for children in self.children(node):
linkqueue.append(children)defpreorder(self):for node in self.breadth_first(self.root()):yield node
defglobal_variable():global count
count =0defdepth_route(Tree, p, d):"""
:param Tree:
:param p:
:return:
"""global count
count = count + d
for children in Tree.children(p):
depth_route(Tree, children, d +1)if __name__ =="__main__":
linkTree = LinkedBinaryTree()
linkTree._add_root(1)
linkTree._add_left(linkTree.root(),2)
linkTree._add_right(linkTree.root(),3)
linkTree._add_left(linkTree.left(linkTree.root()),4)
linkTree._add_right(linkTree.left(linkTree.root()),5)
linkTree._add_left(linkTree.right(linkTree.root()),6)
linkTree._add_right(linkTree.right(linkTree.root()),7)for node in linkTree:print(node, end=' ')
8.55
import os
if __name__ =='__main__':for root, dirs, files in os.walk('F:\python_code\python_senior',topdown=False):#topdown表示优先遍历的顺序默认True表示从根节点到叶子结点,False表示从叶子结点到根节点#猜测实现该算法是由一个栈完成print(root)print(dirs)print(files)
8.56
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 elementdefpreorder(self):"""Generate a preorder iteratiom of positions in the tree."""ifnot self.is_empty():for p in self._subtree_preorder(self.root()):yield p
def_subtree_preorder(self, p):"""Generate a preorder iteration of positions in subtree rooted at p."""yield p # visit p before its subtreesfor c in self.children(p):# for each child cfor other in self._subtree_preorder(c):# do preorder of c's subtreeyield other # yielding each to our callerdefpositions(self):"""Generate an iteration of the tree's positions."""return self.preorder()# return entire preorder iterationdefpreorder_indent(self, T, p, d):"""
缩进版本
:param T:树
:param p:根节点
:param d:路径
:return:
""""""Print preorder representation of subtree of T rooted at p at depth d."""print(2* d *" "+str(p.element()))# use depth for indentationfor c in T.children(p):
self.preorder_indent(T, c, d +1)# child depth is d + 1defpreorder_label(self, T, p, d, path):"""Print labeled representation of subtree of T rooted at p at depth d."""
label ='.'.join(str(j +1)for j in path)# displayed labels are one-indexedprint(2* d *" "+ label, p.element())
path.append(0)for c in T.children(p):
self.preorder_label(T, c, d +1, path)# child depth is d + 1
path[-1]+=1
path.pop()defparenthesize(self, p, d):"""Print parenthesized representation of subtree of T rooted at p."""print(2* d *" "+str(p.element()), end=' ')# use of end avoids trailing newlineifnot self.is_leaf(p):
first_time =Truefor c in self.children(p):
sep =" ("if first_time else""# determiner proper separatorif sep !="":print(sep)
first_time =False# any future passes will not be the first
self.parenthesize(c, d +1)# recur on childprint(2*d*" "+" )")# include closing parenthesiselse:print()classBinaryTree(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):""" An abstraction representing the location of a single element."""def__init__(self, container, node):"""Constructor should not be invoked by yser."""
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 =0passif __name__ =="__main__":
linkTree = LinkedBinaryTree()
linkTree._add_root(1)
linkTree._add_left(linkTree.root(),2)
linkTree._add_right(linkTree.root(),3)
linkTree._add_left(linkTree.left(linkTree.root()),4)
linkTree._add_right(linkTree.left(linkTree.root()),5)
linkTree.parenthesize(linkTree.root(),0)
8.57
from abc import ABC
from typing import List, Any
from collections import deque
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 elementdefpreorder(self):"""Generate a preorder iteratiom of positions in the tree."""ifnot self.is_empty():for p in self._subtree_preorder(self.root()):yield p
def_subtree_preorder(self, p):"""Generate a preorder iteration of positions in subtree rooted at p."""yield p # visit p before its subtreesfor c in self.children(p):# for each child cfor other in self._subtree_preorder(c):# do preorder of c's subtreeyield other # yielding each to our callerdefpositions(self):"""Generate an iteration of the tree's positions."""return self.preorder()# return entire preorder iterationdefpreorder_indent(self, T, p, d):"""
缩进版本
:param T:树
:param p:根节点
:param d:路径
:return:
""""""Print preorder representation of subtree of T rooted at p at depth d."""print(d,str(p.element()))# use depth for indentationfor c in T.children(p):
self.preorder_indent(T, c, d +1)# child depth is d + 1classBinaryTree(Tree, ABC):"""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","_sentinel"def__init__(self, element, parent=None, left=None, right=None):
self._element = element
self._parent = parent
self._left = left
self._right = right
self._sentinel =0classPosition(BinaryTree, ABC):""" An abstraction representing the location of a single element."""def__init__(self, container, node):"""Constructor should not be invoked by yser."""
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 =0defpreorder_next(self, p):print(p.element(), end=' ')for children in self.children(p):
self.preorder_next(children)definorder_next(self, p):if self.left(p)isnotNone:
self.inorder_next(self.left(p))print(p.element(), end=' ')if self.right(p)isnotNone:
self.inorder_next(self.right(p))passdefpostorder_next(self, p):for children in self.children(p):
self.postorder_next(children)print(p.element(), end=' ')defbreadth_first(self, p):
linkqueue = deque()
linkqueue.append(p)whilelen(linkqueue)!=0:
node = linkqueue.popleft()print(node.element(), end=' ')for children in self.children(node):
linkqueue.append(children)defglobal_variable():global stack
stack =[]defdepth_route(Tree, p, d):"""
:param Tree:
:param p:
:return:
"""global stack
linkqueue = deque()
linkqueue.append(p)whilelen(linkqueue)!=0:
node = linkqueue.popleft()
stack.append(node)for children in Tree.children(node):
linkqueue.append(children)defRemo_path(linkTree):
global_variable()
depth_route(linkTree, linkTree.root(),0)for node in stack[::-1]:if node._node._left isnotNone:if node._node._left._sentinel ==0:
node._node._sentinel +=1else:
node._node._sentinel += node._node._left._sentinel
node._node._sentinel +=1if node._node._right isnotNone:if node._node._right._sentinel ==0:
node._node._sentinel +=1else:
node._node._sentinel += node._node._right._sentinel
node._node._sentinel +=1if node._node._sentinel <=5:print(node._node._element)if __name__ =="__main__":
linkTree = LinkedBinaryTree()
linkTree._add_root(1)
linkTree._add_left(linkTree.root(),2)
linkTree._add_right(linkTree.root(),3)
linkTree._add_left(linkTree.left(linkTree.root()),4)
linkTree._add_right(linkTree.left(linkTree.root()),5)
linkTree._add_left(linkTree.right(linkTree.root()),6)
linkTree._add_right(linkTree.right(linkTree.root()),7)
linkTree._add_left(linkTree.left(linkTree.left(linkTree.root())),8)
linkTree._add_right(linkTree.left(linkTree.left(linkTree.root())),9)
linkTree._add_left(linkTree.right(linkTree.left(linkTree.root())),10)
linkTree._add_right(linkTree.right(linkTree.left(linkTree.root())),11)
linkTree._add_left(linkTree.left(linkTree.right(linkTree.root())),12)
linkTree._add_right(linkTree.left(linkTree.right(linkTree.root())),13)
linkTree._add_left(linkTree.right(linkTree.right(linkTree.root())),14)
linkTree._add_right(linkTree.right(linkTree.right(linkTree.root())),15)
Remo_path(linkTree)
8.58
import time
from abc import ABC
from typing import List, Any
from collections import deque
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 elementdefpreorder(self):"""Generate a preorder iteratiom of positions in the tree."""ifnot self.is_empty():for p in self._subtree_preorder(self.root()):yield p
def_subtree_preorder(self, p):"""Generate a preorder iteration of positions in subtree rooted at p."""yield p # visit p before its subtreesfor c in self.children(p):# for each child cfor other in self._subtree_preorder(c):# do preorder of c's subtreeyield other # yielding each to our callerdefpositions(self):"""Generate an iteration of the tree's positions."""return self.preorder()# return entire preorder iterationdefpreorder_indent(self, T, p, d):"""
缩进版本
:param T:树
:param p:根节点
:param d:路径
:return:
""""""Print preorder representation of subtree of T rooted at p at depth d."""print(d,str(p.element()))# use depth for indentationfor c in T.children(p):
self.preorder_indent(T, c, d +1)# child depth is d + 1classBinaryTree(Tree, ABC):"""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","_sentinel"def__init__(self, element, parent=None, left=None, right=None):
self._element = element
self._parent = parent
self._left = left
self._right = right
self._sentinel =0classPosition(BinaryTree, ABC):""" An abstraction representing the location of a single element."""def__init__(self, container, node):"""Constructor should not be invoked by yser."""
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 =0defpreorder_next(self, p):print(p.element(), end=' ')for children in self.children(p):
self.preorder_next(children)definorder_next(self, p):if self.left(p)isnotNone:
self.inorder_next(self.left(p))print(p.element(), end=' ')if self.right(p)isnotNone:
self.inorder_next(self.right(p))passdefpostorder_next(self, p):for children in self.children(p):
self.postorder_next(children)print(p.element(), end=' ')defbreadth_first(self, p):
linkqueue = deque()
linkqueue.append(p)whilelen(linkqueue)!=0:
node = linkqueue.popleft()print(node.element(), end=' ')for children in self.children(node):
linkqueue.append(children)defglobal_variable():global stack
stack =[]defdepth_route(Tree, p, d):"""
:param Tree:
:param p:
:return:
"""global stack
linkqueue = deque()
linkqueue.append(p)whilelen(linkqueue)!=0:
node = linkqueue.popleft()
stack.append(node)for children in Tree.children(node):
linkqueue.append(children)defRemo_path(linkTree):
global_variable()
depth_route(linkTree, linkTree.root(),0)for node in stack[::-1]:if node._node._left isnotNone:if node._node._left._sentinel ==0:
node._node._sentinel +=1else:
node._node._sentinel += node._node._left._sentinel
node._node._sentinel +=1if node._node._right isnotNone:if node._node._right._sentinel ==0:
node._node._sentinel +=1else:
node._node._sentinel += node._node._right._sentinel
node._node._sentinel +=1if node._node._sentinel <=5:print(node._node._element)deffind_node(Tree, p, target):
linkqueue = deque()
linkqueue.append(p)whilelen(linkqueue)!=0:
node = linkqueue.popleft()if node == target:returnTruefor children in Tree.children(node):
linkqueue.append(children)returnFalsepassdeffind_LCA1(Tree, p, q):"""
以任意一个节点往上开始找,节约时间在于判断左右节点,只遍历没有遍历过的节点。
最大的时间就是树的长度
:param Tree:
:param p:
:param q:
:return:
"""if p == q and p == Tree.root():return p
walk = p
result = find_node(Tree, walk, q)if result:return walk
whileTrue:
parent = Tree.parent(walk)if parent isNone:breakelse:if Tree.left(parent)== walk:
result = find_node(Tree, Tree.right(parent), q)else:
result = find_node(Tree, Tree.left(parent), q)if result isTrue:return parent
if walk == Tree.root():break
walk = parent
returnNonedeffind_LCA2(Tree, p, q):"""
使用栈,时间复杂度为n,但是比第一个方法更快,最多的时间即两个节点的深度。
:param Tree:
:param p:
:param q:
:return:
"""
stack1 =[]
stack2 =[]while p isnotNone:
stack1.append(p)
p = Tree.parent(p)while q isnotNone:
stack2.append(q)
q = Tree.parent(q)whilelen(stack1)!=0andlen(stack2)!=0:
p, q = stack1.pop(), stack2.pop()if p == q and stack1[-1]!= stack2[-1]:return p
passif __name__ =="__main__":
linkTree = LinkedBinaryTree()
linkTree._add_root(1)
linkTree._add_left(linkTree.root(),2)
linkTree._add_right(linkTree.root(),3)
linkTree._add_left(linkTree.left(linkTree.root()),4)
linkTree._add_right(linkTree.left(linkTree.root()),5)
linkTree._add_left(linkTree.right(linkTree.root()),6)
linkTree._add_right(linkTree.right(linkTree.root()),7)
linkTree._add_left(linkTree.left(linkTree.left(linkTree.root())),8)
linkTree._add_right(linkTree.left(linkTree.left(linkTree.root())),9)
linkTree._add_left(linkTree.right(linkTree.left(linkTree.root())),10)
linkTree._add_right(linkTree.right(linkTree.left(linkTree.root())),11)
linkTree._add_left(linkTree.left(linkTree.right(linkTree.root())),12)
linkTree._add_right(linkTree.left(linkTree.right(linkTree.root())),13)
linkTree._add_left(linkTree.right(linkTree.right(linkTree.root())),14)
linkTree._add_right(linkTree.right(linkTree.right(linkTree.root())),15)
time1 = time.time()
result1 = find_LCA1(linkTree, linkTree.left(linkTree.left(linkTree.left(linkTree.root()))),
linkTree.right(linkTree.right(linkTree.right(linkTree.root()))))# 稍复杂print(result1.element()if result1 isnotNoneelseNone)
time2 = time.time()print(f'方法一花费时间{time1 - time2}s')
result2 = find_LCA2(linkTree, linkTree.left(linkTree.left(linkTree.left(linkTree.root()))),
linkTree.right(linkTree.right(linkTree.right(linkTree.root()))))# 用栈简单好理解。print(result2.element())print(f'方法二花费时间{time.time() - time2}s')
8.59
import time
from abc import ABC
from typing import List, Any
from collections import deque
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 elementdefpreorder(self):"""Generate a preorder iteratiom of positions in the tree."""ifnot self.is_empty():for p in self._subtree_preorder(self.root()):yield p
def_subtree_preorder(self, p):"""Generate a preorder iteration of positions in subtree rooted at p."""yield p # visit p before its subtreesfor c in self.children(p):# for each child cfor other in self._subtree_preorder(c):# do preorder of c's subtreeyield other # yielding each to our callerdefpositions(self):"""Generate an iteration of the tree's positions."""return self.preorder()# return entire preorder iterationdefpreorder_indent(self, T, p, d):"""
缩进版本
:param T:树
:param p:根节点
:param d:路径
:return:
""""""Print preorder representation of subtree of T rooted at p at depth d."""print(d,str(p.element()))# use depth for indentationfor c in T.children(p):
self.preorder_indent(T, c, d +1)# child depth is d + 1classBinaryTree(Tree, ABC):"""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","_sentinel"def__init__(self, element, parent=None, left=None, right=None):
self._element = element
self._parent = parent
self._left = left
self._right = right
self._sentinel =0classPosition(BinaryTree, ABC):""" An abstraction representing the location of a single element."""def__init__(self, container, node):"""Constructor should not be invoked by yser."""
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 =0defpreorder_next(self, p):print(p.element(), end=' ')for children in self.children(p):
self.preorder_next(children)definorder_next(self, p):if self.left(p)isnotNone:
self.inorder_next(self.left(p))print(p.element(), end=' ')if self.right(p)isnotNone:
self.inorder_next(self.right(p))passdefpostorder_next(self, p):for children in self.children(p):
self.postorder_next(children)print(p.element(), end=' ')defbreadth_first(self, p):
linkqueue = deque()
linkqueue.append(p)whilelen(linkqueue)!=0:
node = linkqueue.popleft()print(node.element(), end=' ')for children in self.children(node):
linkqueue.append(children)defglobal_variable():global stack
stack =[]defdepth_route(Tree, p, d):"""
:param Tree:
:param p:
:return:
"""global stack
linkqueue = deque()
linkqueue.append(p)whilelen(linkqueue)!=0:
node = linkqueue.popleft()
stack.append(node)for children in Tree.children(node):
linkqueue.append(children)defRemo_path(linkTree):
global_variable()
depth_route(linkTree, linkTree.root(),0)for node in stack[::-1]:if node._node._left isnotNone:if node._node._left._sentinel ==0:
node._node._sentinel +=1else:
node._node._sentinel += node._node._left._sentinel
node._node._sentinel +=1if node._node._right isnotNone:if node._node._right._sentinel ==0:
node._node._sentinel +=1else:
node._node._sentinel += node._node._right._sentinel
node._node._sentinel +=1if node._node._sentinel <=5:print(node._node._element)deffind_node(Tree, p, target):
linkqueue = deque()
linkqueue.append(p)whilelen(linkqueue)!=0:
node = linkqueue.popleft()if node == target:returnTruefor children in Tree.children(node):
linkqueue.append(children)returnFalsepassdeffind_LCA1(Tree, p, q):"""
以任意一个节点往上开始找,节约时间在于判断左右节点,只遍历没有遍历过的节点。
最大的时间就是树的长度
:param Tree:
:param p:
:param q:
:return:
"""if p == q and p == Tree.root():return p
walk = p
result = find_node(Tree, walk, q)if result:return walk
whileTrue:
parent = Tree.parent(walk)if parent isNone:breakelse:if Tree.left(parent)== walk:
result = find_node(Tree, Tree.right(parent), q)else:
result = find_node(Tree, Tree.left(parent), q)if result isTrue:return parent
if walk == Tree.root():break
walk = parent
returnNonedeffind_LCA2(Tree, p, q):"""
使用栈,时间复杂度为n,但是比第一个方法更快,最多的时间即两个节点的深度。
:param Tree:
:param p:
:param q:
:return:
"""
stack1 =[]
stack2 =[]while p isnotNone:
stack1.append(p)
p = Tree.parent(p)while q isnotNone:
stack2.append(q)
q = Tree.parent(q)whilelen(stack1)!=0andlen(stack2)!=0:
p, q = stack1.pop(), stack2.pop()if p == q and stack1[-1]!= stack2[-1]:return p
defvariable():global diameter
diameter =0defdiameterBinaryTree(Tree, p):global diameter
if p isNone:return0
diameter_left = diameterBinaryTree(Tree, Tree.left(p))
diameter_right = diameterBinaryTree(Tree, Tree.right(p))if Tree.left(p)isnotNoneand Tree.right(p)isnotNone:
ancestor = find_LCA2(Tree,Tree.left(p), Tree.right(p))
depth_ancestor = Tree.depth(ancestor)
diameter =max(diameter_left + diameter_right -2* depth_ancestor, diameter)returnmax(diameter_left, diameter_right)+1if __name__ =="__main__":
linkTree = LinkedBinaryTree()
linkTree._add_root(1)
linkTree._add_left(linkTree.root(),2)
linkTree._add_right(linkTree.root(),3)
linkTree._add_left(linkTree.left(linkTree.root()),4)
linkTree._add_right(linkTree.left(linkTree.root()),5)
linkTree._add_left(linkTree.right(linkTree.root()),6)
linkTree._add_right(linkTree.right(linkTree.root()),7)
linkTree._add_left(linkTree.left(linkTree.left(linkTree.root())),8)
linkTree._add_right(linkTree.left(linkTree.left(linkTree.root())),9)
linkTree._add_left(linkTree.right(linkTree.left(linkTree.root())),10)
linkTree._add_right(linkTree.right(linkTree.left(linkTree.root())),11)
linkTree._add_left(linkTree.left(linkTree.right(linkTree.root())),12)
linkTree._add_right(linkTree.left(linkTree.right(linkTree.root())),13)
linkTree._add_left(linkTree.right(linkTree.right(linkTree.root())),14)# linkTree._add_right(linkTree.right(linkTree.right(linkTree.root())), 15)
variable()
diameterBinaryTree(linkTree, linkTree.root())print(f"二叉树的直径为: {diameter}")print(linkTree.depth(linkTree.left(linkTree.left(linkTree.left(linkTree.root())))))
8.46from typing import List, Anyclass Tree: """Abstract base class representing a tree structure.""" # ----------------------------nested Position class ----------------------------- class Position: """An abstraction representing t