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