python数据结构第八章课后习题答案(一)

再次更新

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)

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

北漂的阿狸

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值