Computer Science 187 - PowerPoint PPT Presentation

1 / 47
About This Presentation
Title:

Computer Science 187

Description:

tree4.setTree(new Integer (1), tree1, tree3); BinaryTree tree4=new BinaryTree(new Integer(1) ... tree4.attachLeft(tree1); tree4.attachRight(tree3); System.out. ... – PowerPoint PPT presentation

Number of Views:56
Avg rating:3.0/5.0
Slides: 48
Provided by: twikiedla
Category:

less

Transcript and Presenter's Notes

Title: Computer Science 187


1
Computer Science 187
Introduction to Programming with Data Structures
Lecture 17 Implementing Trees
Announcements
  • Current OWL and project 4 are due today (November
    8).
  • New programming project up soon.
  • New OWL up soon.

2
General Tree Interfaces
  • General Tree Interface
  • Interface for traversals of general trees

public interface TreeInterface public Object
getData() public int getHeight() public int
getNumberOfNodes() public boolean
isEmpty() public void clear()
public interface TreeIteratorInterface public
Iterator PreorderIterator() public Iterator
PostOrderIterator() public Iterator
InorderIterator() public Iterator
LevelOrderIterator()
3
Binary Tree interfacemethods only
public Object getData() public int
getHeight() public int getNumberOfNodes() public
boolean isEmpty() public void clear() public
void setTree(Object rootData) public void
setTree(Object rootData, BinaryTreeInterface
leftTree, BinaryTreeInterface
rightTree) public Iterator PreorderIterator() pu
blic Iterator PostOrderIterator() public
Iterator InorderIterator() public Iterator
LevelOrderIterator()
from TreeInterface
from TreeIteratorInterface
4
The Binary Tree Interface
  • public interface BinaryTreeInterface extends
  • TreeInterface, TreeIteratorInterface
  • public void setTree(Object rootData)
  • public void setTree(Object rootData,
    BinaryTreeInterface
  • leftTree, BinaryTreeInterface
    rightTree)
  • //end BinaryTreeInterface

Exceptions?
5
and recall our Binary Tree Node Interface
  • public interface BinaryNodeInterface
  • public Object getData() //returns the data
    element at this node.
  • public void setData(Object myElement) //sets
    data element to myElement
  • public void setLeftChild(BinaryNodeInterface
    myLeft) //set left child to myLeft
  • public void setRightChild(BinaryNodeInterface
    myRight) //set right child to myRight
  • public BinaryNodeInterface getLeftChild() //ret
    urns left child node
  • public BinaryNodeInterface getRightChild()
    //returns right child node
  • public boolean hasLeftChild() //returns true
    if this node has a left child
  • public boolean hasRightChild() //returns true
    if this node has a right child
  • public boolean isLeaf() //returns true if
    node is a leaf node.

6
The methods of the interfaces
BinaryTreeInterface
BinaryNodeInterface
public Object getData() public int
getHeight() public int getNumberOfNodes() public
boolean isEmpty() public void clear() public
void setTree(Object rootData) public void
setTree(Object rootData,
BinaryTreeInterface leftTree,
BinaryTreeInterface rightTree) public Iterator
PreorderIterator() public Iterator
PostOrderIterator() public Iterator
InorderIterator() public Iterator
LevelOrderIterator()
public Object getData() public void
setData(Object myElement) public void
setLeftChild(BinaryNodeInterface myLeft) public
void setRightChild(BinaryNodeInterface
myRight) public BinaryNodeInterface
getLeftChild() public BinaryNodeInterface
getRightChild() public boolean hasLeftChild()
public boolean hasRightChild() public boolean
isLeaf()
7
An 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.getData())
  • System.out.println(Tree t is ")
  • t.inorderTraverse()
  • System.out.println()
  • BinaryTree tree1 new BinaryTree()
  • tree1.setTree(new Integer(2),
  • new BinaryTree(new
    Integer (4)),
  • new BinaryTree(new
    Integer (5)))
  • System.out.println("Tree1 is ")
  • tree1.inorderTraverse()
  • System.out.println()

8
Example, cont'd.
  • BinaryTree tree2 new BinaryTree()
  • tree2.setTree(new Integer (6),
  • new BinaryTree(new Integer(7)),
  • new BinaryTree(new
    Integer(8)))
  • System.out.println("tree2 is ")
  • tree2.inorderTraverse()
  • System.out.println()
  • BinaryTree tree3 new BinaryTree()
  • tree3.setTree(new Integer(3), tree2, null)
  • System.out.println("Tree3 is ")
  • tree3.inorderTraverse()
  • System.out.println()
  • BinaryTree tree4new BinaryTree()
  • tree4.setTree(new Integer (1), tree1, tree3)
  • System.out.println("Final tree is ")
  • tree4.inorderTraverse()
  • System.out.println()

1
tree4
9
Using attach
//tree4.setTree(new Integer (1), tree1,
tree3) BinaryTree tree4new BinaryTree(new
Integer(1)) tree4.attachLeft(tree1) tree4.attach
Right(tree3) System.out.println("Final tree is
") tree4.inorderTraverse() System.out.println()
10
Something to keep in mind
  • BinaryNode N tree3.getRoot()
  • N.setData(new Integer(1000))
  • System.out.println("Tree4 after changing
  • the data in the root node of
    tree3")
  • tree4.inorderTraverse()
  • System.out.println()

Whats the output?
11
Traversing a tree
  • 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?

12
Tree Traversal Patterns
  • A Possible Pattern
  • Touch Root Node
  • Visit Left subtree
  • 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 a PreOrder Traversal

touch means doing something at the node, such
as printing the element there.
13
preorderTraverse( )
  • public void preorderTraverse()
  • preorderTraverse(root)
  • private void preorderTraverse(BinaryNode node)
  • if (node ! null)
  • System.out.print(node.getData()" ")
  • preorderTraverse((BinaryNode)node.getLeftChil
    d())
  • preorderTraverse((BinaryNode)node.getRightChi
    ld())

Note the casts..
Print tree using preorder traversal 1 2 4 5
3 6 7 8
14
Tree Traversal Patterns
  • A Possible Pattern
  • Visit Left subtree
  • Touch Root node
  • Visit Right subtree
  • Must be applied at all levels of the tree.
  • Called an InOrder Traversal

15
inorderTraverse()
  • public void inorderTraverse()
  • inorderTraverse(root)
  • private void inorderTraverse(BinaryNode node)
  • if (node ! null)
  • inorderTraverse((BinaryNode)node.getLeftChild
    ())
  • System.out.print(node.getData()" ")
  • inorderTraverse((BinaryNode)node.getRightChil
    d())

Print tree using inorder traversal 4 2 5 1 7
6 8 3
16
Tree Traversal Patterns
  • A Possible Pattern
  • Visit Left subtree
  • Visit Right subtree
  • Touch Root Node
  • Must be applied at all levels of the tree.

12
7
11
3
6
8
10
1
2
4
5
9
  • Called a PostOrder Traversal

17
postorderTraverse( )
  • public void postorderTraverse()
  • postorderTraverse(root)
  • private void postorderTraverse(BinaryNode node)
  • if (node ! null)
  • postorderTraverse((BinaryNode)node.getLeftChi
    ld())
  • postorderTraverse((BinaryNode)node.getRightCh
    ild())
  • System.out.print(node.getData() )

Print tree using postorder traversal 4 5 2 7
8 6 3 1
18
The BinaryNode Class
  • public class BinaryNode implements
    BinaryNodeInterface
  • private Object data
  • private BinaryNode left
  • private BinaryNode right
  • //Constructors
  • public BinaryNode()
  • this(null)
  • public BinaryNode(Object dataPortion)
  • this(dataPortion, null,null)
  • public BinaryNode(Object nodeData, BinaryNode
    leftChild,
  • BinaryNode
    rightChild)
  • data nodeData
  • left leftChild
  • right rightChild

19
The BinaryNode Class
  • public boolean isLeaf()
  • return ((left null) (right null))
  • public Object getData()
  • return data
  • public void setData(Object newData)
  • datanewData
  • public void setLeftChild(BinaryNodeInterface
    leftChild)
  • left (BinaryNode) leftChild
  • public BinaryNodeInterface getLeftChild()
  • return left

20
The BinaryNode Class
  • public void setRightChild(BinaryNodeInterface
    rightChild)
  • right (BinaryNode) rightChild
  • public BinaryNodeInterface getRightChild()
  • return right
  • public boolean hasLeftChild()
  • return left ! null
  • public boolean hasRightChild()
  • return right ! null
  • //end Binary Node

21
The BinaryTree Class
  • import java.util.
  • public class BinaryTree implements
    BinaryTreeInterface,

  • java.io.Serializable
  • //Implements a binary tree using the BinaryNode
    class
  • protected BinaryNode root


22
The BinaryTree ClassConstructors
//The Constructors public BinaryTree() root
null public BinaryTree(Object rootData)
root new BinaryNode(rootData, null,
null) public BinaryTree(Object rootData,
BinaryTree leftTree,
BinaryTree rightTree) privateSetTree(root
Data, leftTree, rightTree)

23
The BinaryTree Class getRootData
public Object getRootData() Object rootData
null if (root ! null) rootDataroot.getData(
) return rootData
public Object getRootData() public int
getHeight() public int getNumberOfNodes() public
boolean isEmpty() public void clear() public
void setTree(Object rootData) public void
setTree(Object rootData, BinaryTreeInterface
leftTree, BinaryTreeInterface
rightTree) public Iterator getPreorderIterator()
public Iterator getPostOrderIterator() public
Iterator getInorderIterator() public Iterator
getLevelOrderIterator()
Null data at root or no root at
all? EXCEPTIONS????
24
The getHeight() method
  • getHeight() should be a tree method e.g.
    T.getHeight()
  • getHeight() needs to have a
  • node as an argument to
  • support recursion
  • Notice the structure
  • getHeight() is a public
  • tree method
  • getHeight(node) is a private
  • method that takes a node
  • as an argument
  • public int getHeight()
  • return getHeight(root)

We should use this mechanism on MOST tree methods
that need a node argument.
25
The BinaryTree Class getHeight
  • Recall that the height of a tree is the same as
    the depth of the deepest node in the tree.
  • The height of a tree rooted at a node is 1
    max(height of left tree, height of right tree)
    RECURSIVE

public int getHeight() return getHeight(root)
public Object getRootData() public int
getHeight() public int getNumberOfNodes() public
boolean isEmpty() public void clear() public
void setTree(Object rootData) public void
setTree(Object rootData,
BinaryTreeInterface leftTree,
BinaryTreeInterface rightTree) public Iterator
getPreorderIterator() public Iterator
getPostOrderIterator() public Iterator
getInorderIterator() public Iterator
getLevelOrderIterator()
26
The BinaryTree Class getHeight
  • private int getHeight(BinaryNode node)
  • int height 0
  • if (node ! null)
  • height 1 Math.max (
  • getHeight((BinaryNode)node.getLeftChild()),
  • getHeight((BinaryNode)node.getRightChild()))
  • return height

27
The BinaryNode Class getNumberOfNodes
  • Number of nodes in a tree is 1 number in left
    tree number in right tree
  • Another naturally recursive method

public int getNumberOfNodes() return
getNumberOfNodes(root)
public Object getRootData() public int
getHeight() public int getNumberOfNodes() public
boolean isEmpty() public void clear() public
void setTree(Object rootData) public void
setTree(Object rootData,
BinaryTreeInterface leftTree,
BinaryTreeInterface rightTree) public Iterator
getPreorderIterator() public Iterator
getPostOrderIterator() public Iterator
getInorderIterator() public Iterator
getLevelOrderIterator()
28
The BinaryTree Class getNumberOfNodes
private int getNumberOfNodes(BinaryNode node)
int leftNumber 0 int rightNumber 0 if
((BinaryNode)node.getLeftChild() !null)
leftNumbergetNumberOfNodes(
(BinaryNode)node.getLef
tChild()) if ((BinaryNode)node.getRightChild()
! null) rightNumbergetNumberOfNodes(

(BinaryNode)node.getRightChild()) return
1leftNumberrightNumber
29
The BinaryTree Class isEmpty, clear
public boolean isEmpty() return
rootnull public void clear() root null
public Object getRootData() public int
getHeight() public int getNumberOfNodes() public
boolean isEmpty() public void clear() public
void setTree(Object rootData) public void
setTree(Object rootData,
BinaryTreeInterface leftTree,
BinaryTreeInterface rightTree) public Iterator
getPreorderIterator() public Iterator
getPostOrderIterator() public Iterator
getInorderIterator() public Iterator
getLevelOrderIterator()
30
The BinaryTree ClasssetTree
  • public void setTree(Object rootData)
  • rootnew BinaryNode(rootData)
  • public void setTree(Object rootData,
    BinaryTreeInterface leftTree, BinaryTreeInterface
    rightTree)
  • privateSetTree(rootData, (BinaryTree)leftTree,
    (BinaryTree)rightTree)

public Object getRootData() public int
getHeight() public int getNumberOfNodes() public
boolean isEmpty() public void clear() public
void setTree(Object rootData) public void
setTree(Object rootData,
BinaryTreeInterface leftTree,
BinaryTreeInterface rightTree) public Iterator
getPreorderIterator() public Iterator
getPostOrderIterator() public Iterator
getInorderIterator() public Iterator
getLevelOrderIterator()
31
The BinaryTree ClassprivateSetTree - attempt 1
  • private void privateSetTree(rootData, BinaryTree
    leftTree, BinaryTree rightTree)
  • root new BinaryNode(rootData)
  • if (leftTree ! null) root.setRightChild(leftTr
    ee.root)
  • if (rightTree ! null) root.setRightChild(right
    Tree.root)

Problems? Call by reference for the left and
right tree results in the actual subtrees sharing
nodes with the new tree. Solution? Make a copy
of left and right tree before executing the set
methods above. But needs to be a deep copy.
32
The BinaryTree ClassprivateSetTree
  • Solution set trees to null after assignment,
  • Force the user to copy the trees before calling
    setTree if its necessary to preserve them
  • Solution Dont allow the operation
  • Theres nothing wrong with not allowing certain
    operations, such as divide by zero.

33
The BinaryTree ClassprivateSetTree - attempt 2
  • private void privateSetTree(Object rootData,
    BinaryTree leftTree, BinaryTree rightTree) throws
    BinaryTreeException
  • root new BinaryNode(rootData)
  • if (this leftTree this rightTree)
    throw
  • new BinaryTreeException("Cant
    create tree in privateSetTree")
  • if (rightTree leftTree) throw new
    BinaryTreeException

  • ("Cant create tree in privateSetTree")
  • if (leftTree ! null) root.setLeftChild(leftTre
    e.root)
  • if (rightTree ! null) root.setRightChild(right
    Tree.root)
  • leftTree null
  • rightTree null

Not consistent with our interface also need to
write the exception class.
34
BinaryTreeExceptions
  • public class BinaryTreeException extends
    Exception
  • public BinaryTreeException()
  • public BinaryTreeException(String s)
  • super(s)

35
Binary Tree TraversalsinorderTraverse
  • private void inorderTraverse(BinaryNode node)
  • if (node ! null)
  • System.out.print("(")
  • inorderTraverse((BinaryNode)node.getLeftChild
    ())
  • System.out.print(" "node.getData()" ")
  • inorderTraverse((BinaryNode)node.getRightChil
    d())
  • System.out.print(")")

36
Binary Tree Iterators
  • Constructor of the iterator pushes the tree nodes
    onto a queue or a stack
  • The next method simply pops the stack to get the
    next element
  • Well do a postorderIterator
  • You do the preorderIterator and inorderIterator
  • Can use our post order traversal methods to get
    the iterator

37
Binary Tree IteratorspostOrderIterator
  • public class PostOrderIterator
  • Stack s, temp
  • public PostOrderIterator(BinaryTree t) throws
    StackFullException,


  • StackEmptyException
  • //pre t ! null
  • //post this is an postorder Iterator for all
    the elements in t
  • // the first call to next() will return the
    first postorder element of t
  • s new LinkedStack() temp new
    LinkedStack()
  • BinaryNode current t.getRoot()
  • pushNodes(current) //push all nodes onto
    stack using postorder traversal
  • while(!temp.isEmpty()) //reverse node order
    since nodes have been

  • pushed in postorder
  • s.push(temp.pop())

38
Binary Tree IteratorspushNodes
private void pushNodes(BinaryNode n) throws
StackFullException if (n ! null)
pushNodes((BinaryNode)n.getLeftChild())
pushNodes((BinaryNode)n.getRightChild())
temp.push(n)
39
Binary Tree IteratorshasNext, next
  • public boolean hasNext()
  • //post Returns true iff this iteration has more
    elements
  • return !s.isEmpty()
  • public Object next() throws NoSuchElementException
    ,

  • StackFullException, StackEmptyException
  • // pre The structure of the tree this is
    iterating has not changed
  • // since this was constructed.
  • // post Returns the next element in the
    iteration.
  • // Throws a NoSuchElementException if !hasNext()
  • if (hasNext()) return s.pop()
  • else throw new NoSuchElementException()

40
Binary Tree Iteratorsremove
  • public void remove() throws UnsupportedOperationEx
    ception
  • //post Throws an UnsupportedOperationException
  • // (a runTime
    Exception)
  • // (Although defined in the java.util.Iterator
    interface,
  • // it is optional and we will not implement it)
  • throw new UnsupportedOperationException()

41
The BinaryTree ClassOther Useful Methods
  • public void postorderTraverse()
  • postorderTraverse(root)
  • private void postorderTraverse(BinaryNode node)
  • if (node ! null)
  • postorderTraverse((BinaryNode)node.getLeftChi
    ld())
  • postorderTraverse((BinaryNode)node.getRightCh
    ild())
  • System.out.print(node.getData())

42
The BinaryTree ClassOther Useful Methods
  • public void attachLeft(BinaryTree t)
  • //pre t is a non-null binary tree
  • //post the left child of this tree is set to t
  • BinaryNode troot t.getRoot()
  • root.setLeftChild(troot)
  • public void attachRight(BinaryTree t)
  • //pre t is a non-null binary tree
  • //post the right child of this tree is set to t
  • BinaryNode troot t.getRoot()
  • root.setRightChild(troot)

43
The Complete ImplementationClasses
  • Binary Node
  • BinaryNodeInterface.java
  • BinaryNode.java
  • Binary Tree linked implementation
  • TreeInterface.java
  • TreeIteratorInterface.java
  • BinaryTreeInterface.java
  • BinaryTree.java
  • BinaryTreeException.java
  • The Stack linked implementation
  • Stack.java
  • Node.java
  • LinkedStack.java
  • StackFullException.java
  • StackEmptyException.java
  • NoSuchElementException.java
  • Test Program
  • BinaryTreeTest.java

44
The TreeNode Class
  • TreeNode has four class variables
  • Reference to the parent node
  • The element stored there
  • A list of children nodes
  • A value field (for later applications)

TreeNode Object Object NodeList
TreeNodes!
45
insertChild Method
Node C
trailer

X
Node H
ParentC
Element
Value
trailer
header
Children
X
X
ParentH
Element
Node I
Value
trailer
header
Children
X
X
46
Enumerating the Children
  • Child node Enumerator
  • Implements the Enumeration interface

trailer
header
X
X
public Enumeration children(TreeNode n)
return new ListEnumerator(n.getChildren())
47
Balanced vs. Unbalanced Trees 1
start
A
B
C
F
G
L
D
H
I
Sort of Balanced
E
Mostly Unbalanced
J
K
Write a Comment
User Comments (0)
About PowerShow.com