Lecture 18:  Tree Traversals

Announcements

·       p4 (Dictionary + Document Word Count) is due 4/14

·       h6 due today; h7 posted (due )

it's often useful to iterate through a tree's nodes

o      visit each node once

e.g., to print all values, search for a value, etc.

·       four common orderings for traversing the nodes

o      preorder

o      postorder

o      level order

o      in-order (binary trees only)

(these tree traversals are important!)

preorder traversal ("visit the root first")

recursive definition:

1.      visit the root

2.    do a preorder traversal of the 1st subtree

3.    do a preorder traversal of the 2nd subtree

4.    do a preorder traversal of the 3rd subtree

etc., for all subtrees, left to right

example: 

 

 

 

 

 

 


preorder traversal & print:   A  B  D C  E  G F  H  I

code for preorder traversal

preorder(Treenode T) {  // very simple code!

  if (T != null) {

    // visit T; e.g., System.out.print (T.key)

    List tmp = T.getKids();

    for (int k=0; k < tmp.size(); k++){

      preorder(tmp.get(k));

    }

  }

}

postorder traversal ("visit the root last")

1.      do a postorder traversal of the 1st subtree

2.    do a postorder traversal of the 2nd subtree

etc. for all subtrees, left to right

3.    visit the root

postorder traversal & print:  D B G E H I F C A

in-order traversal (binary trees only)

"visit the root inbetween the left and right subtrees"

1.      do an in-order traversal of the left subtree

2.    visit the root

3.    do an in-order traversal of the right subtree

example:

 

 

 

 

 

 


inorder traversal & print:  D B A G E C H F I

Note:  the difference between pre- in- & post-order is

when the root is visited with respect to its subtrees

pre:  visit the root before the subtrees

in:     visit the root in between the subtrees

post: visit the root after the subtrees

level-order traversal

1.      visit all the nodes at level 1

2.    visit all the nodes at level 2

etc.  (always left to right)

 

 

 

 

 

 


·       use a Queue

(recursion for pre-/post-/in-order uses a Stack)

 

Q.enqueue( root );

while (!Q.isEmpty()) {

  // dequeue node n

  // visit n; e.g., print n

  // enqueue all of n's children, left to right

}

(simulate the example with visit = print)

You try:

give the output for 

    pre-order, in-order, post-order & level-order traversals of

 

                                       I

                laughed                              (ha!)

       and           jumped            ate            cakes

 he               she               all           five

 

solutions:

pre-order:  I laughed and he jumped she (ha!) ate all 5 cakes

in-order:  and he laughed she jumped I all ate 5 (ha!) cakes

post-order:  he and she jumped laughed all 5 ate cakes (ha!) I

level-order:  I laughed (ha!) and jumped ate cakes he she all 5

 

Binary Search Trees  (BSTs)

·       special kind of binary tree

·       each node stores a key value

& maybe some associated data

·       for every node n:

o      all keys in n's left subtree are £ the key at n

o      all keys in n's right subtree are ³ the key at n

if duplicate keys are allowed, keys = the key at n 

all go in either the left or the right subtree

(but not in both – need a convention)

BSTs are important because we can do:

·       insert a key (and associated data)

·       lookup a key (return true or associated data)

·       remove a key

·       print all keys in sorted order

easily and efficiently

examples:

   each key is an int

 

 

 


  

                              YES                                              NO  (7 > 6)

  

   each key is a char                         

 

 

 

 

 


                   YES                                               NO  (F < G)

 

Question: 

   what kind of traversal prints the BST keys in sorted order?

   answer:  an in-order traversal

 

Implementing BSTs

Two classes:  one for tree nodes, one for "whole tree"

class Bnode {

  public Comparable key;  // can be private - in notes

  public Bnode left, right;

  // the constructor goes here

}

class BST {

  private Bnode root;

  public BST() { root = null; }

  public void insert( Comparable k ) throws DupEx { … }

  public boolean lookup( Comparable k ) { … }

  public void delete( Comparable k ) { … }

  public void print( PrintWriter p ) { … }

}

root

 

t

 
BST t = new BST();    

Note:  can have associated data with each node

        e.g., key = English word, associated data = French word

        how would each of the above change for associated data?

1.      Bnode has a 4th field:

public Object data;

2.    insert has two parameters:  (Comparable k, Object d)

3.    lookup returns associated data (null if key not in BST)

4.    delete might return data of deleted key