再次更新
8.5
class Tree:
"""Abstract base class representing a tree structure."""
# ----------------------------nested Position class -----------------------------
class Position:
"""An abstraction representing the location of a single element."""
def element(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."""
return not (self == other)
# ---------- abstract methods that concrete subclass must support------------
def root(self):
"""Return Position representing the tree's root (or None if empty)."""
raise NotImplementedError("must be implemented by subclass")
def parent(self, p):
"""Return Position representing p's parent """
return NotImplementedError("must be implemented by subclass")
def num_children(self, p):
"""Return the number of children that Position p has."""
raise NotImplementedError("must be implemented by subclass")
def children(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 --------------
def is_root(self, p):
"Return True if Position p represents the root of the tree."
return self.root() == p
def is_leaf(self, p):
"""Return True if Position p does not have any children."""
return self.num_children(p) == 0
def is_empty(self):
"""Return True if the tree is empty."""
return len(self) == 0
def depth(self, p):
"""Return the number of levels separating Position p from the root."""
if self.is_root(p):
return 0
else:
return 1 + self.depth(self.parent(p))
# 定义 树的高度等于所有叶子结点的深度中的最大值
# 时间复杂度为n**2
def _height1(self):
"""Return the height of the tree."""
return max(self.depth(p) for p in self.positions() if self.is_leaf(p))
# 从根节点,自顶向下,效率比height快
# 时间复杂度为n
def _height2(self, p):
if self.is_leaf(p):
return 0
else:
return 1 + max(self._height2(c) for c in self.children(p))
def height(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 is None:
p = self.root()
return self._height2(p) # start_height2 recursion
class BinaryTree(Tree):
"""Abstract base class representing a binary tree structure."""
# -------------------additional abstract methods -------------------------
def left(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")
def right(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 ===========
def sibling(self, p):
"""Return a Position representing p's sibling (or None if no sibling)。"""
parent = self.parent(p)
if parent is None: # p must be the root
return None # root has no sibling
else:
if p == self.left(parent):
return self.right(parent) # possibly None
else:
return self.left(parent) # possibly None
def children(self, p):
"""Generate an iteraiton of Positions representing p's children."""
if self.left(p) is not None:
yield self.left(p)
if self.right(p) is not None:
yield self.right(p)
class LinkedBinaryTree(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
class Position(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
def element(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."""
return type(other) is type(self) and other._node is self._node
def _validate(self, p):
"""Return associated node ,if position is valid."""
if not isinstance(p, self.Position):
raise TypeError("p must be proper Position type")
if p._container is not self:
raise ValueError("p does not belong to this container")
if p._node._parent is p._node: # convention for deprecated nodes
raise 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 is not None else None
# ------------------------ 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
def root(self):
"""Return the root Position of the tree(or None if tree is empty)"""
return self._make_position(self._root)
def parent(self, p):
node = self._validate(p)
return self._make_position(node._parent)
def left(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)
def right(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)
def num_children(self, p):
"""Return the number of children of Position p."""
node = self._validate(p)
count = 0
if node._left is not None:
count += 1
if node._right is not None:
count += 1
return 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 is not None:
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 is not None:
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 is not None:
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 None
if child is not None:
child._parent = node._parent # child's grandparent becomes parent
if node is self._root:
self._root = child # child becomes root
else:
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)
if not self.is_leaf(p):
raise ValueError('position must be leaf')
if not type(self) is type(t1) is type(t2):
raise TypeError("Tree types must match")
self._size += len(t1) + len(t2)
if not t1.is_empty(): # attached t1 as left subtree of node
t1._root._parent = node
node._left = t1._root
t1._root = None
t1._size = 0
if not t2.is_empty(): # attached t2 as right subtree of node
t2._root._parent = node
node._right = t2._root
t2._root = None
t2._size = 0
pass
def __iter__(self):
"""Generate an iteration of the tree's elements."""
for p in self.positions(): # use same order as positions()
yield p # but yield each element
def preorder(self):
"""Generate a preorder iteratiom of positions in the tree."""
if not 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 subtrees
for c in self.children(p): # for each child c
for other in self._subtree_preorder(c): # do preorder of c's subtree
yield other # yielding each to our caller
def positions(self):
"""Generate an iteration of the tree's positions."""
return self.preorder() # return entire preorder iteration
def count_left_leaf(self):
# return self._leaf_left(self.root())
return self._leaf_left()
def _leaf_left(self):
# 方法二先遍历后寻找叶子结点
count = 0
for node_position in self:
node = self._validate(node_position)
if self.is_leaf(node_position):
parent = node._parent
if parent is None:
count += 1
else:
if parent._left is node:
count += 1
return count
# def _leaf_left(self, p):#方法一自顶向下寻找叶子结点
# node = self._validate(p)
# if self.is_leaf(p):
# parent = node._parent
# if parent is None:
# return 1
# else:
# if parent._left is node:
# return 1
# else:
# return 0
# else:
# return sum(self.leaf_left(node) for node in self.children(p))
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.left(linkTree.root())), 6)
# for leaf in linkTree:
# print(leaf,end = ' ')
print(linkTree.count_left_leaf())
8.10
from abc import ABCMeta
class Tree:
"""Abstract base class representing a tree structure."""
# ----------------------------nested Position class -----------------------------
class Position:
"""An abstraction representing the location of a single element."""
def element(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."""
return not (self == other)
# ---------- abstract methods that concrete subclass must support------------
def root(self):
"""Return Position representing the tree's root (or None if empty)."""
raise NotImplementedError("must be implemented by subclass")
def parent(self, p):
"""Return Position representing p's parent """
return NotImplementedError("must be implemented by subclass")
def num_children(self, p):
"""Return the number of children that Position p has."""
raise NotImplementedError("must be implemented by subclass")
def children(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 --------------
def is_root(self, p):
"Return True if Position p represents the root of the tree."
return self.root() == p
def is_leaf(self, p):
"""Return True if Position p does not have any children."""
return self.num_children(p) == 0
def is_empty(self):
"""Return True if the tree is empty."""
return len(self) == 0
def depth(self, p):
"""Return the number of levels separating Position p from the root."""
if self.is_root(p):
return 0
else:
return 1 + self.depth(self.parent(p))
# 定义 树的高度等于所有叶子结点的深度中的最大值
# 时间复杂度为n**2
def _height1(self):
"""Return the height of the tree."""
return max(self.depth(p) for p in self.positions() if self.is_leaf(p))
# 从根节点,自顶向下,效率比height快
# 时间复杂度为n
def _height2(self, p):
if self.is_leaf(p):
return 0
else:
return 1 + max(self._height2(c) for c in self.children(p))
def height(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 is None:
p = self.root()
return self._height2(p) # start_height2 recursion
class BinaryTree(Tree, metaclass=ABCMeta):
"""Abstract base class representing a binary tree structure."""
# -------------------additional abstract methods -------------------------
def left(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")
def right(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 ===========
def sibling(self, p):
"""Return a Position representing p's sibling (or None if no sibling)。"""
parent = self.parent(p)
if parent is None: # p must be the root
return None # root has no sibling
else:
if p == self.left(parent):
return self.right(parent) # possibly None
else:
return self.left(parent) # possibly None
def children(self, p):
"""Generate an iteraiton of Positions representing p's children."""
if self.left(p) is not None:
yield self.left(p)
if self.right(p) is not None:
yield self.right(p)
def num_children(self, p):
if self.is_leaf(p):
return 1
else:
return 1 + sum(self.num_children(children) for children in self.children(p))
8.15
class Tree:
"""Abstract base class representing a tree structure."""
# ----------------------------nested Position class -----------------------------
class Position:
"""An abstraction representing the location of a single element."""
def element(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."""
return not (self == other)
# ---------- abstract methods that concrete subclass must support------------
def root(self):
"""Return Position representing the tree's root (or None if empty)."""
raise NotImplementedError("must be implemented by subclass")
def parent(self, p):
"""Return Position representing p's parent """
return NotImplementedError("must be implemented by subclass")
def num_children(self, p):
"""Return the number of children that Position p has."""
raise NotImplementedError("must be implemented by subclass")
def children(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 --------------
def is_root(self, p):
"Return True if Position p represents the root of the tree."
return self.root() == p
def is_leaf(self, p):
"""Return True if Position p does not have any children."""
return self.num_children(p) == 0
def is_empty(self):
"""Return True if the tree is empty."""
return len(self) == 0
def depth(self, p):
"""Return the number of levels separating Position p from the root."""
if self.is_root(p):
return 0
else:
return 1 + self.depth(self.parent(p))
# 定义 树的高度等于所有叶子结点的深度中的最大值
# 时间复杂度为n**2
def _height1(self):
"""Return the height of the tree."""
return max(self.depth(p) for p in self.positions() if self.is_leaf(p))
# 从根节点,自顶向下,效率比height快
# 时间复杂度为n
def _height2(self, p):
if self.is_leaf(p):
return 0
else:
return 1 + max(self._height2(c) for c in self.children(p))
def height(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 is None:
p = self.root()
return self._height2(p) # start_height2 recursion
class BinaryTree(Tree):
"""Abstract base class representing a binary tree structure."""
# -------------------additional abstract methods -------------------------
def left(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")
def right(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 ===========
def sibling(self, p):
"""Return a Position representing p's sibling (or None if no sibling)。"""
parent = self.parent(p)
if parent is None: # p must be the root
return None # root has no sibling
else:
if p == self.left(parent):
return self.right(parent) # possibly None
else:
return self.left(parent) # possibly None
def children(self, p):
"""Generate an iteraiton of Positions representing p's children."""
if self.left(p) is not None:
yield self.left(p)
if self.right(p) is not None:
yield self.right(p)
class LinkedBinaryTree(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
class Position(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
def element(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."""
return type(other) is type(self) and other._node is self._node
def _validate(self, p):
"""Return associated node ,if position is valid."""
if not isinstance(p, self.Position):
raise TypeError("p must be proper Position type")
if p._container is not self:
raise ValueError("p does not belong to this container")
if p._node._parent is p._node: # convention for deprecated nodes
raise 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 is not None else None
# ------------------------ 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
def root(self):
"""Return the root Position of the tree(or None if tree is empty)"""
return self._make_position(self._root)
def parent(self, p):
node = self._validate(p)
return self._make_position(node._parent)
def left(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)
def right(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)
def num_children(self, p):
"""Return the number of children of Position p."""
node = self._validate(p)
count = 0
if node._left is not None:
count += 1
if node._right is not None:
count += 1
return 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 is not None:
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 is not None:
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 is not None:
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 None
if child is not None:
child._parent = node._parent # child's grandparent becomes parent
if node is self._root:
self._root = child # child becomes root
else:
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)
if not self.is_leaf(p):
raise ValueError('position must be leaf')
if not type(self) is type(t1) is type(t2):
raise TypeError("Tree types must match")
self._size += len(t1) + len(t2)
if not t1.is_empty(): # attached t1 as left subtree of node
t1._root._parent = node
node._left = t1._root
t1._root = None
t1._size = 0
if not t2.is_empty(): # attached t2 as right subtree of node
t2._root._parent = node
node._right = t2._root
t2._root = None
t2._size = 0
pass
class MutableLinkBinaryTree(LinkedBinaryTree):
def add_root(self, e):
return self._add_root(e)
def add_left(self, p, e):
return self._add_left(p, e)
def add_right(self, p, e):
return self._add_right(p, e)
def replace(self, p, e):
return self._replace(p, e)
def delete(self, p):
return self._delete(p)
def attach(self, p, t1, t2):
self._attach(p, t1, t2)
8.18
class Empty(Exception):
pass
class Tree:
"""Abstract base class representing a tree structure."""
# ----------------------------nested Position class -----------------------------
class Position:
"""An abstraction representing the location of a single element."""
def element(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."""
return not (self == other)
# ---------- abstract methods that concrete subclass must support------------
def root(self):
"""Return Position representing the tree's root (or None if empty)."""
raise NotImplementedError("must be implemented by subclass")
def parent(self, p):
"""Return Position representing p's parent """
return NotImplementedError("must be implemented by subclass")
def num_children(self, p):
"""Return the number of children that Position p has."""
raise NotImplementedError("must be implemented by subclass")
def children(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 --------------
def is_root(self, p):
"Return True if Position p represents the root of the tree."
return self.root() == p
def is_leaf(self, p):
"""Return True if Position p does not have any children."""
return self.num_children(p) == 0
def is_empty(self):
"""Return True if the tree is empty."""
return len(self) == 0
def depth(self, p):
"""Return the number of levels separating Position p from the root."""
if self.is_root(p):
return 0
else:
return 1 + self.depth(self.parent(p))
# 定义 树的高度等于所有叶子结点的深度中的最大值
# 时间复杂度为n**2
def _height1(self):
"""Return the height of the tree."""
return max(self.depth(p) for p in self.positions() if self.is_leaf(p))
# 从根节点,自顶向下,效率比height快
# 时间复杂度为n
def _height2(self, p):
if self.is_leaf(p):
return 0
else:
return 1 + max(self._height2(c) for c in self.children(p))
def height(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 is None:
p = self.root()
return self._height2(p) # start_height2 recursion
class BinaryTree(Tree):
"""Abstract base class representing a binary tree structure."""
# -------------------additional abstract methods -------------------------
def left(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")
def right(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 ===========
def sibling(self, p):
"""Return a Position representing p's sibling (or None if no sibling)。"""
parent = self.parent(p)
if parent is None: # p must be the root
return None # root has no sibling
else:
if p == self.left(parent):
return self.right(parent) # possibly None
else:
return self.left(parent) # possibly None
def children(self, p):
"""Generate an iteraiton of Positions representing p's children."""
if self.left(p) is not None:
yield self.left(p)
if self.right(p) is not None:
yield self.right(p)
class LinkedBinaryTree(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
class Position(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
def element(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."""
return type(other) is type(self) and other._node is self._node
def _validata(self, p):
"""Return associated node ,if position is valid."""
if not isinstance(p, self.Position):
raise TypeError("p must be proper Position type")
if p._container is not self:
raise ValueError("p does not belong to this container")
if p._node._parent is p._node: # convention for deprecated nodes
raise 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 is not None else None
# ------------------------ 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
def root(self):
"""Return the root Position of the tree(or None if tree is empty)"""
return self._make_position(self._root)
def parent(self, p):
node = self._validata(p)
return self._make_position(node._parent)
def left(self, p):
"""Return the Position of p's left child (or None if no left child)."""
node = self._validata(p)
return self._make_position(node._left)
def right(self, p):
"""Return the Position of p's right child (or None if no right child)."""
node = self._validata(p)
return self._make_position(node._right)
def num_children(self, p):
"""Return the number of children of Position p."""
node = self._validata(p)
count = 0
if node._left is not None:
count += 1
if node._right is not None:
count += 1
return 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 is not None:
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._validata(p)
if node._left is not None:
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._validata(p)
if node._right is not None:
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._validata(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._validata(p)
if self.num_children(p) == 2:
raise ValueError("p has two children")
child = node._left if node._left else node._right # might be None
if child is not None:
child._parent = node._parent # child's grandparent becomes parent
if node is self._root:
self._root = child # child becomes root
else:
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._validata(p)
if not self.is_leaf(p):
raise ValueError('position must be leaf')
if not type(self) is type(t1) is type(t2):
raise TypeError("Tree types must match")
self._size += len(t1) + len(t2)
if not t1.is_empty(): # attached t1 as left subtree of node
t1._root._parent = node
node._left = t1._root
t1._root = None
t1._size = 0
if not t2.is_empty(): # attached t2 as right subtree of node
t2._root._parent = node
node._right = t2._root
t2._root = None
t2._size = 0
pass
class MutableLinkBinaryTree(LinkedBinaryTree):
def add_root(self, e):
return self._add_root(e)
def add_left(self, p, e):
return self._add_left(p, e)
def add_right(self, p, e):
return self._add_right(p, e)
def replace(self, p, e):
return self._replace(p, e)
def delete(self, p):
return self._delete(p)
def attach(self, p, t1, t2):
self._attach(p, t1, t2)
class ArrayBinaryTree(BinaryTree):
def __init__(self):
self._array = [None]
def __getitem__(self, item):
temp = self._array[1:]
if 0 <= item < len(temp):
return temp[item]
elif -1 * len(temp) <= item < 0:
return temp[item]
else:
raise IndexError
def element(self):
return self._array[1:]
def root(self):
return 1
def parent(self, p):
index = int(p / 2)
if index <= 0:
return None
return index
def left(self, p):
index = 2 * p
if index > len(self._array):
return None
return index
def right(self, p):
index = 2 * p + 1
if index > len(self._array):
return None
return index
def add_root(self, p):
if len(self._array) == 1:
self._array = self._array[:1] + [p] + self._array[2:]
else:
raise ValueError
def add_left(self, p, e):
if len(self._array) == 1:
raise IndexError
else:
self._array = self._array[:2 * p] + [e] + self._array[2 * p + 1:]
def add_right(self, p, e):
if len(self._array) == 1:
raise IndexError
else:
self._array = self._array[:2 * p + 1] + [e] + self._array[2 * p + 2:]
def is_leaf(self, p):
if 2*p > len(self._array) and 2*p+1 > len(self._array):
return True
return False
def is_root(self, p):
if p == self.root():
return True
return False
pass
if __name__ == '__main__':
arrayTree = ArrayBinaryTree()
arrayTree.add_root(1)
arrayTree.add_left(arrayTree.root(), 2)
arrayTree.add_right(arrayTree.root(), 3)
arrayTree.add_right(arrayTree.left(arrayTree.root()), 5)
print(arrayTree.is_leaf(arrayTree.right(arrayTree.left(arrayTree.root()))))
print(arrayTree.element())
8.26
class Empty(Exception):
pass
class Tree:
"""Abstract base class representing a tree structure."""
# ----------------------------nested Position class -----------------------------
class Position:
"""An abstraction representing the location of a single element."""
def element(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."""
return not (self == other)
# ---------- abstract methods that concrete subclass must support------------
def root(self):
"""Return Position representing the tree's root (or None if empty)."""
raise NotImplementedError("must be implemented by subclass")
def parent(self, p):
"""Return Position representing p's parent """
return NotImplementedError("must be implemented by subclass")
def num_children(self, p):
"""Return the number of children that Position p has."""
raise NotImplementedError("must be implemented by subclass")
def children(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 --------------
def is_root(self, p):
"Return True if Position p represents the root of the tree."
return self.root() == p
def is_leaf(self, p):
"""Return True if Position p does not have any children."""
return self.num_children(p) == 0
def is_empty(self):
"""Return True if the tree is empty."""
return len(self) == 0
def depth(self, p):
"""Return the number of levels separating Position p from the root."""
if self.is_root(p):
return 0
else:
return 1 + self.depth(self.parent(p))
# 定义 树的高度等于所有叶子结点的深度中的最大值
# 时间复杂度为n**2
def _height1(self):
"""Return the height of the tree."""
return max(self.depth(p) for p in self.positions() if self.is_leaf(p))
# 从根节点,自顶向下,效率比height快
# 时间复杂度为n
def _height2(self, p):
if self.is_leaf(p):
return 0
else:
return 1 + max(self._height2(c) for c in self.children(p))
def height(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 is None:
p = self.root()
return self._height2(p) # start_height2 recursion
class BinaryTree(Tree):
"""Abstract base class representing a binary tree structure."""
# -------------------additional abstract methods -------------------------
def left(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")
def right(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 ===========
def sibling(self, p):
"""Return a Position representing p's sibling (or None if no sibling)。"""
parent = self.parent(p)
if parent is None: # p must be the root
return None # root has no sibling
else:
if p == self.left(parent):
return self.right(parent) # possibly None
else:
return self.left(parent) # possibly None
def children(self, p):
"""Generate an iteraiton of Positions representing p's children."""
if self.left(p) is not None:
yield self.left(p)
if self.right(p) is not None:
yield self.right(p)
class LinkedBinaryTree(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
class Position(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
def element(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."""
return type(other) is type(self) and other._node is self._node
def _validata(self, p):
"""Return associated node ,if position is valid."""
if not isinstance(p, self.Position):
raise TypeError("p must be proper Position type")
if p._container is not self:
raise ValueError("p does not belong to this container")
if p._node._parent is p._node: # convention for deprecated nodes
raise 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 is not None else None
# ------------------------ 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
def root(self):
"""Return the root Position of the tree(or None if tree is empty)"""
return self._make_position(self._root)
def parent(self, p):
node = self._validata(p)
return self._make_position(node._parent)
def left(self, p):
"""Return the Position of p's left child (or None if no left child)."""
node = self._validata(p)
return self._make_position(node._left)
def right(self, p):
"""Return the Position of p's right child (or None if no right child)."""
node = self._validata(p)
return self._make_position(node._right)
def num_children(self, p):
"""Return the number of children of Position p."""
node = self._validata(p)
count = 0
if node._left is not None:
count += 1
if node._right is not None:
count += 1
return 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 is not None:
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._validata(p)
if node._left is not None:
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._validata(p)
if node._right is not None:
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._validata(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._validata(p)
if self.num_children(p) == 2:
raise ValueError("p has two children")
child = node._left if node._left else node._right # might be None
if child is not None:
child._parent = node._parent # child's grandparent becomes parent
if node is self._root:
self._root = child # child becomes root
else:
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._validata(p)
if not self.is_leaf(p):
raise ValueError('position must be leaf')
if not type(self) is type(t1) is type(t2):
raise TypeError("Tree types must match")
self._size += len(t1) + len(t2)
if not t1.is_empty(): # attached t1 as left subtree of node
t1._root._parent = node
node._left = t1._root
t1._root = None
t1._size = 0
if not t2.is_empty(): # attached t2 as right subtree of node
t2._root._parent = node
node._right = t2._root
t2._root = None
t2._size = 0
pass
class MutableLinkBinaryTree(LinkedBinaryTree):
def add_root(self, e):
return self._add_root(e)
def add_left(self, p, e):
return self._add_left(p, e)
def add_right(self, p, e):
return self._add_right(p, e)
def replace(self, p, e):
return self._replace(p, e)
def delete(self, p):
return self._delete(p)
def attach(self, p, t1, t2):
self._attach(p, t1, t2)
class ArrayBinaryTree(BinaryTree):
def __init__(self):
self._array = [None]
def __getitem__(self, item):
temp = self._array[1:]
if 0 <= item < len(temp):
return temp[item]
elif -1 * len(temp) <= item < 0:
return temp[item]
else:
raise IndexError
def element(self):
return self._array[1:]
def root(self):
return 1
def parent(self, p):
index = int(p / 2)
if index <= 0:
return None
return index
def left(self, p):
index = 2 * p
if index > len(self._array):
return None
return index
def right(self, p):
index = 2 * p + 1
if index > len(self._array):
return None
return index
def add_root(self, p):
if len(self._array) == 1:
self._array = self._array[:1] + [p] + self._array[2:]
else:
raise ValueError
def add_left(self, p, e):
if len(self._array) == 1:
raise IndexError
else:
self._array = self._array[:2 * p] + [e] + self._array[2 * p + 1:]
def add_right(self, p, e):
if len(self._array) == 1:
raise IndexError
else:
self._array = self._array[:2 * p + 1] + [e] + self._array[2 * p + 2:]
def is_leaf(self, p):
if 2*p > len(self._array) and 2*p+1 > len(self._array):
return True
return False
def is_root(self, p):
if p == self.root():
return True
return False
pass
if __name__ == '__main__':
arrayTree = ArrayBinaryTree()
arrayTree.add_root(1)
arrayTree.add_left(arrayTree.root(), 2)
arrayTree.add_right(arrayTree.root(), 3)
arrayTree.add_right(arrayTree.left(arrayTree.root()), 5)
print(arrayTree.is_leaf(arrayTree.right(arrayTree.left(arrayTree.root()))))
print(arrayTree.element())
8.27
class Empty(Exception):
pass
class LinkQueue:
"""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 usage
def __init__(self, element, next): # initialize node's fields
self._element = element # reference to user's element
self._next = next # reference to next node
def __init__(self):
"""Create an empty queue."""
self._head = None
self._tail = None
self._size = 0 # number of queue elements
def __len__(self):
"""Return the number of elements in the queue."""
return self._size
def is_empty(self):
"""Return True if the queue is emtpy."""
return self._size == 0
def first(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
def dequeue(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 -= 1
if self.is_empty(): # special case as queue is empty
self._tail = None # remove head had been the tail
return answer
def enqueue(self, item):
"""Add an element to the back of queue."""
newest = self._Node(item, None) # node will be new tail node
if self.is_empty():
self._head = newest # special case : perviously empty
else:
self._tail._next = newest
self._tail = newest # update reference to tail node
self._size += 1
class Tree:
"""Abstract base class representing a tree structure."""
# ----------------------------nested Position class -----------------------------
class Position:
"""An abstraction representing the location of a single element."""
def element(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."""
return not (self == other)
# ---------- abstract methods that concrete subclass must support------------
def root(self):
"""Return Position representing the tree's root (or None if empty)."""
raise NotImplementedError("must be implemented by subclass")
def parent(self, p):
"""Return Position representing p's parent """
return NotImplementedError("must be implemented by subclass")
def num_children(self, p):
"""Return the number of children that Position p has."""
raise NotImplementedError("must be implemented by subclass")
def children(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 --------------
def is_root(self, p):
"Return True if Position p represents the root of the tree."
return self.root() == p
def is_leaf(self, p):
"""Return True if Position p does not have any children."""
return self.num_children(p) == 0
def is_empty(self):
"""Return True if the tree is empty."""
return len(self) == 0
def depth(self, p):
"""Return the number of levels separating Position p from the root."""
if self.is_root(p):
return 0
else:
return 1 + self.depth(self.parent(p))
# 定义 树的高度等于所有叶子结点的深度中的最大值
# 时间复杂度为n**2
def _height1(self):
"""Return the height of the tree."""
return max(self.depth(p) for p in self.positions() if self.is_leaf(p))
# 从根节点,自顶向下,效率比height快
# 时间复杂度为n
def _height2(self, p):
if self.is_leaf(p):
return 0
else:
return 1 + max(self._height2(c) for c in self.children(p))
def height(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 is None:
p = self.root()
return self._height2(p) # start_height2 recursion
def __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 element
def postorder(self):
"""Generate a postorder iteration of positions in the tree."""
if not self.is_empty():
for p in self._subtree_postorder(self.root()): # start recursion
yield p
def _subtree_postorder(self, p):
"""Generate a postorder iteration of position in subtree rooted at p."""
for c in self.children(p): # for each child c
for other in self._subtree_postorder(c): # do postorder of c's subtree
yield other # yielding each to our caller
yield p # visit p after its subtrees
def positions(self):
"""Generate an iteration of the tree's positions."""
return self.breadthfirst() # return entire preorder iteration
def breadthfirst(self):
"""Generate a breadth-first iteration of the positions of thr tree."""
if self.is_empty():
raise Empty("tree is None")
else:
queue = LinkQueue()
queue.enqueue(self.root())
while len(queue) != 0:
node = queue.dequeue()
yield node
for children in self.children(node):
queue.enqueue(children)
class BinaryTree(Tree):
"""Abstract base class representing a binary tree structure."""
# -------------------additional abstract methods -------------------------
def left(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")
def right(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 ===========
def sibling(self, p):
"""Return a Position representing p's sibling (or None if no sibling)。"""
parent = self.parent(p)
if parent is None: # p must be the root
return None # root has no sibling
else:
if p == self.left(parent):
return self.right(parent) # possibly None
else:
return self.left(parent) # possibly None
def children(self, p):
"""Generate an iteraiton of Positions representing p's children."""
if self.left(p) is not None:
yield self.left(p)
if self.right(p) is not None:
yield self.right(p)
class LinkedBinaryTree(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
class Position(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
def element(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."""
return type(other) is type(self) and other._node is self._node
def _validate(self, p):
"""Return associated node ,if position is valid."""
if not isinstance(p, self.Position):
raise TypeError("p must be proper Position type")
if p._container is not self:
raise ValueError("p does not belong to this container")
if p._node._parent is p._node: # convention for deprecated nodes
raise 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 is not None else None
# ------------------------ 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
def root(self):
"""Return the root Position of the tree(or None if tree is empty)"""
return self._make_position(self._root)
def parent(self, p):
node = self._validate(p)
return self._make_position(node._parent)
def left(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)
def right(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)
def num_children(self, p):
"""Return the number of children of Position p."""
node = self._validate(p)
count = 0
if node._left is not None:
count += 1
if node._right is not None:
count += 1
return 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 is not None:
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 is not None:
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 is not None:
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 None
if child is not None:
child._parent = node._parent # child's grandparent becomes parent
if node is self._root:
self._root = child # child becomes root
else:
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)
if not self.is_leaf(p):
raise ValueError('position must be leaf')
if not type(self) is type(t1) is type(t2):
raise TypeError("Tree types must match")
self._size += len(t1) + len(t2)
if not t1.is_empty(): # attached t1 as left subtree of node
t1._root._parent = node
node._left = t1._root
t1._root = None
t1._size = 0
if not t2.is_empty(): # attached t2 as right subtree of node
t2._root._parent = node
node._right = t2._root
t2._root = None
t2._size = 0
pass
def parenthesize(T, start):
if T.is_empty() and start is None:
raise Empty("tree is None")
else:
linkqueue = LinkQueue()
linkqueue.enqueue(start)
depth = T.height() - T.depth(start)
if depth == 0:
return None
else:
i = 0
while i <= depth:
temp = LinkQueue()
while len(linkqueue) != 0:
leaf = linkqueue.dequeue()
print(leaf.element(), end=' ')
for children in T.children(leaf):
temp.enqueue(children)
print()
while len(temp) != 0:
linkqueue.enqueue(temp.dequeue())
i += 1
pass
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=' ')
parenthesize(linkTree, linkTree.root())
pass
8.30
import re
class Tree:
"""Abstract base class representing a tree structure."""
# ----------------------------nested Position class -----------------------------
class Position:
"""An abstraction representing the location of a single element."""
def element(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."""
return not (self == other)
# ---------- abstract methods that concrete subclass must support------------
def root(self):
"""Return Position representing the tree's root (or None if empty)."""
raise NotImplementedError("must be implemented by subclass")
def parent(self, p):
"""Return Position representing p's parent """
return NotImplementedError("must be implemented by subclass")
def num_children(self, p):
"""Return the number of children that Position p has."""
raise NotImplementedError("must be implemented by subclass")
def children(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 --------------
def is_root(self, p):
"Return True if Position p represents the root of the tree."
return self.root() == p
def is_leaf(self, p):
"""Return True if Position p does not have any children."""
return self.num_children(p) == 0
def is_empty(self):
"""Return True if the tree is empty."""
return len(self) == 0
def depth(self, p):
"""Return the number of levels separating Position p from the root."""
if self.is_root(p):
return 0
else:
return 1 + self.depth(self.parent(p))
# 定义 树的高度等于所有叶子结点的深度中的最大值
# 时间复杂度为n**2
def _height1(self):
"""Return the height of the tree."""
return max(self.depth(p) for p in self.positions() if self.is_leaf(p))
# 从根节点,自顶向下,效率比height快
# 时间复杂度为n
def _height2(self, p):
if self.is_leaf(p):
return 0
else:
return 1 + max(self._height2(c) for c in self.children(p))
def height(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 is None:
p = self.root()
return self._height2(p) # start_height2 recursion
class BinaryTree(Tree):
"""Abstract base class representing a binary tree structure."""
# -------------------additional abstract methods -------------------------
def left(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")
def right(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 ===========
def sibling(self, p):
"""Return a Position representing p's sibling (or None if no sibling)。"""
parent = self.parent(p)
if parent is None: # p must be the root
return None # root has no sibling
else:
if p == self.left(parent):
return self.right(parent) # possibly None
else:
return self.left(parent) # possibly None
def children(self, p):
"""Generate an iteraiton of Positions representing p's children."""
if self.left(p) is not None:
yield self.left(p)
if self.right(p) is not None:
yield self.right(p)
class LinkedBinaryTree(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
class Position(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
def element(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."""
return type(other) is type(self) and other._node is self._node
def _validate(self, p):
"""Return associated node ,if position is valid."""
if not isinstance(p, self.Position):
raise TypeError("p must be proper Position type")
if p._container is not self:
raise ValueError("p does not belong to this container")
if p._node._parent is p._node: # convention for deprecated nodes
raise 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 is not None else None
# ------------------------ 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
def root(self):
"""Return the root Position of the tree(or None if tree is empty)"""
return self._make_position(self._root)
def parent(self, p):
node = self._validate(p)
return self._make_position(node._parent)
def left(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)
def right(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)
def num_children(self, p):
"""Return the number of children of Position p."""
node = self._validate(p)
count = 0
if node._left is not None:
count += 1
if node._right is not None:
count += 1
return 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 is not None:
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 is not None:
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 is not None:
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 None
if child is not None:
child._parent = node._parent # child's grandparent becomes parent
if node is self._root:
self._root = child # child becomes root
else:
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)
if not self.is_leaf(p):
raise ValueError('position must be leaf')
if not type(self) is type(t1) is type(t2):
raise TypeError("Tree types must match")
self._size += len(t1) + len(t2)
if not t1.is_empty(): # attached t1 as left subtree of node
t1._root._parent = node
node._left = t1._root
t1._root = None
t1._size = 0
if not t2.is_empty(): # attached t2 as right subtree of node
t2._root._parent = node
node._right = t2._root
t2._root = None
t2._size = 0
pass
class ExpressionTree(LinkedBinaryTree):
"""An arithmetic expression tree."""
def __init__(self, token, left=None, right=None):
"""Create an expression tree.
In a single parameter form,token should be a leaf value
and the expression tree will have that value at an isolated node.
In a three-parameter version , token should be an operator,
and left and right should be existing ExpressionTree instances
that become the operands for the binary operator.
"""
super().__init__()
if not isinstance(token, str):
raise TypeError("Token must be a string")
self._add_root(token) # use inherited,nonpublic method
if left is not None:
if token not in '+-*/':
raise ValueError("token must be valid operator")
self._attach(self.root(), left, right)
def __str__(self):
"""Return string representation of th eexpression."""
pieces = [] # sequence of piecewise strings to compose
self._parenthesize_recur(self.root(), pieces)
return " ".join(pieces)
def _parenthesize_recur(self, p, result):
"""Append piecewise representation of p's subtree to resultsing list."""
if self.is_leaf(p):
result.append(str(p.element())) # leaf value as a string
else:
result.append('(') # opening parenthesis
self._parenthesize_recur(self.left(p), result)
result.append(p.element())
self._parenthesize_recur(self.right(p), result)
result.append(')')
def evaluate(self, value={'a': 2, "b": 2}):
"""Return the numeric result of the expression."""
return self._evaluate_recur(self.root(), value)
def _evaluate_recur(self, p, value):
"""Return the numeric result of subtree rooted at p."""
if self.is_leaf(p):
if value is not None:
item = value.get(list(value.keys())[0])
del value[list(value.keys())[0]]
return float(item)
return float(p.element()) # we assume element is numeric
else:
op = p.element()
left_val = self._evaluate_recur(self.left(p), value)
right_val = self._evaluate_recur(self.right(p), value)
if op == '+':
return left_val + right_val
elif op == '-':
return left_val - right_val
elif op == '/':
return left_val / right_val
else:
return left_val * right_val
def execute(self):
"""Perform the tour and return any result from post visit of root."""
if self.root() is not None:
return self._expression_tree(self.root(), 0, []) # start the recursion
def _expression_tree(self, p, d, path):
results = [None, None] # will update with results of recursions
# self._hook_previsit(p, d, path)
if self.left(p) is not None:
path.append(0)
self._expression_tree(self.left(p), d + 1, path)
path.pop()
self._hook_invisit(p, d, path)
if self.right(p) is not None:
path.append(1)
self._expression_tree(self.right(p), d + 1, path)
path.pop()
# answer = self._hook_postvisit(p, d, path, results)
# return answer
def _hook_invisit(self, p, d, path):
print(p)
def tokenize(strings):
strings = "".join(strings.split(' ')) # 去除空格
pattern = re.compile(r"\w+|\+|\(|\)|\-|\/|\*")
return re.findall(pattern, strings)
def build_expression_tree(tokens):
"""Returns an Expression Tree based upon by a tokenized expression."""
s = [] # we use Python list as stack
tokens = tokenize(tokens)
for t in tokens:
if t in '+-x*/': # t is an operator symbol
s.append(t) # push the operator symbol
elif t not in '()': # consider t to be a literal
s.append(ExpressionTree(t)) # push trival tree storing value
elif t == ")": # compose a new tree from three constituent parts
right = s.pop() # right subtree as per LIFO
op = s.pop() # operator symbol
left = s.pop() # left subtree
s.append(ExpressionTree(op, left, right))
# we ignore a left parenthesis
return s
if __name__ == "__main__":
result = build_expression_tree("(1+222 2)+2")
print(ExpressionTree('+', ExpressionTree('1'), ExpressionTree('2')).evaluate())
8.38
class Empty(Exception):
pass
class LinkQueue:
"""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 usage
def __init__(self, element, next): # initialize node's fields
self._element = element # reference to user's element
self._next = next # reference to next node
def __init__(self):
"""Create an empty queue."""
self._head = None
self._tail = None
self._size = 0 # number of queue elements
def __len__(self):
"""Return the number of elements in the queue."""
return self._size
def is_empty(self):
"""Return True if the queue is emtpy."""
return self._size == 0
def first(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
def dequeue(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 -= 1
if self.is_empty(): # special case as queue is empty
self._tail = None # remove head had been the tail
return answer
def enqueue(self, item):
"""Add an element to the back of queue."""
newest = self._Node(item, None) # node will be new tail node
if self.is_empty():
self._head = newest # special case : perviously empty
else:
self._tail._next = newest
self._tail = newest # update reference to tail node
self._size += 1
class Tree:
"""Abstract base class representing a tree structure."""
# ----------------------------nested Position class -----------------------------
class Position:
"""An abstraction representing the location of a single element."""
def element(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."""
return not (self == other)
# ---------- abstract methods that concrete subclass must support------------
def root(self):
"""Return Position representing the tree's root (or None if empty)."""
raise NotImplementedError("must be implemented by subclass")
def parent(self, p):
"""Return Position representing p's parent """
return NotImplementedError("must be implemented by subclass")
def num_children(self, p):
"""Return the number of children that Position p has."""
raise NotImplementedError("must be implemented by subclass")
def children(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 --------------
def is_root(self, p):
"Return True if Position p represents the root of the tree."
return self.root() == p
def is_leaf(self, p):
"""Return True if Position p does not have any children."""
return self.num_children(p) == 0
def is_empty(self):
"""Return True if the tree is empty."""
return len(self) == 0
def depth(self, p):
"""Return the number of levels separating Position p from the root."""
if self.is_root(p):
return 0
else:
return 1 + self.depth(self.parent(p))
# 定义 树的高度等于所有叶子结点的深度中的最大值
# 时间复杂度为n**2
def _height1(self):
"""Return the height of the tree."""
return max(self.depth(p) for p in self.positions() if self.is_leaf(p))
# 从根节点,自顶向下,效率比height快
# 时间复杂度为n
def _height2(self, p):
if self.is_leaf(p):
return 0
else:
return 1 + max(self._height2(c) for c in self.children(p))
def height(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 is None:
p = self.root()
return self._height2(p) # start_height2 recursion
def __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 element
def postorder(self):
"""Generate a postorder iteration of positions in the tree."""
if not self.is_empty():
for p in self._subtree_postorder(self.root()): # start recursion
yield p
def _subtree_postorder(self, p):
"""Generate a postorder iteration of position in subtree rooted at p."""
for c in self.children(p): # for each child c
for other in self._subtree_postorder(c): # do postorder of c's subtree
yield other # yielding each to our caller
yield p # visit p after its subtrees
def positions(self):
"""Generate an iteration of the tree's positions."""
return self.breadthfirst() # return entire preorder iteration
def breadthfirst(self):
"""Generate a breadth-first iteration of the positions of thr tree."""
if self.is_empty():
raise Empty("tree is None")
else:
queue = LinkQueue()
queue.enqueue(self.root())
while len(queue) != 0:
node = queue.dequeue()
yield node
for children in self.children(node):
queue.enqueue(children)
class BinaryTree(Tree):
"""Abstract base class representing a binary tree structure."""
# -------------------additional abstract methods -------------------------
def left(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")
def right(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 ===========
def sibling(self, p):
"""Return a Position representing p's sibling (or None if no sibling)。"""
parent = self.parent(p)
if parent is None: # p must be the root
return None # root has no sibling
else:
if p == self.left(parent):
return self.right(parent) # possibly None
else:
return self.left(parent) # possibly None
def children(self, p):
"""Generate an iteraiton of Positions representing p's children."""
if self.left(p) is not None:
yield self.left(p)
if self.right(p) is not None:
yield self.right(p)
class LinkedBinaryTree(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
class Position(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
def element(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."""
return type(other) is type(self) and other._node is self._node
def _validate(self, p):
"""Return associated node ,if position is valid."""
if not isinstance(p, self.Position):
raise TypeError("p must be proper Position type")
if p._container is not self:
raise ValueError("p does not belong to this container")
if p._node._parent is p._node: # convention for deprecated nodes
raise 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 is not None else None
# ------------------------ 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
def root(self):
"""Return the root Position of the tree(or None if tree is empty)"""
return self._make_position(self._root)
def parent(self, p):
node = self._validate(p)
return self._make_position(node._parent)
def left(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)
def right(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)
def num_children(self, p):
"""Return the number of children of Position p."""
node = self._validate(p)
count = 0
if node._left is not None:
count += 1
if node._right is not None:
count += 1
return 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 is not None:
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 is not None:
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 is not None:
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 None
if child is not None:
child._parent = node._parent # child's grandparent becomes parent
if node is self._root:
self._root = child # child becomes root
else:
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)
if not self.is_leaf(p):
raise ValueError('position must be leaf')
if not type(self) is type(t1) is type(t2):
raise TypeError("Tree types must match")
self._size += len(t1) + len(t2)
if not t1.is_empty(): # attached t1 as left subtree of node
t1._root._parent = node
node._left = t1._root
t1._root = None
t1._size = 0
if not t2.is_empty(): # attached t2 as right subtree of node
t2._root._parent = node
node._right = t2._root
t2._root = None
t2._size = 0
pass
def _delete_subtree(self,p):
linkqueue = LinkQueue()
linkqueue.enqueue(p)
while len(linkqueue) !=0:
node = linkqueue.dequeue()
print(node.element(),end=' ')
for children in self.children(node):
linkqueue.enqueue(children)
node._node._parent = node._node._left = node._node._right = node._node._element = None
pass
def parenthesize(T, start):
if T.is_empty() and start is None:
raise Empty("tree is None")
else:
linkqueue = LinkQueue()
linkqueue.enqueue(start)
depth = T.height() - T.depth(start)
if depth == 0:
return None
else:
i = 0
while i <= depth:
temp = LinkQueue()
while len(linkqueue) != 0:
leaf = linkqueue.dequeue()
print(leaf.element(), end=' ')
for children in T.children(leaf):
temp.enqueue(children)
print()
while len(temp) != 0:
linkqueue.enqueue(temp.dequeue())
i += 1
pass
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._delete_subtree(linkTree.left(linkTree.root()))
pass
8.30
class Empty(Exception):
pass
class LinkQueue:
"""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 usage
def __init__(self, element, next): # initialize node's fields
self._element = element # reference to user's element
self._next = next # reference to next node
def __init__(self):
"""Create an empty queue."""
self._head = None
self._tail = None
self._size = 0 # number of queue elements
def __len__(self):
"""Return the number of elements in the queue."""
return self._size
def is_empty(self):
"""Return True if the queue is emtpy."""
return self._size == 0
def first(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
def dequeue(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 -= 1
if self.is_empty(): # special case as queue is empty
self._tail = None # remove head had been the tail
return answer
def enqueue(self, item):
"""Add an element to the back of queue."""
newest = self._Node(item, None) # node will be new tail node
if self.is_empty():
self._head = newest # special case : perviously empty
else:
self._tail._next = newest
self._tail = newest # update reference to tail node
self._size += 1
class Tree:
"""Abstract base class representing a tree structure."""
# ----------------------------nested Position class -----------------------------
class Position:
"""An abstraction representing the location of a single element."""
def element(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."""
return not (self == other)
# ---------- abstract methods that concrete subclass must support------------
def root(self):
"""Return Position representing the tree's root (or None if empty)."""
raise NotImplementedError("must be implemented by subclass")
def parent(self, p):
"""Return Position representing p's parent """
return NotImplementedError("must be implemented by subclass")
def num_children(self, p):
"""Return the number of children that Position p has."""
raise NotImplementedError("must be implemented by subclass")
def children(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 --------------
def is_root(self, p):
"Return True if Position p represents the root of the tree."
return self.root() == p
def is_leaf(self, p):
"""Return True if Position p does not have any children."""
return self.num_children(p) == 0
def is_empty(self):
"""Return True if the tree is empty."""
return len(self) == 0
def depth(self, p):
"""Return the number of levels separating Position p from the root."""
if self.is_root(p):
return 0
else:
return 1 + self.depth(self.parent(p))
# 定义 树的高度等于所有叶子结点的深度中的最大值
# 时间复杂度为n**2
def _height1(self):
"""Return the height of the tree."""
return max(self.depth(p) for p in self.positions() if self.is_leaf(p))
# 从根节点,自顶向下,效率比height快
# 时间复杂度为n
def _height2(self, p):
if self.is_leaf(p):
return 0
else:
return 1 + max(self._height2(c) for c in self.children(p))
def height(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 is None:
p = self.root()
return self._height2(p) # start_height2 recursion
def __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 element
def postorder(self):
"""Generate a postorder iteration of positions in the tree."""
if not self.is_empty():
for p in self._subtree_postorder(self.root()): # start recursion
yield p
def _subtree_postorder(self, p):
"""Generate a postorder iteration of position in subtree rooted at p."""
for c in self.children(p): # for each child c
for other in self._subtree_postorder(c): # do postorder of c's subtree
yield other # yielding each to our caller
yield p # visit p after its subtrees
def positions(self):
"""Generate an iteration of the tree's positions."""
return self.breadthfirst() # return entire preorder iteration
def breadthfirst(self):
"""Generate a breadth-first iteration of the positions of thr tree."""
if self.is_empty():
raise Empty("tree is None")
else:
queue = LinkQueue()
queue.enqueue(self.root())
while len(queue) != 0:
node = queue.dequeue()
yield node
for children in self.children(node):
queue.enqueue(children)
class BinaryTree(Tree):
"""Abstract base class representing a binary tree structure."""
# -------------------additional abstract methods -------------------------
def left(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")
def right(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 ===========
def sibling(self, p):
"""Return a Position representing p's sibling (or None if no sibling)。"""
parent = self.parent(p)
if parent is None: # p must be the root
return None # root has no sibling
else:
if p == self.left(parent):
return self.right(parent) # possibly None
else:
return self.left(parent) # possibly None
def children(self, p):
"""Generate an iteraiton of Positions representing p's children."""
if self.left(p) is not None:
yield self.left(p)
if self.right(p) is not None:
yield self.right(p)
class LinkedBinaryTree(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
class Position(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
def element(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."""
return type(other) is type(self) and other._node is self._node
def _validate(self, p):
"""Return associated node ,if position is valid."""
if not isinstance(p, self.Position):
raise TypeError("p must be proper Position type")
if p._container is not self:
raise ValueError("p does not belong to this container")
if p._node._parent is p._node: # convention for deprecated nodes
raise 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 is not None else None
# ------------------------ 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
def root(self):
"""Return the root Position of the tree(or None if tree is empty)"""
return self._make_position(self._root)
def parent(self, p):
node = self._validate(p)
return self._make_position(node._parent)
def left(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)
def right(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)
def num_children(self, p):
"""Return the number of children of Position p."""
node = self._validate(p)
count = 0
if node._left is not None:
count += 1
if node._right is not None:
count += 1
return 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 is not None:
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 is not None:
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 is not None:
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 None
if child is not None:
child._parent = node._parent # child's grandparent becomes parent
if node is self._root:
self._root = child # child becomes root
else:
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)
if not self.is_leaf(p):
raise ValueError('position must be leaf')
if not type(self) is type(t1) is type(t2):
raise TypeError("Tree types must match")
self._size += len(t1) + len(t2)
if not t1.is_empty(): # attached t1 as left subtree of node
t1._root._parent = node
node._left = t1._root
t1._root = None
t1._size = 0
if not t2.is_empty(): # attached t2 as right subtree of node
t2._root._parent = node
node._right = t2._root
t2._root = None
t2._size = 0
def _delete_subtree(self, p):
linkqueue = LinkQueue()
linkqueue.enqueue(p)
while len(linkqueue) != 0:
node = linkqueue.dequeue()
print(node.element(), end=' ')
for children in self.children(node):
linkqueue.enqueue(children)
node._node._parent = node._node._left = node._node._right = node._node._element = None
def _swap(self, p, q):
node_p = self._validate(p)
node_q = self._validate(q)
node_p_parent = node_p._parent
node_q_parent = node_q._parent
node_p_left = node_p._left
node_p_right = node_p._right
node_q_left = node_q._left
node_q_right = node_q._right
node_p._parent = node_q_parent if node_q_parent != node_p else node_q
node_q._parent = node_p_parent if node_p_parent != node_q else node_p
node_p._left = node_q_left if node_q_left != node_p else node_q
try:
if node_p_left != node_q:
node_p_left._parent = node_q
except Exception:
pass
node_p._right = node_q_right if node_q_right != node_p else node_q
try:
if node_p_right != node_q:
node_p_right._parent = node_q
except Exception:
pass
node_q._left = node_p_left if node_p_left != node_q else node_p
try:
if node_q_left != node_p:
node_q_left._parent = node_p
except Exception:
pass
node_q._right = node_p_right if node_p_right != node_q else node_p
try:
if node_q_right != node_p:
node_q_right._parent = node_p
except Exception:
pass
try:
if node_p_parent is None or node_q_parent is None:
if node_p_parent is None:
if node_q_parent is None:
pass
else:
self._root = node_q
if node_p_left == node_q:
node_q._left = node_p
elif node_p_right == node_q:
node_q._right = node_p
else:
pass
else:
self._root = node_p
if node_q_left == node_p:
node_p._left = node_q
elif node_q_right == node_p:
node_p._right = node_q
else:
pass
try:
if node_p_parent._left is node_p and node_p_parent is not node_q:
node_p_parent._left = node_q
elif node_p_parent._right is node_p and node_p_parent is not node_q:
node_p_parent._right = node_q
else:
pass
except Exception:
pass
try:
if node_q_parent._left is node_q and node_q_parent is not node_p:
node_q_parent._left = node_p
elif node_q_parent._right is node_q:
node_q_parent._right = node_p
else:
pass
except Exception:
pass
except Exception:
pass
def parenthesize(T, start):
if T.is_empty() and start is None:
raise Empty("tree is None")
else:
linkqueue = LinkQueue()
linkqueue.enqueue(start)
depth = T.height() - T.depth(start)
if depth == 0:
return None
else:
i = 0
while i <= depth:
temp = LinkQueue()
while len(linkqueue) != 0:
leaf = linkqueue.dequeue()
print(leaf.element(), end=' ')
for children in T.children(leaf):
temp.enqueue(children)
print()
while len(temp) != 0:
linkqueue.enqueue(temp.dequeue())
i += 1
pass
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._swap(linkTree.root(),linkTree.root())
for tree in linkTree:
print(tree)
pass
8.40
class Empty(Exception):
pass
class LinkQueue:
"""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 usage
def __init__(self, element, next): # initialize node's fields
self._element = element # reference to user's element
self._next = next # reference to next node
def __init__(self):
"""Create an empty queue."""
self._head = None
self._tail = None
self._size = 0 # number of queue elements
def __len__(self):
"""Return the number of elements in the queue."""
return self._size
def is_empty(self):
"""Return True if the queue is emtpy."""
return self._size == 0
def first(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
def dequeue(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 -= 1
if self.is_empty(): # special case as queue is empty
self._tail = None # remove head had been the tail
return answer
def enqueue(self, item):
"""Add an element to the back of queue."""
newest = self._Node(item, None) # node will be new tail node
if self.is_empty():
self._head = newest # special case : perviously empty
else:
self._tail._next = newest
self._tail = newest # update reference to tail node
self._size += 1
class Tree:
"""Abstract base class representing a tree structure."""
# ----------------------------nested Position class -----------------------------
class Position:
"""An abstraction representing the location of a single element."""
def element(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."""
return not (self == other)
# ---------- abstract methods that concrete subclass must support------------
def root(self):
"""Return Position representing the tree's root (or None if empty)."""
raise NotImplementedError("must be implemented by subclass")
def parent(self, p):
"""Return Position representing p's parent """
return NotImplementedError("must be implemented by subclass")
def num_children(self, p):
"""Return the number of children that Position p has."""
raise NotImplementedError("must be implemented by subclass")
def children(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 --------------
def is_root(self, p):
"Return True if Position p represents the root of the tree."
return self.root() == p
def is_leaf(self, p):
"""Return True if Position p does not have any children."""
return self.num_children(p) == 0
def is_empty(self):
"""Return True if the tree is empty."""
return len(self) == 0
def depth(self, p):
"""Return the number of levels separating Position p from the root."""
if self.is_root(p):
return 0
else:
return 1 + self.depth(self.parent(p))
# 定义 树的高度等于所有叶子结点的深度中的最大值
# 时间复杂度为n**2
def _height1(self):
"""Return the height of the tree."""
return max(self.depth(p) for p in self.positions() if self.is_leaf(p))
# 从根节点,自顶向下,效率比height快
# 时间复杂度为n
def _height2(self, p):
if self.is_leaf(p):
return 0
else:
return 1 + max(self._height2(c) for c in self.children(p))
def height(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 is None:
p = self.root()
return self._height2(p) # start_height2 recursion
def __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 element
def postorder(self):
"""Generate a postorder iteration of positions in the tree."""
if not self.is_empty():
for p in self._subtree_postorder(self.root()): # start recursion
yield p
def _subtree_postorder(self, p):
"""Generate a postorder iteration of position in subtree rooted at p."""
for c in self.children(p): # for each child c
for other in self._subtree_postorder(c): # do postorder of c's subtree
yield other # yielding each to our caller
yield p # visit p after its subtrees
def positions(self):
"""Generate an iteration of the tree's positions."""
return self.breadthfirst() # return entire preorder iteration
def breadthfirst(self):
"""Generate a breadth-first iteration of the positions of thr tree."""
if self.is_empty():
raise Empty("tree is None")
else:
queue = LinkQueue()
queue.enqueue(self.root())
while len(queue) != 0:
node = queue.dequeue()
yield node
for children in self.children(node):
queue.enqueue(children)
class BinaryTree(Tree):
"""Abstract base class representing a binary tree structure."""
# -------------------additional abstract methods -------------------------
def left(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")
def right(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 ===========
def sibling(self, p):
"""Return a Position representing p's sibling (or None if no sibling)。"""
parent = self.parent(p)
if parent is None: # p must be the root
return None # root has no sibling
else:
if p == self.left(parent):
return self.right(parent) # possibly None
else:
return self.left(parent) # possibly None
def children(self, p):
"""Generate an iteraiton of Positions representing p's children."""
if self.left(p) is not None:
yield self.left(p)
if self.right(p) is not None:
yield self.right(p)
class LinkedBinaryTree(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
class Position(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
def element(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."""
return type(other) is type(self) and other._node is self._node
def _validate(self, p):
"""Return associated node ,if position is valid."""
if not isinstance(p, self.Position):
raise TypeError("p must be proper Position type")
if p._container is not self:
raise ValueError("p does not belong to this container")
if p._node is self._sentinel: # convention for deprecated nodes
raise 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 is not None else self._sentinel
# ------------------------ binary tree constructor --------------------
def __init__(self):
"""Create an initially empty binary tree."""
self._sentinel = None
self._size = 0
# --------------------public accessors ---------------------
def __len__(self):
"""return the total number of elements in the tree."""
return self._size
def root(self):
"""Return the root Position of the tree(or None if tree is empty)"""
return self._make_position(self._sentinel._left)
def parent(self, p):
node = self._validate(p)
return self._make_position(node._parent)
def left(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)
def right(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)
def num_children(self, p):
"""Return the number of children of Position p."""
node = self._validate(p)
count = 0
if node._left is not self._sentinel:
count += 1
if node._right is not self._sentinel:
count += 1
return count
def children(self, p):
"""Generate an iteraiton of Positions representing p's children."""
if self.left(p) is not self._sentinel:
yield self.left(p)
if self.right(p) is not self._sentinel:
yield self.right(p)
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._sentinel is not None:
raise ValueError("Root exists")
self._size += 1
self._sentinel = self._Node(None)
self._sentinel._left = self._Node(e,self._sentinel)
return self._make_position(self._sentinel._left)
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 is not None:
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 is not None:
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 None
if child is not None:
child._parent = node._parent # child's grandparent becomes parent
if node is self._sentinel._left:
self._sentinel._left = child # child becomes root
else:
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)
if not self.is_leaf(p):
raise ValueError('position must be leaf')
if not type(self) is type(t1) is type(t2):
raise TypeError("Tree types must match")
self._size += len(t1) + len(t2)
if not t1.is_empty(): # attached t1 as left subtree of node
t1._sentinel._left._parent = node
node._left = t1._sentinel._left
t1._sentinel._left = None
t1._size = 0
if not t2.is_empty(): # attached t2 as right subtree of node
t2._sentinel._left._parent = node
node._right = t2._sentinel._left
t2._sentinel = None
t2._size = 0
def _delete_subtree(self, p):
linkqueue = LinkQueue()
linkqueue.enqueue(p)
while len(linkqueue) != 0:
node = linkqueue.dequeue()
print(node.element(), end=' ')
for children in self.children(node):
linkqueue.enqueue(children)
node._node._parent = node._node._left = node._node._right = node._node._element = None
def _swap(self, p, q):
node_p = self._validate(p)
node_q = self._validate(q)
node_p_parent = node_p._parent
node_q_parent = node_q._parent
node_p_left = node_p._left
node_p_right = node_p._right
node_q_left = node_q._left
node_q_right = node_q._right
node_p._parent = node_q_parent if node_q_parent != node_p else node_q
node_q._parent = node_p_parent if node_p_parent != node_q else node_p
node_p._left = node_q_left if node_q_left != node_p else node_q
try:
if node_p_left != node_q:
node_p_left._parent = node_q
except Exception:
pass
node_p._right = node_q_right if node_q_right != node_p else node_q
try:
if node_p_right != node_q:
node_p_right._parent = node_q
except Exception:
pass
node_q._left = node_p_left if node_p_left != node_q else node_p
try:
if node_q_left != node_p:
node_q_left._parent = node_p
except Exception:
pass
node_q._right = node_p_right if node_p_right != node_q else node_p
try:
if node_q_right != node_p:
node_q_right._parent = node_p
except Exception:
pass
try:
if node_p_parent is None or node_q_parent is None:
if node_p_parent is None:
if node_q_parent is None:
pass
else:
self._root = node_q
if node_p_left == node_q:
node_q._left = node_p
else:
node_q._right = node_p
else:
self._root = node_p
if node_q_left == node_p:
node_p._left = node_q
else:
node_p._right = node_q
else:
try:
if node_p_parent._left == node_p:
node_p_parent._left = node_q
else:
node_p_parent._right = node_q
if node_q_parent._left == node_q:
node_q_parent._left = node_p
else:
node_q_parent._right = node_p
except Exception:
pass
except Exception:
pass
def parenthesize(T, start):
if T.is_empty() and start is None:
raise Empty("tree is None")
else:
linkqueue = LinkQueue()
linkqueue.enqueue(start)
depth = T.height() - T.depth(start)
if depth == 0:
return None
else:
i = 0
while i <= depth:
temp = LinkQueue()
while len(linkqueue) != 0:
leaf = linkqueue.dequeue()
print(leaf.element(), end=' ')
for children in T.children(leaf):
temp.enqueue(children)
print()
while len(temp) != 0:
linkqueue.enqueue(temp.dequeue())
i += 1
pass
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._swap(linkTree.root(), linkTree.root())
for tree in linkTree:
print(tree)
pass
8.44
class Empty(Exception):
pass
class LinkQueue:
"""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 usage
def __init__(self, element, next): # initialize node's fields
self._element = element # reference to user's element
self._next = next # reference to next node
def __init__(self):
"""Create an empty queue."""
self._head = None
self._tail = None
self._size = 0 # number of queue elements
def __len__(self):
"""Return the number of elements in the queue."""
return self._size
def is_empty(self):
"""Return True if the queue is emtpy."""
return self._size == 0
def first(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
def dequeue(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 -= 1
if self.is_empty(): # special case as queue is empty
self._tail = None # remove head had been the tail
return answer
def enqueue(self, item):
"""Add an element to the back of queue."""
newest = self._Node(item, None) # node will be new tail node
if self.is_empty():
self._head = newest # special case : perviously empty
else:
self._tail._next = newest
self._tail = newest # update reference to tail node
self._size += 1
class Tree:
"""Abstract base class representing a tree structure."""
# ----------------------------nested Position class -----------------------------
class Position:
"""An abstraction representing the location of a single element."""
def element(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."""
return not (self == other)
# ---------- abstract methods that concrete subclass must support------------
def root(self):
"""Return Position representing the tree's root (or None if empty)."""
raise NotImplementedError("must be implemented by subclass")
def parent(self, p):
"""Return Position representing p's parent """
return NotImplementedError("must be implemented by subclass")
def num_children(self, p):
"""Return the number of children that Position p has."""
raise NotImplementedError("must be implemented by subclass")
def children(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 --------------
def is_root(self, p):
"Return True if Position p represents the root of the tree."
return self.root() == p
def is_leaf(self, p):
"""Return True if Position p does not have any children."""
return self.num_children(p) == 0
def is_empty(self):
"""Return True if the tree is empty."""
return len(self) == 0
def depth(self, p):
"""Return the number of levels separating Position p from the root."""
if self.is_root(p):
return 0
else:
return 1 + self.depth(self.parent(p))
# 定义 树的高度等于所有叶子结点的深度中的最大值
# 时间复杂度为n**2
def _height1(self):
"""Return the height of the tree."""
return max(self.depth(p) for p in self.positions() if self.is_leaf(p))
# 从根节点,自顶向下,效率比height快
# 时间复杂度为n
def _height2(self, p):
if self.is_leaf(p):
return 0
else:
return 1 + max(self._height2(c) for c in self.children(p))
def height(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 is None:
p = self.root()
return self._height2(p) # start_height2 recursion
def __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 element
def postorder(self):
"""Generate a postorder iteration of positions in the tree."""
if not self.is_empty():
for p in self._subtree_postorder(self.root()): # start recursion
yield p
def _subtree_postorder(self, p):
"""Generate a postorder iteration of position in subtree rooted at p."""
for c in self.children(p): # for each child c
for other in self._subtree_postorder(c): # do postorder of c's subtree
yield other # yielding each to our caller
yield p # visit p after its subtrees
def positions(self):
"""Generate an iteration of the tree's positions."""
return self.breadthfirst() # return entire preorder iteration
def breadthfirst(self):
"""Generate a breadth-first iteration of the positions of thr tree."""
if self.is_empty():
raise Empty("tree is None")
else:
queue = LinkQueue()
queue.enqueue(self.root())
while len(queue) != 0:
node = queue.dequeue()
yield node
for children in self.children(node):
queue.enqueue(children)
class BinaryTree(Tree):
"""Abstract base class representing a binary tree structure."""
# -------------------additional abstract methods -------------------------
def left(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")
def right(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 ===========
def sibling(self, p):
"""Return a Position representing p's sibling (or None if no sibling)。"""
parent = self.parent(p)
if parent is None: # p must be the root
return None # root has no sibling
else:
if p == self.left(parent):
return self.right(parent) # possibly None
else:
return self.left(parent) # possibly None
def children(self, p):
"""Generate an iteraiton of Positions representing p's children."""
if self.left(p) is not None:
yield self.left(p)
if self.right(p) is not None:
yield self.right(p)
class LinkedBinaryTree(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
class Position(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
def element(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."""
return type(other) is type(self) and other._node is self._node
def _validate(self, p):
"""Return associated node ,if position is valid."""
if not isinstance(p, self.Position):
raise TypeError("p must be proper Position type")
if p._container is not self:
raise ValueError("p does not belong to this container")
if p._node._parent is p._node: # convention for deprecated nodes
raise 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 is not None else None
# ------------------------ 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
def root(self):
"""Return the root Position of the tree(or None if tree is empty)"""
return self._make_position(self._root)
def parent(self, p):
node = self._validate(p)
return self._make_position(node._parent)
def left(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)
def right(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)
def num_children(self, p):
"""Return the number of children of Position p."""
node = self._validate(p)
count = 0
if node._left is not None:
count += 1
if node._right is not None:
count += 1
return 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 is not None:
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 is not None:
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 is not None:
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 None
if child is not None:
child._parent = node._parent # child's grandparent becomes parent
if node is self._root:
self._root = child # child becomes root
else:
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)
if not self.is_leaf(p):
raise ValueError('position must be leaf')
if not type(self) is type(t1) is type(t2):
raise TypeError("Tree types must match")
self._size += len(t1) + len(t2)
if not t1.is_empty(): # attached t1 as left subtree of node
t1._root._parent = node
node._left = t1._root
t1._root = None
t1._size = 0
if not t2.is_empty(): # attached t2 as right subtree of node
t2._root._parent = node
node._right = t2._root
t2._root = None
t2._size = 0
def _delete_subtree(self, p):
linkqueue = LinkQueue()
linkqueue.enqueue(p)
while len(linkqueue) != 0:
node = linkqueue.dequeue()
print(node.element(), end=' ')
for children in self.children(node):
linkqueue.enqueue(children)
node._node._parent = node._node._left = node._node._right = node._node._element = None
def _swap(self, p, q):
node_p = self._validate(p)
node_q = self._validate(q)
node_p_parent = node_p._parent
node_q_parent = node_q._parent
node_p_left = node_p._left
node_p_right = node_p._right
node_q_left = node_q._left
node_q_right = node_q._right
node_p._parent = node_q_parent if node_q_parent != node_p else node_q
node_q._parent = node_p_parent if node_p_parent != node_q else node_p
node_p._left = node_q_left if node_q_left != node_p else node_q
try:
if node_p_left != node_q:
node_p_left._parent = node_q
except Exception:
pass
node_p._right = node_q_right if node_q_right != node_p else node_q
try:
if node_p_right != node_q:
node_p_right._parent = node_q
except Exception:
pass
node_q._left = node_p_left if node_p_left != node_q else node_p
try:
if node_q_left != node_p:
node_q_left._parent = node_p
except Exception:
pass
node_q._right = node_p_right if node_p_right != node_q else node_p
try:
if node_q_right != node_p:
node_q_right._parent = node_p
except Exception:
pass
try:
if node_p_parent is None or node_q_parent is None:
if node_p_parent is None:
if node_q_parent is None:
pass
else:
self._root = node_q
if node_p_left == node_q:
node_q._left = node_p
else:
node_q._right = node_p
else:
self._root = node_p
if node_q_left == node_p:
node_p._left = node_q
else:
node_p._right = node_q
else:
try:
if node_p_parent._left == node_p:
node_p_parent._left = node_q
else:
node_p_parent._right = node_q
if node_q_parent._left == node_q:
node_q_parent._left = node_p
else:
node_q_parent._right = node_p
except Exception:
pass
except Exception:
pass
def parenthesize(T, start):
if T.is_empty() and start is None:
raise Empty("tree is None")
else:
linkqueue = LinkQueue()
linkqueue.enqueue(start)
depth = T.height() - T.depth(start)
if depth == 0:
return None
else:
i = 0
while i <= depth:
temp = LinkQueue()
while len(linkqueue) != 0:
leaf = linkqueue.dequeue()
print(leaf.element(), end=' ')
for children in T.children(leaf):
temp.enqueue(children)
print()
while len(temp) != 0:
linkqueue.enqueue(temp.dequeue())
i += 1
def show_subtree(Tree,p):
"""后序遍历"""
for children in Tree.children(p):
show_subtree(Tree,children)
print(p.element())
pass
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._swap(linkTree.root(),linkTree.root())
show_subtree(linkTree,linkTree.root())
8.45
class Tree:
"""Abstract base class representing a tree structure."""
# ----------------------------nested Position class -----------------------------
class Position:
"""An abstraction representing the location of a single element."""
def element(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."""
return not (self == other)
# ---------- abstract methods that concrete subclass must support------------
def root(self):
"""Return Position representing the tree's root (or None if empty)."""
raise NotImplementedError("must be implemented by subclass")
def parent(self, p):
"""Return Position representing p's parent """
return NotImplementedError("must be implemented by subclass")
def num_children(self, p):
"""Return the number of children that Position p has."""
raise NotImplementedError("must be implemented by subclass")
def children(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 --------------
def is_root(self, p):
"Return True if Position p represents the root of the tree."
return self.root() == p
def is_leaf(self, p):
"""Return True if Position p does not have any children."""
return self.num_children(p) == 0
def is_empty(self):
"""Return True if the tree is empty."""
return len(self) == 0
def depth(self, p):
"""Return the number of levels separating Position p from the root."""
if self.is_root(p):
return 0
else:
return 1 + self.depth(self.parent(p))
# 定义 树的高度等于所有叶子结点的深度中的最大值
# 时间复杂度为n**2
def _height1(self):
"""Return the height of the tree."""
return max(self.depth(p) for p in self.positions() if self.is_leaf(p))
# 从根节点,自顶向下,效率比height快
# 时间复杂度为n
def _height2(self, p):
if self.is_leaf(p):
return 0
else:
return 1 + max(self._height2(c) for c in self.children(p))
def height(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 is None:
p = self.root()
return self._height2(p) # start_height2 recursion
def __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 element
def preorder(self):
"""Generate a preorder iteratiom of positions in the tree."""
if not 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 subtrees
for c in self.children(p): # for each child c
for other in self._subtree_preorder(c): # do preorder of c's subtree
yield other # yielding each to our caller
def positions(self):
"""Generate an iteration of the tree's positions."""
return self.preorder() # return entire preorder iteration
def preorder_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 indentation
for c in T.children(p):
self.preorder_indent(T, c, d + 1) # child depth is d + 1
class BinaryTree(Tree):
"""Abstract base class representing a binary tree structure."""
# -------------------additional abstract methods -------------------------
def left(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")
def right(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 ===========
def sibling(self, p):
"""Return a Position representing p's sibling (or None if no sibling)。"""
parent = self.parent(p)
if parent is None: # p must be the root
return None # root has no sibling
else:
if p == self.left(parent):
return self.right(parent) # possibly None
else:
return self.left(parent) # possibly None
def children(self, p):
"""Generate an iteraiton of Positions representing p's children."""
if self.left(p) is not None:
yield self.left(p)
if self.right(p) is not None:
yield self.right(p)
class LinkedBinaryTree(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
class Position(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
def element(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."""
return type(other) is type(self) and other._node is self._node
def _validate(self, p):
"""Return associated node ,if position is valid."""
if not isinstance(p, self.Position):
raise TypeError("p must be proper Position type")
if p._container is not self:
raise ValueError("p does not belong to this container")
if p._node._parent is p._node: # convention for deprecated nodes
raise 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 is not None else None
# ------------------------ 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
def root(self):
"""Return the root Position of the tree(or None if tree is empty)"""
return self._make_position(self._root)
def parent(self, p):
node = self._validate(p)
return self._make_position(node._parent)
def left(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)
def right(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)
def num_children(self, p):
"""Return the number of children of Position p."""
node = self._validate(p)
count = 0
if node._left is not None:
count += 1
if node._right is not None:
count += 1
return 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 is not None:
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 is not None:
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 is not None:
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 None
if child is not None:
child._parent = node._parent # child's grandparent becomes parent
if node is self._root:
self._root = child # child becomes root
else:
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)
if not self.is_leaf(p):
raise ValueError('position must be leaf')
if not type(self) is type(t1) is type(t2):
raise TypeError("Tree types must match")
self._size += len(t1) + len(t2)
if not t1.is_empty(): # attached t1 as left subtree of node
t1._root._parent = node
node._left = t1._root
t1._root = None
t1._size = 0
if not t2.is_empty(): # attached t2 as right subtree of node
t2._root._parent = node
node._right = t2._root
t2._root = None
t2._size = 0
pass
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.preorder_indent(linkTree,linkTree.root(),0)