Title: COSC2007 Data Structures II
1COSC2007 Data Structures II
2Topics
- ADT Binary Tree (BT)
- Operations
- Tree traversal
- BT Implementation
- Array-based
- LL-based
- Expression Notation and Tree traversal
3ADT Binary Tree
4ADT Binary Tree
- Operations
- CreateBinaryTree()
- // Creates an empty Binary Tree
- CretaeBinaryTree(in rootItemTreeItemType)
- // Creates a one-node BT whose root contains
RootItem - CreateBT(in rootItemTreeItemType,inout
leftTreeBinaryTree,inout rightTreeBinaryTree) - // Creates a BT with root data RootItem and a
leftTree and rightTree, - // respectively as its left right subtrees.
Makes leftTree rightTree empty - // so they cant be used to gain access to the
new tree. - destroyBinaryTree()
- // Destroys a binary tree
- isEmpty()boolean query
- // Determines whether a binary tree is empty
5ADT Binary Tree
- Operations
- getRootData()TreeItemType throw TreeException
- // Returns the data item in the root of a
nonempty subtree. - // Throws an exception if the tree is empty
- setRootData(in newItemTreeItemType) throw
TreeException - // Replaces the data item in the root of a binary
tree with newItem, if the - // tree is not empty, otherwise a root node is
created with newItem as its data - // item and is inserted in the tree.
- // If a new node cant be created, TreeException
is thrown - attachLeft(in newItem TreeItemType) throw
TreeException - // Attaches a left child containing newItem to
the root of a binary tree. - // Throws TreeException if the operation the
binary tree is empty - // or a left subtree already exists.
- attachRight(in newItemTreeItemType) throw
TreeException - // Attaches a left child containing newItem to
the root of a binary tree. - // Throws TreeException if the operation the
binary tree is empty
6ADT Binary Tree
- Operations
- attachLeftSubtree(inout leftTreeBinaryTree)
throw TreeException - // Attaches leftTree as the left subtree of the
root of a binary tree and makes - // leftTree empty so that it cant be used to
access this tree. Throws - // TreeException is the binary tree is empty or a
left subtree already exists. - attachRightSubtree(inout rightTreeBinaryTree)
throw TreeException - // Attaches rightTree as the right subtree of the
root of a binary tree and makes - // rightTree empty so that it cant be used to
access this tree. Throws - // TreeException is the binary tree is empty or a
right subtree already exists. - detachLeftSubtree(out leftTreeBinaryTree)
ThrowTreeException - // Detaches the left subtree of a binary trees
root. and retains it in - // leftTree. Throws TreeException if the tree is
empty. - detachRightSubtree(out rightTreeBinaryTree)
ThrowTreeException - // Detaches the right subtree of a binary trees
root. and retains it in - // rightTree. Throws TreeException if the tree
is empty.
7ADT Binary Tree
- Operations
- leftSubtree( )BinaryTree
- // Returns a copy of the left subtree of a binary
trees root without - // detaching the subtree. Returns an empty tree
if the binary tree is empty. - rightSubtree( )BinaryTree
- // Returns a copy of the right subtree of a
binary trees root without - // detaching the subtree. Returns an empty tree
if the binary tree is empty. - preorderTraverse(in visitFunctionType)
- // Traverses a binary tree in preorder
- // calls function visit() once for each node
- inorderTraverse(in visitFunctionType)
- // Traverses a binary tree in inorder
- // calls function visit() once for each node
- postorderTraverse(in visitFunctionType)
- // Traverses a binary tree in postorder
8BT Traversal
- Suppose I wanted to visit all the nodes in this
tree. - Furthermore, suppose I wanted to perform some
operation on the data there (such as printing it
out).
- What are some of the possible visitation patterns
we could use?
9BT Traversal
- Visit every node in a BT exactly once.
- Each visit performs the same operations on each
node - Visiting sequence of nodes is of importance
- Natural traversal orders
- Pre-order
- Depth-First or Node-Left-Right (NLR)
- In-order
- Symmetric or Left-Node-Right (LNR)
- Post-order
- Left-Right-Node (LRN)
10Pre-order Traversal
- Each node is processed the first time it is
observed. i.e. before any node in either subtree.
- A Possible Pattern
- Visit Root Node
- Visit Left subtree in preorder
- Visit Right subtree
- Must be applied at all levels of the tree.
1
2
9
3
6
10
11
4
5
7
8
12
- Called an PreOrder Traversal
A B D H I E J K C F G L
11Pre-order Traversal
- Pseudocode
- preorder (binaryTreeBinaryTree )
- // Traverses the binary tree binaryTree in
preorder. - // Assumes that visit a node means to display
the nodes data item - if (binaryTree is not empty )
-
- Display the data in the root of binaryTree
- preorder ( Left subtree of binaryTree s root )
- preorder ( Right subtree of binaryTree s root )
12In-order Traversal
- Each node is processed the second time it is
observed. i.e. after all the nodes in its left
subtree but before any of the nodes in its right
subtree. - A Possible Pattern
- Visit Left subtree
- Visit Root node
- Visit Right subtree
- Must be applied at all levels of the tree.
H D I B J E K A F C G L
13In-order Traversal
- Pseudocode
- inorder (binaryTreeBinaryTree )
- // Traverses the binary tree binaryTree in
inorder. - // Assumes that visit a node means to display
the nodes data item - if (binaryTree is not empty )
-
- inorder ( Left subtree of binaryTree s root )
- Display the data in the root of binaryTree
- inorder ( Right subtree of binaryTree s root )
-
14Post-order Traversal
- Each node is processed the third time it is
observed. i.e. after all nodes in both of its
subtrees. - A Possible Pattern
- Visit Left subtree
- Visit Right subtree
- Visit Root Node
- Must be applied at all levels of the tree.
12
7
11
3
6
8
10
1
2
4
5
9
H I D J K E B F L G C A
15Post-order Traversal
- Pseudocode
- postorder (binaryTreeBinaryTree )
- // Traverses the binary tree binaryTree in
postorder. - // Assumes that visit a node means to display
the nodes data item - if (binaryTree is not empty )
-
- postorder ( Left subtree of binaryTree s root )
- postorder ( Right subtree of binaryTree s root
) - Display the data in the root of binaryTree
-
16Implementation of BT
- Possible Implementations
- Array based
- Fast access
- Difficult to change
- Used if elements are not modified often
- Reference (Pointer) based
- Slower
- Easy to modify
- More flexible when elements are modified often
17BT Array-Based Implementation
- Nodes
- A Java Node class
- Each node should contain
- Data portion
- Left-child index
- Right-child index
- Tree
- Array of structures
- For empty tree
- Root's index -1
18BT Array-Based Implementation
- public class TreeNode // node in the
tree -
- private Object item // data item in the
tree - private int leftChild // index to left
child - private int rightChild // index to right
child - . //constructor
- // end of TreeNode
- public abstract class BinaryTreeArrayedBased
- protected final int MAX_NODES 100
- protected TreeNode tree
- protected int root // index of root
- protected int free // index of next
unused array location - ..//constructor and methods
- // end BinaryTreeArrayedBased
19BT Array-Based Implementation
- Example
- Item Lchild RChild
- O James 1 2 root
- 1 Bob 3 4
- 2 Tony 5 -1
- 3 Adams -1 -1
- 4 Davis -1 -1
- 5 Neil -1 -1
- 6 ? -1 7
- 7 ? -1 8
- 8 ? -1 9
List of Free Nodes
20BT Array-Based Implementation
- As insertion and/or deletion operations are
performed, the elements of the tree might not be
in consecutive locations in the array - A list of free nodes should be maintained
- When a node is deleted, it is added to the free
list - When a node is inserted, it is removed from the
free list - If you know that the binary tree is complete, a
simpler array-based implementation can be used
that contains no Lchild, or Rchild entries.
21BT Array-Based Implementation
- Since tree is complete, it maps nicely onto an
array representation.
A
C
B
F
G
D
E
H
I
J
K
L
last
A B C D E F G H I
J K L
T
0 1 2 3 4 5 6 7
8 9 10 11 12
22BT Array-Based Implementation
- For Complete Trees
- A formula can be used to find the location of any
node in the tree - Lcild ( Tree i ) Tree 2 i 1
- Rcild ( Tree i ) Tree 2 i 2
- Parent (Tree i ) Tree ( i - 1) / 2
-
23Reference-Based Implementation
- Typical for implementing BTs
- Different constructors to allow defining the BT
in a variety of circumstances - Only the pointer to the root of the tree can be
accessed by BT class clients - The data structure would be private data member
of a class of binary trees
24Reference -Based Implementation
- public class TreeNode // node in the tree
-
- private Object item // data portion
- private TreeNode leftChildPtr // pointer to
left child - private TreeNode rightChildPtr // pointer to
right child - TreeNode()
- TreeNode(Object nodeItem, TreeNode left ,
TreeNode right ) -
- .
- // end TreeNode class
25Reference -Based Implementation
- public abstract class BinaryTreeBasis
-
- protected TreeNode root
- . // constructor and methods
- // end BinaryTreeBasis class
- If the tree is empty, then root is null
- The root of a nonempty BT has a left subtree and
right subtree, each is BT - root.getRight ()
- root.getLeft()
26Reference -Based Implementation
27The TreeNode Class
- public class TreeNode
- private Object item
- private TreeNode leftChild
- private TreeNode rightChild
- public TreeNode() //Constructors
- public TreeNode(Object myElement)
- item myElement
- leftChild null
- rightChild null
-
- public TreeNode(Object newItem, TreeNode left,
TreeNode right) item newItem - leftChild left
- rightChild right
-
28TreeNode, cont'd.
- public Object getItem()
- return item
- public void setItem(Object newItem)
- item newItem
- public void setLeft(TreeNode left)
- leftChild left
- public TreeNode getLeft()
- return leftChild
- public void setRight(TreeNode right)
- rightChild right
- public TreeNode getRight()
- return rightChild
29TreeException
- public class TreeException extends
RuntimeException -
- public TreeException(String s) super (s)
- // end TreeException
30The BinaryTreeBasis class
- public abstract class BinaryTreeBasis
- protected TreeNode root
- public BinaryTreeBasis ()
- root null
- //end constructor
- public BinaryTreeBasis (object rootItem)
- root new TreeNode (rootItem, null, null)
- //end constructor
- public boolean isEmpty() //true is tree is
empty - return root null
-
- public void makeEmpty() //sets root of tree
to null - root null
-
-
31The BinaryTreeBasis class
- public Object getRootItem() throws TreeException
//returns element at root if it exists - if (root null)
- throw new TreeException ( Empty tree)
- else
- return root.getItem()
- //end getRootItem()
- public TreeNode getRoot()
- return root
- //end getRoot()
- //end class BinaryTreeBasis
-
32The BinaryTree Class
- public class BinaryTree extend BinaryTreeBasis
-
- //the Constructors
- public BinaryTree()
- public BinaryTree(Object rootItem)
- super (rootItem)
- //end constructor
- public BinaryTree(Object rootItem, BinaryTree
leftTree, BinaryTree rightTree) - root new TreeNode(rootItem, null, null)
- attachLeftSubTree (leftTree)
- attachRightSubTree (rightTree)
- // end constructor
- Â Â Â Â Â all the methods go here
- //end BinaryTree
33The BinaryTree Class
- public void setRootItem(Object newItem)
- if (root null)
- root new TreeNode (newItem, null, null)
- else
- root.setItem(newItem)
- //end setRootItem
34The BinaryTree Class
- public void attachLeft(Object newItem)
- if (!isEmpty() root.getLeft() null)
- root.setLeft(new TreeNode(newItem, null,
null)) - // end attachLeft
- public void attachRight(Object newItem)
- if (!isEmpty() root.getRight() null)
- root.setRight(new TreeNode(newItem, null,
null)) - // end attachRight
35The BinaryTree Class
- public void attachLeftSubtree(BinaryTree
leftTree) throws TreeException -
- if (isEmpty()) throw new TreeException("Cannot
attach left subtree to empty tree.") - else if (root.getLeft() ! null) throw new
TreeException("Cannot overwrite left
subtree.") - else //no empty tree, no left child
- root.setLeft(leftTree.root)
- leftTree.makeEmpty()
- //end attachLeftSubtree
-
-
36The BinaryTree Class
- public void attachRightSubtree(BinaryTree
rightTree) throws TreeException -
- if (isEmpty()) throw new TreeException("Cannot
attach left subtree to empty tree.") - else if (root.getRight() ! null) throw new
TreeException("Cannot overwrite right
subtree.") - else //no empty tree, no right child
- root.setRight(rightTree.root)
- rightTree.makeEmpty()
- //end attachRightSubtree
-
-
37The BinaryTree Class
- protected BinaryTree (TreeNode rootNode)
- root rootNode
- //end constructor
- public BinaryTree detachLeftSubtree() throws
TreeException -
- if (isEmpty()) throw new TreeException("Cannot
detach empty tree.") - else // create a tree points to the
leftsubtree - BinaryTree leftTree
- leftTree new BinaryTree (root.getLeft())
- root.setLeft (null)
- return leftTree
-
- //end detachLeftSubtree
-
-
38The BinaryTree Class
- public BinaryTree detachRightSubtree() throws
TreeException -
- if (isEmpty()) throw new TreeException("Cannot
detach empty tree.") - else // create a tree points to the
rightsubtree - BinaryTree rightTree
- rightTree new BinaryTree (root.getRight())
- root.setRight (null)
- return rightTree
-
- //end detachRightSubtree
-
-
39preOrderPrint( )
- public void preOrderPrint(TreeNode rootNode)
throws TreeException -
- if (rootNode!null)
-
- System.out.print(rootNode.getItem() "
") - preOrderPrint(rootNode.getLeft())
- preOrderPrint(rootNode.getRight())
-
Print tree using preorder traversal 1 2 4 5
3 6 7 8
40inOrderPrint()
- public void inOrderPrint(TreeNode rootNode)
throws TreeException -
- if (rootNode!null)
-
- inOrderPrint(rootNode.getLeft())
- System.out.print(rootNode.getItem() " ")
- inOrderPrint(rootNode.getRight())
-
Print tree using inorder traversal 4 2 5 1 7
6 8 3
41postOrderPrint( )
- public void postOrderPrint(TreeNode rootNode)
throws TreeException -
- if (rootNode!null)
-
- postOrderPrint(rootNode.getLeft())
- postOrderPrint(rootNode.getRight())
- System.out.print(rootNode.getItem() "
") -
Print tree using postOrder traversal 4 5 2 7
8 6 3 1
42An Example Program
- public class BinaryTreeTest
-
- public static void main (String args) throws
BinaryTreeException -
- BinaryTree t new BinaryTree(new Integer(1))
- System.out.println("Element at root of tree
" t.getRootElement()) - System.out.println("Initial tree is ")
- t.reOrderPrint(t.getRoot())
- System.out.println()
-
- BinaryTree tree1 new BinaryTree(new
Integer(2)) - tree1.attachLeft(new Integer(4))
- tree1.attachRight(new Integer(5))
- System.out.println("Tree1 is ")
- tree1.preOrderPrint(tree1.getRoot())
- System.out.println()
-
43Example, cont'd.
- BinaryTree tree2 new BinaryTree(new
Integer(6)) - tree2.attachLeft(new Integer(7))
- tree2.attachRight(new Integer(8))
- System.out.println("tree2 is ")
- tree2.preOrderPrint(tree2.getRoot())
- System.out.println()
- BinaryTree tree3 new BinaryTree(new
Integer(3)) - tree3.attachLeftSubtree(tree2)
- System.out.println("Tree3 is ")
- tree3.preOrderPrint(tree3.getRoot())
- System.out.println()
-
- t.attachLeftSubtree(tree1)
- t.attachRightSubtree(tree3)
- System.out.println("Final tree is ")
- t.preOrderPrint(t.getRoot())
- System.out.println()
-
44Expression Tree
- Given a math expression, there exists a unique
corresponding expression tree. - 5 (6 (8-6))
45Preorder Of Expression Tree
/
a
b
-
c
d
e
f
Gives prefix form of expression!
46Inorder By Projection
47Inorder Of Expression Tree
Gives infix form of expression (sans parentheses)!
48Postorder Of Expression Tree
a
b
c
d
-
e
f
/
Gives postfix form of expression!