VIEWS: 40 PAGES: 26 POSTED ON: 2/27/2011
Trees CS3323 1/26 Trees ☛ Trees ☛ Terminology ☛ The Tree ADT ☛ Depth and Height ☛ Tree traversals ☛ Binary Trees ☛ Properties of Binary Trees ☛ The Binary Tree ADT ☛ Data structures for trees October 6, 2005 by S. W. Rauch Trees CS3323 2/26 Trees ☛ A tree represents a hierarchy ➤ Organization structure of a corporation Electronics R'Us R&D Sales Purchasing Manufacturing Domestic International TV CD Tuner Canada S. America Overseas Africa Europe Asia Australia ➤ Table of contents of a book ➤ Unix or DOS/Windows ﬁle system ☛ A tree as a linked list: October 6, 2005 by S. W. Rauch Trees CS3323 3/26 Terminology A tree T is a set of nodes storing elements in a parent-child relationship with the following properties ☛ T has a distinguished node r, called the root of T, that has no parent. ☛ Each node v of T distinct from r has a parent node u ☛ ancestors and descendants An ancestor of a node is either the parent of the node itself or an ancestor of the parent of the node. A node v is a descendant of a node u if u is an ancestor of v ☛ For every node v of T, the root r is an ancestor of v ☛ If u is a parent of v, then v is a child of u ☛ Two or more children of the same parent node are siblings ☛ A node is a leaf if it has no children; internal, if it has at least one child. ☛ The subtree of T rooted at a node v is the tree consisting of v and all of its descendants. October 6, 2005 by S. W. Rauch Trees CS3323 4/26 Depth of a Node and Height of a Tree ☛ Depth ➤ If n is the root of T, then the depth of n is 0. ➤ Otherwise, the depth of n is one plus the depth of the parent of n ☛ Height ➤ The height of an empty tree is −1. ➤ Otherwise, the height of T is the length of the path from the node to the deepest leaf. October 6, 2005 by S. W. Rauch Trees CS3323 5/26 Terminology ➤ A is the root node. ➤ B is the parent of D and E. ➤ C is the sibling of B ➤ D and E are the children of B. ➤ D, E, F, G, I are leaf nodes. ➤ A, B, C, H are internal nodes. ➤ The depth (level) of E is 2. ➤ The height of the tree is 3. Property: (#edges) = (#nodes) − 1. A B C D E F H G I October 6, 2005 by S. W. Rauch Trees CS3323 6/26 The Tree ADT ➤ The BTNode element(): Return the element in a BTNode. Input: None; Output: Object ➤ Tree Methods root(): Return the root of T . Input: None; Output: BTNode parent(n): Return parent of node n. Input: BTNode; Output: BTNode children(n): Return the children of n setRoot(n): Sets the root of T . Input: BTNode; Output: None ➤ Query methods isInternal(n): Test whether node n is internal. Input: BTNode; Output: Boolean isLeaf(n): Test whether node n is a leaf. Input: BTNode; Output: Boolean isRoot(n): Test whether node n is the root. Input: BTNode; Output: Boolean isEmpty(), size(): Similar to stacks and queues October 6, 2005 by S. W. Rauch Trees CS3323 7/26 The Tree ADT(2) ➤ Other methods swapElements(n, v): Swap the elements stored at nodes n and v. Input: BTNode, BTNode; Output: None replaceElement(n, e): Replace the element stored at node u with e. Input: BTNode, Object; Output: Object October 6, 2005 by S. W. Rauch Trees CS3323 8/26 Traversing Trees ☛ Preorder traversal Algorithm preOrder(n) ”visit” node n for each child w of n do recursively perform preOrder(w) ➤ Reading a document from beginning to end ☛ Postorder traversal Algorithm postOrder(n) for each child w of n do recursively perform postOrder(w) ”visit” node n ➤ du (disk usage) command in Unix October 6, 2005 by S. W. Rauch Trees CS3323 9/26 Binary Trees ☛ A tree is ordered if there is a linear ordering deﬁned for the children of each node so that they can be identiﬁed as being ﬁrst, second, etc. ☛ Binary tree: An ordered tree in which no node can have more than two children. ➤ The ﬁrst child is called the left child ➤ The second child is called the right child ☛ Recursive deﬁnition of a binary tree: A binary tree is either ➤ empty or consists of ➤ a root, a left binary subtree, and a right binary sub- tree. The left and right subtrees may themselves be empty. October 6, 2005 by S. W. Rauch Trees CS3323 10/26 Properties of Binary Trees ☛ (#leaf nodes) (#internal nodes) +1 nL (T ) nI (T ) Induction on the number of internal nodes n I (T ): ➤ nI (T ) = n = 0: The tree may be empty or the root is a leaf node. Therefore, nL (T ) 1, nI (T ) = 0 and nL (T ) nI (T ) + 1. ➤ Assume true for nI (T ) = n > 0: Thus, for any binary tree T with n internal nodes we assume that n L(T ) n+1 leaf nodes. ➤ Prove true for nI (T ) = n + 1, i.e, show nL (T ) n + 2: Suppose T has nI (T ) = n + 1 R internal nodes. Since the root R is internal, nI (T ) = nI (A) + nI (B)+1 and A has nI (A) n T = B internal nodes and the induc- A tion hypothesis applies. Thus, nL(A) nI (A) + 1. Similarly, nL(B) nI (B) + 1. Therefore, since nL (T ) = nL (A) + nL (B), nL(T ) nI (A) + 1 + nI (B) + 1 = n + 1 + 1 = n + 2 ☛ (#nodes at level i) 2i Induction on level number i. Let n i (T ) be the number of nodes at level i. ➤ i = 0: Level 0 contains only the root. Therefore n0 (T ) = 1 20 = 1 ➤ Assume true for i > 0: Thus, n i (T ) 2i . October 6, 2005 by S. W. Rauch Trees CS3323 11/26 R ➤ Prove true for i + 1: T = A B i+1 i The number of nodes, n i+1 (T ), at level i + 1 of T satisﬁes ni+1 (T ) = ni(A) + ni (B), the sum of the number of nodes on level i of A and B. By induction assumption, n i (A) 2i. Similarly ni (B) 2i. Therefore, ni+1 (T ) 2i + 2i = 2i+1. ☛ (#leaf nodes) 2height n = nI +nL = n0 +n1 +· · ·+nh 20 +21 +· · ·+2h = 2h+1 −1 Therefore, using the ﬁrst property, nL − 1 nI ; 2nL − 1 nI + nL 2h+1 − 1; nL 2h ☛ (height) log2 (#leaf nodes) ☛ (height) log2 (#nodes + 1) − 1 ☛ (height) (#internal nodes) Induction on the number of internal nodes n I : ➤ nI = 0: The tree may be empty or the root is a leaf node. h(T ) 0. Therefore, h(T ) 0 = nI . ➤ Assume true for nI > 0: Thus, for any binary tree with n I internal nodes we assume that h(T ) n I . ➤ Prove true for ntI = nI + 1: Using the same diagram as the ﬁrst property, h(T ) = 1 + max(h(A), h(B)) 1 + max(naI , nbI ) nI + 1 October 6, 2005 by S. W. Rauch Trees CS3323 12/26 Binary Tree Node public class BTNode { private BTNode mLeft; private BTNode mRight; private BTNode mParent; private Object mElement; public BTNode(Object o, BTNode p, BTNode l, BTNode r) { mElement = o; mLeft = l; mRight = r; mParent = p; } public Object element() { return mElement; } public BTNode left() { return mLeft; } public BTNode right() { return mRight; } public BTNode parent() { return mParent; } public void setElement(Object o) { mElement = o; } public void setLeft(BTNode l) { mLeft = l; } public void setRight(BTNode r) { mRight = r; } public void setParent(BTNode p) { mParent = p; } } // BTNode October 6, 2005 by S. W. Rauch Trees CS3323 13/26 The Binary Tree ADT ➤ Specialization of a Tree parentn): Return the parent of n. Input: BTNode; Output: BTNode leftChild(n): Return the left child of n. Input: BTNode; Output: BTNode rightChild(n): Return the right child of n. Input: BTNode; Output: BTNode sibling(n): Return the sibling of n. Input: BTNode; Output: BTNode ➤ Errors: root(): if T is empty parent(n): if n = root() leftChild(n), rightChild(n): if n is a leaf October 6, 2005 by S. W. Rauch Trees CS3323 14/26 Depth of a Node, Height of a Tree ➤ Depth is O(n). Algorithm depth(t, n) Compute the depth of node in a binary tree Input: A binary tree t and a node n Output: The depth of n in t if t.isRoot(n) then return 0 else return 1 + depth(t, t.parent(n)) ➤ Height is O(n). Algorithm heightAux(t, n) Compute the height of node in a binary tree Input: A binary tree t and a node n Output: The height of n in t if n is null then { return −1 } else { return 1 + max(heightAux(t, t.leftChild(n), heightAux(t, t.rightChild(n)) } Algorithm height(t) Compute the height of a binary tree Input: A binary tree t Output: The height of t return heightAux(t, t.root()) } October 6, 2005 by S. W. Rauch Trees CS3323 15/26 An Expression Tree ☛ Arithmetic Expression as a binary tree ☛ Inorder traversal 7 4−1+2∧5×4×2÷2∧3∧2 → 2 ☛ Preorder traversal (+ (− 4 1) (÷ (× (× (∧ 2 5) 4) 2) (∧ 2 7 (∧ 3 2) ) ) ) → 2 ☛ Postorder traversal 7 4 1 − 2 5 ∧ 4 × 2 × 2 3 2 ∧ ∧ ÷ + → 2 October 6, 2005 by S. W. Rauch Trees CS3323 16/26 Postﬁx to Expression Tree ☛ Algorithm postfixToExpressionTree(Queue theQueue) Input: Assumes the postﬁx expression has been copied to theQueue Output: Binary Tree that represents the postﬁx expression while ( ! theQueue.isEmpty() ) do { token ← theQueue.dequeue() } if ( token is a number ) then { theStack.push( new BTNode( token, null, null, null) ) } else { token is an operator right ← theStack.pop() left ← theStack.pop() node ← new BTNode( token, null, left, right ) left.parent() ← node right.parent() ← node theStack.push( node ) } } root ← theStack.pop() theExpressionTree.setRoot( root ) return theExpressionTree ☛ If you now do a preorder traversal of the expresson tree you get the corresponding preﬁx expression. The inorder traver- sal yields the corresponding inﬁx expression. ☛ Consider the postﬁx expression: 5 8 3 4 × + 2 ∧ + 7 − October 6, 2005 by S. W. Rauch Trees CS3323 17/26 Traversing Binary Trees ☛ Preorder traversal of the internal nodes in a binary tree Algorithm preOrderTraversal(t, n) Input: A binary tree t and a node n ”visit n” if (t.leftChild(n) != null) then { preOrderTraversal(t, t.leftChild(n)) } if t.rightChild(n) != null then { preOrderTraversal(t, t.rightChild(n)) } ☛ Inorder traversal of the internal nodes in a binary tree Algorithm inOrderTraversal(t, n) Input: A binary tree t and a node n if (t.leftChild(n) != null) then { inOrderTraversal(t, t.leftChild(n)) } ”visit n” if t.rightChild(n) != null then { inOrderTraversal(t, t.rightChild(n)) } ☛ Postorder traversal of the internal nodes in a binary tree Algorithm postOrderTraversal(t, n) Input: A binary tree t and a node n if (t.leftChild(n) != null) then { postOrderTraversal(t, t.leftChild(n)) } if t.rightChild(n) != null then { postOrderTraversal(t, t.rightChild(n)) } ”visit n” October 6, 2005 by S. W. Rauch Trees CS3323 18/26 Traversals With Brackets ☛ Preorder traversal public String preOrderAux(BTNode n) { if (n == null) { return "()"; } else { return "(" + n.toString() + " " + preOrderAux(n.left()) + " " + preOrderAux(n.right()) + ")"; } } ☛ Inorder traversal public String InOrderAux(BTNode n) { if (n == null) { return ""; } else { return "(" + InOrderAux(n.left()) + " " + n.toString() + " " + InOrderAux(n.right()) + ")"; } } ☛ Postorder traversal public String PostOrderAux(BTNode n) { if (n == null) { return ""; } else { return PostOrderAux(n.left()) + " " + PostOrderAux(n.right()) + " " + n.toString(); } } October 6, 2005 by S. W. Rauch Trees CS3323 19/26 Euler Tour Traversal ☛ Generic traversal of a binary tree ☛ The preorder, inorder, and postorder traversals are special cases of the Euler tour traversal ☛ “walk around” the tree and visit each node three times: ➤ on the left ➤ from below ➤ on the right ☛ Euler traversal of the nodes in a binary tree Algorithm eulerTraversal(t, n) Input: A binary tree t and a node n ”visit n” if (t.leftChild(n) != null) then { eulerTraversal(t, t.leftChild(n)) } ”visit n” if t.rightChild(n) != null then { eulerTraversal(t, t.rightChild(n)) } ”visit n” October 6, 2005 by S. W. Rauch Trees CS3323 20/26 Non-recursive Preorder Traversal ☛ Algorithm preOrderTraversal(BinaryTree t) Uses a stack, theStack. Visit the popped node before its right and left children have been pushed on the stack. push t’s root, t.root(), on theStack while ( ! theStack.isEmpty() )do { node ← theStack.pop() “visit” node if ( node.right() != null ) then { push node.right() on theStack } if ( node.left() != null ) then { push node.left() on theStack } } October 6, 2005 by S. W. Rauch Trees CS3323 21/26 Non-recursive Postorder traversal ☛ Nodes are pushed onto stack with counter 0, 1, or 2: ➤ If we are about to process node’s left subtree ➤ If we are about to process node’s right subtree ➤ If we are about to process the node itself ☛ Algorithm postOrderTraversal(BinaryTree t) Uses a stack, theStack, and BTNode’s each with a counter, initially 0, whose value is incremented each time the node is popped from the stack. Visit the node after it has been popped 3 times. push t’s root, t.root(), on theStack while ( ! theStack.isEmpty() ) do { node ← theStack.pop() increment node.counter() if ( node.counter() == 3 ) then { “visit” node } else { push node on theStack if ( node.counter() == 1 && node.left() != null ) then { push node.left() on theStack } else if ( node.counter() == 2 && node.right() != null ) then { push node.right() on theStack } } } October 6, 2005 by S. W. Rauch Trees CS3323 22/26 Non-recursive Inorder traversal ☛ Algorithm inOrderTraversal(BinaryTree t) Uses a stack, theStack, and BTNode’s each with a counter, initially 0, whose value is incremented each time the node is popped from the stack. Visit the node after it has been popped 2 times. push t’s root, t.root(), on theStack while ( ! theStack.isEmpty() ) do { node ← theStack.pop() increment node.counter() if ( node.counter() == 2 ) then { “visit” node if ( node.right() != null ) then { push node.right() on theStack } } else { push node on theStack if ( node.left() != null ) then { push node.left() on theStack } } } October 6, 2005 by S. W. Rauch Trees CS3323 23/26 Depth and Breadth Traversals ☛ Depth First Traversal Algorithm depthFirstTraversal(t) visit the nodes of a binary tree in a depth ﬁrst fashion Input: A binary tree t Let s be a Stack. s.push(t.root()) while ! s.isEmpty() do { n ←− s.pop() ”visit v” if t.rightChild(n) != null then { s.push(t.rightChild(n)) } if (t.leftChild(n) != null) then { s.push(t.leftChild(n)) } } ☛ Breadth First Traversal Algorithm breadthFirstTraversal(t) visit the nodes of a binary tree in a breadth ﬁrst fashion Input: A binary tree t Let q be a Queue. q.enqueue(t.root()) while ! q.isEmpty() do { n ←− q.dequeue() ”visit v” if (t.leftChild(n) != null) then { q.enqueue(t.leftChild(n)) } if t.rightChild(n) != null then { q.enqueue(t.rightChild(n)) } } October 6, 2005 by S. W. Rauch Trees CS3323 24/26 Binary Tree public class BinaryTree { private BTNode mRoot; public BinaryTree() { mRoot = null; } public BTNode root() { return mRoot; } public BTNode parent(BTNode n) { return n.parent(); } public BTNode leftChild(BTNode n) { return n.left(); } public BTNode rightChild(BTNode n) { return n.right(); } public boolean isRoot(BTNode n) { return root() == n; } public boolean isLeaf(BTNode n) { return n.left() == null && n.right() == null; } public boolean isInternal(BTNode n) { return ! isLeaf(n); } public void setRoot(BTNode n) { mRoot = n; } public void setParent(BTNode u, BTNode v) { u.setParent(v); } public void setLeftChild(BTNode u, BTNode v) { u.setLeft(v); } public void setRightChild(BTNode u, BTNode v) { u.setRight(v); } public boolean isEmpty() { return root() == null; } } // BinaryTree October 6, 2005 by S. W. Rauch Trees CS3323 25/26 Array Representation of a Binary Tree ☛ Store the nodes of a binary tree in an array theArray ☛ theArray[0] is always empty ☛ The root is always stored in theArray[1] ☛ For a node stored in theArray[i] ➤ theArray[2 ∗ i] stores its left child ➤ theArray[2 ∗ i + 1] stores its right child ➤ theArray[i/2] stores its parent ☛ Advantages ➤ Simple direct access to children, siblings, and parents. ➤ Efﬁcient representation for trees that are full or almost full. ☛ Disadvantages ➤ Capacity must always be dealt with. ➤ Visually difﬁcult to see relationships of deeper nodes. ➤ Inefﬁcient storage for sparse trees. October 6, 2005 by S. W. Rauch Trees CS3323 26/26 Expression Trees Revisited ☛ The expression tree 1 2 3 4 5 6 7 12 13 14 15 24 25 30 31 48 49 ☛ The array 0 4 9 14 19 24 29 34 39 44 49 October 6, 2005 by S. W. Rauch