0
点赞
收藏
分享

微信扫一扫

Lecture06 Binary Tree I

Lecture06 Binary Trees I

What’s a Binary Tree?

  • Pointer-based data structures (like Liked List) can achieve worst case
  • Binary tree is pointer-based data structure with three pointers per node.
  • Node representation: node.{item, parent, left, right}
  • Implement:
class Binary_Node:
    def __init__(A, x):					# O(1)
        A.item	 = x
        A.left 	 = None
        A.right	 = None
        A.parent = None
        # A.subtree_update()			# wait for R07!

Terminology of a Binary Tree

  • Root - The root of a tree has no parent
  • Leaf - A leaf of a tree has no children
  • Depth - Define depth(<X>) of node <X> in a tree rooted at <R> to be length of path from <X> to <R> [from up to bottom (max)]
  • Height - Define height(<X>) of node <X> to be max depth of ant node in the subtree rooted at <X> [from bottom to up]
  • Traversal Order
    • every node in node <X>'s left subtree is before <X>
    • every node in node <X>'s right subtree is after <X>
  • List nodes
def subtree_iter(A):					# O(n)
    if A.left:	yield from A.left.subtree_iter()
    yield
    if A.right:	yield from A.right.subtree_iter()

Tree Navigation

  • Find first node in the traversal order of node <X>'s subtree

    • If <X> has left child, recursively return the first node in the left subtree

    • Else, <X> is the first node, so return it

    • Implement:

      def subtree_first(A):					# O(h)
          if A.left:	return A.left.subtree_first()
          else:		return A
      
      def subtree_last(A):					# O(h)
          if A.right:	return A.right.subtree_last()
          else:		return A
      
  • Find successor of node <X> in the traversal order

    • If <X> has a right child, return first of right subtree
    • Else, return lowest ancestor of <X> for which <X> is in its left subtree
    • Implement:
    def successor(A):					# O(h)
      if A.right:	return A.right.subtree_first()
      while A.parent and (A is A.parent.right):
          A = A.parent
      return A.parent
    

Dynamic Operations

  • Change the tree by a single item (only add or remove leaves):

    • add a node after another in the traversal order (before is symmetric)
    • remove an item from the tree
  • Insert node <Y> after node <X> in the traversal order

    • If <X> has no right child, make <Y> the right child of <X>

    • Else, make <Y> the left child of <X>’s successor (which cannot have a left child)

    • Implement:

      def subtree_insert_before(A, B):		# O(h)
          if A.left:
              A = A.left.subtree_last()
              A.right, B.parent = B, A
          else:
              A.left, B.parent = B, A
          # A.maintain()						# wait for R07!
      
      def subtree_insert_after(A, B):			# O(h)
          if A.right:
              A = A.right.subtree_first()
              A.left, B.parent = B, A
          else:
              A.right, B.parent = B, A
          # A.maintain()						# wait for R07!
      
  • Delete the item in node <X> from <X>’s subtree

    • If <X> is a leaf, detach from parent and return

    • Else, <X> has a child

      • If <X> has a left child, swap items with the predecessor of <X> and recurse
      • Otherwise <X> has a right child, swap items with the successor of <X>and recurse
    • Implement:

      def subtree_delete(A):					# O(h)
          if A.left or A.right:				# A is not a leaf
              if A.left:	B = A.predecessor()
              else:		B = A.successor()
              A.item, B.item = B.item, A.item
              return B.subtree_delete()
          if A.parent:						# A is a leaf
              if A.parent.left is A:	A.parent.left = None
              else:					A.parent.right = None
              # A.parent.maintain()			# wait for R07
              return A
      

Binary Node Full Implementation

       class Binary_Node:
           def __init__(A, x):					# O(1)
               A.item	 = x
               A.left 	 = None
               A.right	 = None
               A.parent = None
               # A.subtree_update()			# wait for R07!
       
           def subtree_iter(A):					# O(n)
               if A.left:	yield from A.left.subtree_iter()
               yield
               if A.right:	yield from A.right.subtree_iter()
               
           def subtree_first(A):					# O(h)
               if A.left:	return A.left.subtree_first()
               else:		return A
       
           def subtree_last(A):					# O(h)
               if A.right:	return A.right.subtree_last()
               else:		return A       
       
           def successor(A):					# O(h)
               if A.right:	return A.right.subtree_first()
               while A.parent and (A is A.parent.right):
                   A = A.parent
               return A.parent
       
           def predecessor(A):					# O(h)
               if A.left:	return A.left.subtree_last()
               while A.parent and (A is A.parent.left):
                   A = A.parent
               return A.parent
           
           def subtree_insert_before(A, B):		# O(h)
           if A.left:
               A = A.left.subtree_last()
               A.right, B.parent = B, A
           else:
               A.left, B.parent = B, A
           # A.maintain()						# wait for R07!
       
           def subtree_insert_after(A, B):			# O(h)
               if A.right:
                   A = A.right.subtree_first()
                   A.left, B.parent = B, A
               else:
                   A.right, B.parent = B, A
               # A.maintain()						# wait for R07!
               
           def subtree_delete(A):					# O(h)
               if A.left or A.right:				# A is not a leaf
                   if A.left:	B = A.predecessor()
                   else:		B = A.successor()
                   A.item, B.item = B.item, A.item
                   return B.subtree_delete()
               if A.parent:						# A is a leaf
                   if A.parent.left is A:	A.parent.left = None
                   else:					A.parent.right = None
                   # A.parent.maintain()			# wait for R07
                   return A

Top-Level Data Structure

class Binary_Tree:
    def __init__(T, Node_Type = Binary_Node):
        T.root = None
        T.size = 0
        T.Node_Type = Node_Type
        
    def __len__(T):	return T.size
    def __iter__(T):
        if T.root:
            for A in T.root.subtree_iter():
                yield A.item
举报

相关推荐

0 条评论