You are on page 1of 52

Lecture #12

Binary Tree Traversals


Using Binary Trees to Evaluate Expressions
Binary Search Trees
Binary Search Tree Operations
Searching for an item
Inserting a new item
Finding the minimum and maximum items
Printing out the items in order
Deleting the whole tree

Binary Tree Traversals


When we process all the nodes in a tree, its called a
traversal.
There are four common ways to traverse a tree.
1. Pre-order traversal
2. In-order traversal
3. Post-order traversal
4. Level-order traversal

Lets see a pre-order traversal first!

The Preorder Traversal


Preorder:
1. Process the current node.
2. Process the nodes in the
left sub-tree.
3. Process the nodes in the
right sub-tree.

root
c

NULL NULL

NULL NULL

NULL NULL

By process the current node we typically mean one of


the following:
1. Print the current nodes value out.
2. Search the current node to see if its value matches
the one youre searching for.
3. Add the current nodes value to a total for the tree
4. Etc

The Pre-order Traversal


Output:
a bd

cur

cur

root
c

NULL NULL

cur

NULL

cur

NULL NULL

NULL NULL

void PreOrder(Node *cur)


void
{ PreOrder(Node *cur)
void
*cur) // if empty, return
{ PreOrder(Node
if (cur == NULL)
{ PreOrder(Node
void
*cur)// if empty, return
if (cur
== NULL)
return;
== NULL)
// if empty, return
{ if (cur
return;
main()
cout
<<
cur->value;
//
Process
the
current
node.
return;
if (cur == NULL)
// if empty, return
{
cout
<<
cur->value;
// Process the current node.
return;
// Process
nodes innode.
left sub-tree.Node *root;
coutPreOrder(cur->left);
<< cur->value;
// Process
the current
PreOrder(cur->left);
////Process
left
PreOrder(cur->
Process
nodesinin
leftsub-tree.
sub-tree.
cout
<<
cur->value; right);
// Process
the nodes
current
node.
PreOrder(cur->left);
nodes
ininleft
sub-tree.
Process
nodes
left
sub-tree.
}PreOrder(cur-> right);////Process
Processnodes
nodesininleft
leftsub-tree.
sub-tree.
PreOrder(cur->left);
}PreOrder(cur-> right);////Process
PreOrder(root);
} PreOrder(cur-> right); // Process nodes in left sub-tree.
}
}

The Pre-order Traversal


Output:
a bd

cur

cur
cur

root
c

NULL NULL

NULL
cur

NULL NULL

NULL NULL

void PreOrder(Node *cur)


void PreOrder(Node *cur)
{
void
{ PreOrder(Node *cur)
if (cur == NULL)
// if empty, return
{ PreOrder(Node
void
*cur)// if empty, return
if (cur == NULL)
return;
== NULL)
// if empty, return
{ if (cur
return;
main()
return;
if (cur
== NULL)
// if empty,
return
cout
<< cur->value;
// Process
the current node. {
cout
<<
cur->value;
//
Process
the
current node.
return;
coutPreOrder(cur->left);
<< cur->value;
// Process
the current
// Process
nodes innode.
left sub-tree.Node *root;
PreOrder(cur->left);
//
Process
nodes
in
left
sub-tree.
cout <<
cur->value; right);
// Process
the current
node.
PreOrder(cur->
// Process
nodes in
left sub-tree.
PreOrder(cur->left);
nodes
ininleft
sub-tree.
PreOrder(cur-> right);////Process
Process
nodes
left
sub-tree.
}
Processnodes
nodesininleft
leftsub-tree.
sub-tree.
PreOrder(cur->left);
}PreOrder(cur-> right);////Process
PreOrder(root);
} PreOrder(cur-> right); // Process nodes in left sub-tree.
}
}

The Pre-order Traversal


Output:
a bd

cur

cur

root
c

NULL NULL

cur

NULL NULL

NULL NULL

void PreOrder(Node *cur)


void
{ PreOrder(Node *cur)
{ PreOrder(Node
void
*cur)// if empty, return
if (cur == NULL)
== NULL)
// if empty, return
{ if (cur
return;
main()
return;
if (cur == NULL)
// if empty, return
{
cout
<<
cur->value;
// Process the current node.
return;
cout << cur->value;
// Process the current node.
Node *root;
PreOrder(cur->left);
//
Process
nodes
in
left
sub-tree.
cout << cur->value;
// Process the current node.
PreOrder(cur->left);
nodes
ininleft
sub-tree.
PreOrder(cur-> right);////Process
Process
nodes
left
sub-tree.
Processnodes
nodesininleft
leftsub-tree.
sub-tree.
PreOrder(cur->left);
}PreOrder(cur-> right);////Process
PreOrder(root);
} PreOrder(cur-> right); // Process nodes in left sub-tree.
}
}

The Pre-order Traversal


Output:
a bde

cur

cur

root
c

NULL NULL

NULL NULL

NULL NULL

cur

void PreOrder(Node *cur)


void
{ PreOrder(Node *cur)
{ PreOrder(Node
void
*cur) // if empty, return
if (cur == NULL)
== NULL)
// if empty, return
{ if (curreturn;
main()
return;
if (cur == NULL)
// if empty, return
{
cout
<<
cur->value;
// Process the current node.
return;
cout << cur->value;
// Process the current node.
Node *root;
PreOrder(cur->left);
//
Process
nodes
in
left
sub-tree.
cout << cur->value;
// Process the current node.
PreOrder(cur->left);
Process
nodes
in in
left
sub-tree.
PreOrder(cur-> right);////
Process
nodes
left
sub-tree.
Processnodes
nodesininleft
leftsub-tree.
sub-tree.
PreOrder(cur->left);
}PreOrder(cur-> right);////Process
PreOrder(root);
} PreOrder(cur-> right); // Process nodes in left sub-tree.
}
}

The Pre-order Traversal


Output:
a bde

cur

cur

root
c

NULL NULL

NULL NULL

NULL NULL

void PreOrder(Node *cur)


{ PreOrder(Node *cur)
void
// if empty, return
{ if (cur == NULL)
main()
return;
if (cur == NULL)
// if empty, return
{
return;
cout << cur->value;
// Process the current node.
Node *root;
cout << cur->value;
// Process the current node.
PreOrder(cur->left); // Process nodes in left sub-tree.
PreOrder(cur-> right);////Process
Processnodes
nodesininleft
leftsub-tree.
sub-tree.
PreOrder(cur->left);
PreOrder(root);
} PreOrder(cur-> right); // Process nodes in left sub-tree.
}
}

The Pre-order Traversal

cur

Output:
a bdec

cur

NULL NULL

NULL NULL

root
c
NULL NULL

void PreOrder(Node *cur)


void
{ PreOrder(Node *cur)
{
if (cur == NULL)
// if empty, return
main()
if (curreturn;
== NULL)
// if empty, return
{
return;
Node *root;
cout << cur->value;
// Process the current node.
cout << cur->value;
// Process the current node.
PreOrder(cur->left); // Process nodes in left sub-tree.
PreOrder(cur->left);
Process
nodes
in in
left
sub-tree.
PreOrder(cur-> right);////
Process
nodes
left
sub-tree.
PreOrder(root);
}PreOrder(cur-> right); // Process nodes in left sub-tree.
}
}

The In-order Traversal


1. Process the nodes in the left
sub-tree.
2. Process the current node.
3. Process the nodes in the right
cur
sub-tree.

root

NULL NULL

NULL NULL

void InOrder(Node *cur)


{
void InOrder(Node *cur)
if (cur == NULL)
// if empty, return
{
return;
if (cur == NULL)
// if empty, return
return;
InOrder(cur->left);
// Process nodes in left sub-tree.
InOrder(cur->left);
cout << cur->value;

cur

////Process
in left sub-tree.
Processnodes
the current
node.

cout
<< cur->value;right);
// Process
thenodes
current
node.
InOrder(cur->
// Process
in left
sub-tree.
}
InOrder(cur-> right); // Process nodes in left sub-tree.

Output:
b

The In-order Traversal


1. Process the nodes in the left
sub-tree.
2. Process the current node.
3. Process the nodes in the right
sub-tree.

b
NULL NULL

void InOrder(Node *cur)


{
void InOrder(Node *cur)
if (cur == NULL)
// if empty, return
{
return;
if (cur == NULL)
// if empty, return
return;
InOrder(cur->left);
// Process nodes in left sub-tree.
InOrder(cur->left);
cout << cur->value;

////Process
in left sub-tree.
Processnodes
the current
node.

cout
<< cur->value;right);
// Process
thenodes
current
node.
InOrder(cur->
// Process
in left
sub-tree.
}
InOrder(cur-> right); // Process nodes in left sub-tree.

root

cur

cur

c
NULL NULL

Output:
bac

The Post-order Traversal


1. Process the nodes in the left
sub-tree.
2. Process the nodes in the right
sub-tree.
cur
3. Process the current node.

cur

root

NULL NULL

NULL NULL

void PostOrder(Node *cur)


{
void PostOrder(Node *cur)
if (cur == NULL)
// if empty, return
{
return;
if (cur == NULL)
// if empty, return
return;
PostOrder(cur->left);
// Process nodes in left sub-tree.
PostOrder(cur->left);
Process
nodes
in in
left
sub-tree.
PostOrder(cur-> right);////
Process
nodes
right
sub-tree.

PostOrder(cur->
right); // Process the
nodes
in right
sub-tree.
cout << cur->value;
current
node.
}
cout << cur->value;
// Process the current node.

Output:
b

The Post-order Traversal


1. Process the nodes in the left
sub-tree.
2. Process the nodes in the right
sub-tree.
3. Process the current node.

cur
b
NULL NULL

void PostOrder(Node *cur)


{
void PostOrder(Node *cur)
if (cur == NULL)
// if empty, return
{
return;
if (cur == NULL)
// if empty, return
return;
PostOrder(cur->left);
// Process nodes in left sub-tree.
PostOrder(cur->left);
Process
nodes
in in
left
sub-tree.
PostOrder(cur-> right);////
Process
nodes
right
sub-tree.

PostOrder(cur->
right); // Process the
nodes
in right
sub-tree.
cout << cur->value;
current
node.
}
cout << cur->value;
// Process the current node.

root

cur

c
NULL NULL

Output:
bc a

The Level Order Traversal


In a level order traversal we visit each levels nodes, from
left to right, before visiting nodes in the next level.
temp 800
700
720
780

Heres the algorithm:


700
700
1. Use a temp pointer variable and
root
a
720780
a queue of node pointers.
2. Insert the root node pointer
720
780
c
b
into the queue.
NULL 900
800760
3. While the queue is not empty:
A. Dequeue the top node
760 e 900 f
800 d
pointer and put it in temp.
NULL NULL
NULL NULL
NULL NULL
B. Process the node.
C. Add the nodes children to
queue if they are not NULL.
700
780
720780
900
800760
900
760
800760
front
rear
a b c d Etc

Traversal Overview, Part 1


Pre-order
#1

In-order
root

#2
#15

#8

#17

#9

d
NULL

#6

NULL

#7

NULL NULL

#11

#12

1. Process current node


2. Traverse left
3. Traverse right

#15

#6
#4

c
#16

#8

d
NULL

#3

NULL

#5

#18

#10

NULL NULL

#9

#17

NULL NULL

#12

#2

#18

#10

#19
#13

#7

#16

NULL NULL

#13

#4

#5

root

#1

#19
#14

#3

#14

#11

1. Traverse left
2. Process current node
3. Traverse right

Traversal Overview, Part 2


Post-order
#19

Level-order
root

#1
#14

#2

#5

#15
#7

d
NULL

#3

NULL

#4

root

#10

#9

1. Traverse left
2. Traverse right
3. Process current node

#3

NULL NULL

#16

NULL NULL

#8

#2

#17

NULL NULL

#11
#6

#18
#13

#12

#1

#4

d
NULL

NULL

#5

NULL NULL

Big-Oh of Traversals?
Question: Whatre the big-ohs of each of our traversals?
Answer: Well, since a traversal must visit each node
exactly once
and since there are n nodes in a tree
the big-oh for any of the traversals is

O(n)

Traversal Challenge
RULES
The class will split into
left and right teams
One student from each
team will come up to the
board
Each student can either
write one new item or
fix a single error in
their teammates
solution
Then the next two people
come up, etc.
The team that completes
their program first wins!

Challenge: What order will the


following nodes be printed out if
we use an in-order traversal?
root

Larry

Fran

Ronda
NULL

Danny

Jack

NULL NULL

NULL NULL

Tom
NULL

Sam
NULL NULL

Expression Evaluation
We can represent arithmetic expressions using a
binary tree.

ptr

For example, the tree on


the left represents the
expression: (5+6)*(3-1)
Once you have an expression
in a tree, its easy to
evaluate it and get the
result.
Lets see how!

Expression Evaluation
Heres our evaluation function. We start by passing in a
pointer to the root of the tree.

cu
r

1. If the current node is a


1. Ifnumber,
the current
node
is
a
return
its
value.
1. If
the current
node
is a
ptr
number,
return
its value.
2.
Recursively
number,
returnevaluate
its value.the left
2. Recursively
evaluate
the
left
cur
subtree
and
get
the
result.
2. Recursively
evaluate
left
subtree and
get thethe
result.
3.
Recursively
the right
subtree
and getevaluate
the result.
3. Recursively
evaluate
the
right
subtree
and
get
the
result.
3. Recursively
evaluate
right
cur
subtree and
get thethe
result.
4.
Applyand
theget
operator
in the
subtree
the result.
4. Apply
the node
operator
in the
current
to
the
left and
4. Apply
the
operator
in
the
current
node toreturn
the left
and
right
results;
the
current
node toreturn
the left
and
right
results;
the
result.
right
results; return the
result.
result.

(5+6)*(3-1)

Expression Evaluation
Heres our evaluation function. We start by passing in a
pointer to the root of the tree.

cu
r

1. If the current node is a


1. Ifnumber,
the current
node
is a
return
its
value.
1. If
the current
node
is a
ptr
number,
return
its value.
2.number,
Recursively
the left
returnevaluate
its value.
2. Recursively
evaluate
the
left
cur
subtree
and
get
the
result.
2. Recursively
evaluate
left
Result
= 5the
subtree and
get the
result.
3.subtree
Recursively
evaluate
the right
and get
the result.
3. Recursively
evaluate
the
right
subtree
and
get
the
result.
3. Recursively
evaluate
right
cur
subtree and
get thethe
result.
4.subtree
Apply and
the get
operator
in the
the result.
4. Apply
thenode
operator
in left
the and
current
to
the
4. Apply
thenode
operator
in left
the and
current
to
the
right results;
return
the
current
node
to
the
left
and
right
results;
return
the
result.
right
results; return the
result.
result.

(5+6)*(3-1)

Expression Evaluation
Heres our evaluation function. We start by passing in a
pointer to the root of the tree.
1. If the current node is a
1. If
the current
node
is a
number,
return
its value.
number, return its value.
2. Recursively evaluate the left
2. Recursively
evaluate
left
Result
= 5the
subtree and
get the
result.
subtree and get the result.
3. Recursively evaluate the right
3. Recursively
evaluate
right
Result
= 6the
subtree and
get the
result.
subtree and get the result.
4. Apply the operator in the
4. Apply
thenode
operator
in left
the and
current
to the
current
node toreturn
the left
right results;
theand
right
results; return the
result.
result.

(5+6)*(3-1)
ptr
cur
cur

5+6 = 11

Expression Evaluation
Heres our evaluation function. We start by passing in a
pointer to the root of the tree.
1. If the current node is a
1. If
the current
node
is a
number,
return
its value.
number, return its value.
2. Recursively evaluate the left
2. Recursively
evaluate
left
Result
= 3the
subtree Result
and
get=the
11 result.
subtree and get the result.
3. Recursively evaluate the right
3. Recursively
evaluate
right
Result
= 1the
subtree and
get the
result.
subtree and get the result.
4. Apply the operator in the
4. Apply
thenode
operator
in left
the and
current
to the
current
node toreturn
the left
right results;
theand
right
results; return the
result.
result.

(5+6)*(3-1)
ptr
cur

r
u
c

3-1 = 2

Expression Evaluation
Heres our evaluation function. We start by passing in a
pointer to the root of the tree.
The result is 22.
1. If the current node is a
number, return its value.
2. Recursively evaluate the left
Result = 11
subtree and get the result.

(5+6)*(3-1)
ptr
cur

3. Recursively evaluate the right


Result
= 2 result.
subtree and
get the
4. Apply the operator in the
current node to the left and
right results; return the
result.

11*2=22
3-1
=2

Expression Evaluation
Heres our evaluation function. We start by passing in a
pointer to the root of the tree.

1. If the current node is a


number, return its value.
2. Recursively evaluate the left
subtree and get the result.
3. Recursively evaluate the right
subtree and get the result.
4. Apply the operator in the
current node to the left and
right results; return the
result.

Question: Which other


algorithm does this remind
you of?

Binary Search Trees


Binary Search Trees are a type of binary tree with
specific properties that make them very efficient to
search for a value in the tree.
root

Larry

Like regular Binary Trees,


we store and search for
values in Binary Search
Trees
Heres an example BST

Fran

Ronda
NULL

Danny

Jack

NULL NULL

NULL NULL

Tom
NULL

Sam
NULL NULL

Binary Search Trees


BST Definition: A Binary Search Tree is a binary tree
with the following two properties:
Given any node in the binary tree,
all nodes in its left sub-tree must
be less than the nodes value.
Given any node in the binary tree,
all nodes in its right sub-tree must
be greater than the nodes value.
Lets validate that this
is a valid BST

root

Larry

Fran

Ronda
NULL

Danny

Jack

NULL NULL

NULL NULL

Tom
NULL

Sam
NULL NULL

Binary Search Trees


Question: Which of the following are valid BSTs?
Larry

Larry

NULL

Fran
NULL

Fran

Ronda
NULL NULL

Danny
NULL

Danny

Nick

NULL NULL

NULL NULL

Manny

Alex

Amy

NULL NULL

NULL NULL

Nick
NULL

Maddy
NULL NULL

Operations on a Binary Search Tree


Heres what we can do to a BST:
Determine if the binary search tree is empty
Search the binary search tree for a value
Insert an item in the binary search tree
Delete an item from the binary search tree
Find the height of the binary search tree
Find the number of nodes and leaves in the
binary search tree
Traverse the binary search tree
Free the memory used by the binary search tree

Searching a BST
Input: A value V to search for
Output: TRUE if found, FALSE otherwise
Start at the root of the tree
Keep going until we hit the NULL pointer
If V is equal to current nodes value, then found!
If V is less than current nodes value, go left
If V is greater than current nodes value, go right
If we hit a NULL pointer, not found.
Gary
Larry??
Gary==
<==
> Fran??
Larry??
Fran??
Fran??
Gary??

Larry

Fran

Ronda
NULL NULL

Lets search for


Gary.

Barry

Gary

NULL NULL

NULL NULL

Searching a BST
Start at the root of the tree
Keep going until we hit the NULL pointer
If V is equal to current nodes value, then found!
If V is less than current nodes value, go left
If V is greater than current nodes value, go right
If we hit a NULL pointer, not found.
Show how to search for:
1. Khang
2. Dale
3. Sam

Searching a BST
Here are two different BST search algorithms in C++,
one recursive and one iterative:

bool Search(int V, Node *ptr)


{
if (ptr == NULL)
return(false); // nope
else if (V == ptr->value)
return(true); // found!!!
else if (V < ptr->value)
return(Search(V,ptr->left));
else
return(Search(V,ptr->right));
}

bool Search(int V,Node *ptr)


{
while (ptr != NULL)
{
if (V == ptr->value)
return(true);
else if (V < ptr->value)
ptr = ptr->left;
else
ptr = ptr->right;
}
return(false); // nope
}

Lets trace through the recursive version

Recursive BST Search


Lets search for 14.

pRoot

14 ==
13??
< 17??
13??
17??
14??

ptr->

13

bool Search(int V, Node *ptr)


bool
Search(int V, Node *ptr)
{
ptr-> 17
7
{ if (ptr == NULL)
NULL
bool
V, Node
if Search(int
(ptr == NULL)
return(false);
// *ptr)
nope
true
{ else
return(false);
//
nope
if (V == ptr->value)
if
(ptr
else
if ==
(V NULL)
== ptr->value)
return(true);
// found!!!
ptr-> 14
3
19
return(false);
// found!!!
nope
return(true);
//
else
if (V < ptr->value)
NULL NULL
NULL NULL
NULL NULL
else
if
(V
==
ptr->value)
else
if
(V
<
ptr->value)
return(Search(V,ptr->left));
return(true);
// found!!!
return(Search(V,ptr->left));
else
void main(void)
else
if
(V
<
ptr->value)
else
return(Search(V,ptr->right));
return(Search(V,ptr->right)); {
} return(Search(V,ptr->left));
bool bFnd;
} else
bFnd = Search(14,pRoot);
return(Search(V,ptr->right));
}
}

Recursive BST Search


Lets search for 14.

pRoot

ptr->
bool Search(int V, Node *ptr)
{
bool
V, Node *ptr)
if Search(int
(ptr == NULL)
{
return(false); // nope
if
(ptr
else
if ==
(V NULL)
== ptr->value)
return(false);
// found!!!
nope
return(true); //
else
ptr->value)
else if
if (V
(V ==
< ptr->value)
return(true);
//
found!!!
true
return(Search(V,ptr->left));
else
else if (V < ptr->value)
return(Search(V,ptr->left));
return(Search(V,ptr->right));
} else
return(Search(V,ptr->right));
}

7
NULL

13

ptr->

17

true

3
NULL NULL

true

14

19

NULL NULL

NULL NULL

void main(void)
{
bool bFnd;
bFnd = Search(14,pRoot);
}

Recursive BST Search


Lets search for 14.

pRoot

true

ptr->

13

true
17

7
bool Search(int V, Node *ptr)
{
if (ptr == NULL)
return(false); // nope
else if (V == ptr->value)
return(true); // found!!!
else if (V < ptr->value)
return(Search(V,ptr->left));
else
true
return(Search(V,ptr->right));
}

NULL

true

3
NULL NULL

14

19

NULL NULL

NULL NULL

void main(void)
{
bool bFnd;
bFnd = Search(14,pRoot);
true
}

Big Oh of BST Search


Question:
In the average BST with N values,
how many steps are required to
find our value?

Right! log2(N) steps


Question:
In the worst case BST with
N values, how many steps are
required find our value?

50%
eliminated!

50% eliminated!

50%
eliminated!
50%
eliminated!

Right! N steps
Question:
If there are 4 billion nodes in a BST, how
many steps will it take to perform a search?

Just 32!

WOW!
Now thats PIMP!

Inserting A New Value Into A BST


To insert a new node in our BST, we must place the
new node so that the resulting tree is still a valid
BST!
Where would the following
new values go?
Carly
Ken
Alice
Ken
Alice

Carly

Inserting A New Value Into A BST


Input: A value V to insert
If the tree is empty
Allocate a new node and put V into it
Point the root pointer to our new node. DONE!
Start at the root of the tree
While were not done
If V is equal to current nodes value, DONE!
If V is less than current nodes value

(nothing to do...)

If there is a left child, then go left


ELSE allocate a new node and put V into it, and
set current nodes left pointer to new node. DONE!

If V is greater than current nodes value

If there is a right child, then go right


ELSE allocate a new node and put V into it,
set current nodes right pointer to new node. DONE!

Now the C++ Code!

void insert(const std::string


&value)
heres
our Binary Search
Just And
as with
a regular
{

if (m_root == NULL)
binary tree, we Tree
use a class.
node
However
lets
add
a
constructor to
{ m_root = struct
new Node(value);
to hold ourreturn;
items.}

If our tree is
our
Node
so
we
can
easily
create
a
class
BinarySearchTree
Node
*cur = m_root;
empty,
new
one!
{struct
for (;;)
Node
Startallocate
traversing
a
And our constructor initializes that
public:
{ {
down
newfrom
nodethe
and
root pointer to NULL
if (value == cur->value) return;
Node(const std::string &myVal)
If our
value
is
root
of
the
tree.
point
the
when
we
create
a
new
tree.
if
(value
<
cur->value)
BinarySearchTree()
{ {
If
already
the
value
the
to
for(;;)
isinthe
(This indicates the tree is empty)
root
pointer
{ valueif= (cur->left
myVal;
!= NULL)
tree,
insert
then
is
less
were
same
as
an a
If
there
is
to
it

then
m_root
=
NULL;
cur
=
cur->left;
Now
lets
see
our
complete
left = right = NULL;
than
done
the
-current
just
infinite
loop.
to our
left,
done!
}}
else
insertion function in C++. nodewere
{

cur->left = new Node(value);

void
insert(const
std::string
value;std::string &value)
return;
{Node }
*left,*right;
}; }
else if (value > cur->value)
}
Our BST class has a single
{
private:
};

if (cur->right != NULL)
member variable the root
cur = cur->right; pointer to the tree.
else

{
Node *m_root;

cur->right = new Node(value);


return;

nodes
return.
value,
Otherwise
advance
to weve
that
then
goand
left.
found
the
node
proper
spot for
continue.
our new value!
Add
ourvalue
valuewe
as
If the
the
child of
wantleft
to insert
is
greater
than the
the current
current
nodes
node.
value, then
traverse/insert
to the right.

void insert(const std::string &value)


{

if (m_root == NULL)
{ m_root = new Node(value);

m_root NULL

return; }

Larry

Node *cur = m_root;


for (;;)
{

if (value == cur->value)
if (value < cur->value)
{

NULL NULL

return;

if (cur->left != NULL)
cur = cur->left;
else
{

cur->left = new Node(value);


return;

else if (value > cur->value)


{

if (cur->right != NULL)
cur = cur->right;
else

void main(void)
{
BinarySearchTree bst;
bst.insert(Larry);

cur->right = new Node(value);


return;

...
bst.insert(Phil);
}

void insert(const std::string &value)


{

if (m_root == NULL)
{ m_root = new Node(value);

m_root

return; }

cur

Node *cur = m_root;


for (;;)
{

Phil == Ronda??
Larry??
if (value
cur->value)
Phil <==Larry??
Ronda??

Phil > Larry??

if (cur->right != NULL)
cur = cur->right;
else

Ronda
NULL NULL

Barry

cur->left = new Node(value);


return;

else if (value > cur->value)

Fran

if (cur->left != NULL)
cur = cur->left;
else
{

return;

if (value < cur->value)


{

Larry

NULL NULL

Phil

NULL NULL

void main(void)
{
BinarySearchTree bst;
bst.insert(Larry);

cur->right = new Node(value);


return;

...
bst.insert(Phil);
}

Inserting A New Value Into A BST


As with BST Search, there is a recursive version of
the Insertion algorithm too. Be familiar with it!
Question:
Given a random array of numbers if you insert them one
at a time into a BST, what will the BST look like?
Question:
Given a ordered array of numbers if you insert them
one at a time into a BST, what will the BST look like?

Big Oh of BST Insertion


So, whats the big-oh of BST Insertion?
Right! Its also O(log2n)
Why? Because we have to first use a binary search to find
where to insert our node and binary search is O(log2n).
Once weve found the right spot, we can insert our new
node in O(1) time.

Groovy Baby!

Finding Min & Max of a BST


How do we find the minimum and maximum values in a BST?
The minimum value is located at the left-most node.
The maximum value is located at the right-most node.
int GetMin(node *pRoot)
int GetMax(node *pRoot)
Larry
{
{
if (pRoot == NULL)
if (pRoot == NULL)
return(-1); // empty
return(-1); // empty
Ronda
Fran
NULL NULL
while (pRoot->left != NULL)
while
(pRoot->right != NULL)
pRoot = pRoot->left;
pRoot = pRoot->right;
}

Barry
return(pRoot->value);
NULL
NULL

Phil
return(pRoot->value);

NULL NULL

Question: Whats the big-oh to find the minimum or


maximum element?

Finding Min & Max of a BST


And here are recursive versions for you
int GetMin(node *pRoot)
{
if (pRoot == NULL)
return(-1); // empty

int GetMax(node *pRoot)


{
if (pRoot == NULL)
return(-1); // empty

if (pRoot->left == NULL)
return(pRoot->value);

if (pRoot->right == NULL)
return(pRoot->value);

return(GetMin(pRoot->left));

return(GetMax(pRoot->right));
}

Hopefully youre getting the idea that most tree


functions can be done recursively

Printing a BST In Alphabetical Order


Can anyone guess
what algorithm we
use to print out a
BST in alphabetical
order?

cur
cur
cur

danny cur

bill
NULL NULL

void InOrder(Node *cur)


Big-oh Alert!
{
if (cur == NULL)
// if empty, return
return; the big-Oh of printing
So whats

InOrder(cur->left);
// Process
nodes in left sub-tree.
all the items in the
tree?
cout << cur->value;

// Process the current node.

Right! O(n) since we have to visit


InOrder(cur-> right); // Process nodes in left sub-tree.
and print all n items.
}

root

jane

waa
NULL NULL

frank
NULL NULL

Output:
bill
danny
frank
jane
waa

cur

Freeing The Whole Tree


When we are done with our BST, we have to free every
node in the tree, one at a time.
Question: Can anyone think of an algorithm for this?
void FreeTree(Node *cur)
{
if (cur == NULL)
// if empty, return
return;
FreeTree(cur->left);

// Delete nodes in left sub-tree.

FreeTree (cur-> right); // Delete nodes in left sub-tree.


}

delete cur;

// Free the current node

Freeing The Whole Tree


cur-> Larry

cur = NULL
void FreeTree(Node *cur)
{ FreeTree(Node *cur)
void
if (cur == NULL)
{ FreeTree(Node
void
*cur)
if (curreturn;
== NULL)
{ FreeTree(Node
void
*cur)
return;
if (cur
== NULL)
{
FreeTree(cur->left);
return;
if (curFreeTree(cur->left);
== NULL)
FreeTree (cur-> right);
return;
FreeTree(cur->left);
FreeTree (cur-> right);
FreeTree(cur->left);
delete(cur->
cur; right);
FreeTree
}
delete
cur; right);
FreeTree
(cur->
}
delete
cur;
}
delete
cur;
}

cur-> Fran

Ronda
NULL NULL

cur-> Barry
NULL NULL

Gabby
NULL NULL

Freeing The Whole Tree


cur-> Larry
cur-> Fran

Ronda
NULL NULL

void FreeTree(Node *cur)


{ FreeTree(Node *cur)
void
if (cur == NULL)
{ FreeTree(Node
void
*cur)
if (curreturn;
== NULL)
{
return;
if (curFreeTree(cur->left);
== NULL)
return;
FreeTree(cur->left);
FreeTree (cur-> right);
FreeTree(cur->left);
FreeTree (cur-> right);
delete(cur->
cur; right);
FreeTree
}
delete
cur;
}
delete
cur;
}

cur-> Barry
NULL NULL

Gabby
NULL NULL

Freeing The Whole Tree


cur-> Larry
cur-> Fran

Ronda
NULL NULL

void FreeTree(Node *cur)


void
{ FreeTree(Node *cur)
{ FreeTree(Node
if (cur == NULL)
void
*cur)
if (curreturn;
== NULL)
{
if (curreturn;
== NULL)
FreeTree(cur->left);
return;
FreeTree(cur->left);
FreeTree (cur-> right);
FreeTree(cur->left);
FreeTree (cur-> right);
delete(cur->
cur; right);
FreeTree
delete
cur;
}
}
delete
cur;
}

cur-> Gabby
NULL NULL

Freeing The Whole Tree


cur-> Larry
cur-> Fran

Ronda
NULL NULL

void FreeTree(Node *cur)


{ FreeTree(Node *cur)
void
if (cur == NULL)
{
if (curreturn;
== NULL)
return;
FreeTree(cur->left);

FreeTree(cur->left);
FreeTree (cur-> right);
FreeTree (cur-> right);
delete cur;
}
delete
cur;

Big-oh Alert!
And so on
So whats the big-Oh of freeing
all the items in the tree?
Its still O(n) since we have
to visit all n items.

Appendix Slides

You might also like