0% found this document useful (0 votes)
27 views52 pages

Lecture12 Updated

The document discusses different tree traversal algorithms including pre-order, in-order, and post-order traversal. It provides pseudocode for pre-order and in-order traversal functions that recursively process each node in the tree. It also includes an example binary tree and sample output for each traversal type.

Uploaded by

Damion Sullivan
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
27 views52 pages

Lecture12 Updated

The document discusses different tree traversal algorithms including pre-order, in-order, and post-order traversal. It provides pseudocode for pre-order and in-order traversal functions that recursively process each node in the tree. It also includes an example binary tree and sample output for each traversal type.

Uploaded by

Damion Sullivan
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 52

1

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
2
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!
3
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.

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
NULL
a
b c
NULL
d
NULL NULL NULL
e
NULL
root
4
void PreOrder(Node *cur)
{
if (cur == NULL) // if empty, return
return;

cout << cur->value; // Process the current node.

PreOrder(cur->left); // Process nodes in left sub-tree.
PreOrder(cur-> right); // Process nodes in left sub-tree.
}
main()
{
Node *root;

PreOrder(root);
}
NULL
a
b c
NULL
d
NULL NULL NULL
e
NULL
root
cur
Output:
a b
The Pre-order Traversal
d
void PreOrder(Node *cur)
{
if (cur == NULL) // if empty, return
return;

cout << cur->value; // Process the current node.

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

cout << cur->value; // Process the current node.

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

cout << cur->value; // Process the current node.

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

cout << cur->value; // Process the current node.

PreOrder(cur->left); // Process nodes in left sub-tree.
PreOrder(cur-> right); // Process nodes in left sub-tree.
}
main()
{
Node *root;

PreOrder(root);
}
NULL
a
b c
NULL
d
NULL NULL NULL
e
NULL
root
cur
Output:
a b d
void PreOrder(Node *cur)
{
if (cur == NULL) // if empty, return
return;

cout << cur->value; // Process the current node.

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

cout << cur->value; // Process the current node.

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

cout << cur->value; // Process the current node.

PreOrder(cur->left); // Process nodes in left sub-tree.
PreOrder(cur-> right); // Process nodes in left sub-tree.
}
The Pre-order Traversal
NULL
cur
6
void PreOrder(Node *cur)
{
if (cur == NULL) // if empty, return
return;

cout << cur->value; // Process the current node.

PreOrder(cur->left); // Process nodes in left sub-tree.
PreOrder(cur-> right); // Process nodes in left sub-tree.
}
main()
{
Node *root;

PreOrder(root);
}
NULL
a
b c
NULL
d
NULL NULL NULL
e
NULL
root
cur
Output:
a b d
void PreOrder(Node *cur)
{
if (cur == NULL) // if empty, return
return;

cout << cur->value; // Process the current node.

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

cout << cur->value; // Process the current node.

PreOrder(cur->left); // Process nodes in left sub-tree.
PreOrder(cur-> right); // Process nodes in left sub-tree.
}
cur
The Pre-order Traversal
7
void PreOrder(Node *cur)
{
if (cur == NULL) // if empty, return
return;

cout << cur->value; // Process the current node.

PreOrder(cur->left); // Process nodes in left sub-tree.
PreOrder(cur-> right); // Process nodes in left sub-tree.
}
main()
{
Node *root;

PreOrder(root);
}
NULL
a
b c
NULL
d
NULL NULL NULL
e
NULL
root
cur
Output:
a b d
void PreOrder(Node *cur)
{
if (cur == NULL) // if empty, return
return;

cout << cur->value; // Process the current node.

PreOrder(cur->left); // Process nodes in left sub-tree.
PreOrder(cur-> right); // Process nodes in left sub-tree.
}
cur
The Pre-order Traversal
void PreOrder(Node *cur)
{
if (cur == NULL) // if empty, return
return;

cout << cur->value; // Process the current node.

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

cout << cur->value; // Process the current node.

PreOrder(cur->left); // Process nodes in left sub-tree.
PreOrder(cur-> right); // Process nodes in left sub-tree.
}
main()
{
Node *root;

PreOrder(root);
}
NULL
a
b c
NULL
d
NULL NULL NULL
e
NULL
root
cur
Output:
a b d
void PreOrder(Node *cur)
{
if (cur == NULL) // if empty, return
return;

cout << cur->value; // Process the current node.

PreOrder(cur->left); // Process nodes in left sub-tree.
PreOrder(cur-> right); // Process nodes in left sub-tree.
}
cur
The Pre-order Traversal
e
9
void PreOrder(Node *cur)
{
if (cur == NULL) // if empty, return
return;

cout << cur->value; // Process the current node.

PreOrder(cur->left); // Process nodes in left sub-tree.
PreOrder(cur-> right); // Process nodes in left sub-tree.
}
main()
{
Node *root;

PreOrder(root);
}
NULL
a
b c
NULL
d
NULL NULL NULL
e
NULL
root
cur
Output:
a b d
The Pre-order Traversal
e
void PreOrder(Node *cur)
{
if (cur == NULL) // if empty, return
return;

cout << cur->value; // Process the current node.

PreOrder(cur->left); // Process nodes in left sub-tree.
PreOrder(cur-> right); // Process nodes in left sub-tree.
}
cur
c
10
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.

void InOrder(Node *cur)
{
if (cur == NULL) // if empty, return
return;

InOrder(cur->left); // Process nodes in left sub-tree.

cout << cur->value; // Process the current node.

InOrder(cur-> right); // Process nodes in left sub-tree.
}
NULL
a
b c
NULL NULL NULL
root
Output:
cur
void InOrder(Node *cur)
{
if (cur == NULL) // if empty, return
return;

InOrder(cur->left); // Process nodes in left sub-tree.

cout << cur->value; // Process the current node.

InOrder(cur-> right); // Process nodes in left sub-tree.
}
cur
b
11
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.

void InOrder(Node *cur)
{
if (cur == NULL) // if empty, return
return;

InOrder(cur->left); // Process nodes in left sub-tree.

cout << cur->value; // Process the current node.

InOrder(cur-> right); // Process nodes in left sub-tree.
}
NULL
a
b c
NULL NULL NULL
root
Output:
cur
b a
void InOrder(Node *cur)
{
if (cur == NULL) // if empty, return
return;

InOrder(cur->left); // Process nodes in left sub-tree.

cout << cur->value; // Process the current node.

InOrder(cur-> right); // Process nodes in left sub-tree.
}
cur
c
12
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.

void PostOrder(Node *cur)
{
if (cur == NULL) // if empty, return
return;

PostOrder(cur->left); // Process nodes in left sub-tree.

PostOrder(cur-> right); // Process nodes in right sub-tree.

cout << cur->value; // Process the current node.
}
Output:
NULL
a
b c
NULL NULL NULL
root
cur
void PostOrder(Node *cur)
{
if (cur == NULL) // if empty, return
return;

PostOrder(cur->left); // Process nodes in left sub-tree.

PostOrder(cur-> right); // Process nodes in right sub-tree.

cout << cur->value; // Process the current node.
}
cur
b
13
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.

void PostOrder(Node *cur)
{
if (cur == NULL) // if empty, return
return;

PostOrder(cur->left); // Process nodes in left sub-tree.

PostOrder(cur-> right); // Process nodes in right sub-tree.

cout << cur->value; // Process the current node.
}
Output:
NULL
a
b c
NULL NULL NULL
root
cur
b
void PostOrder(Node *cur)
{
if (cur == NULL) // if empty, return
return;

PostOrder(cur->left); // Process nodes in left sub-tree.

PostOrder(cur-> right); // Process nodes in right sub-tree.

cout << cur->value; // Process the current node.
}
cur
c a
14
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.
NULL
a
b c
d
NULL NULL NULL
e
NULL
root
Heres the algorithm:
1. Use a temp pointer variable and
a queue of node pointers.
2. Insert the root node pointer
into the queue.
3. While the queue is not empty:
A. Dequeue the top node
pointer and put it in temp.
B. Process the node.
C. Add the nodes children to
queue if they are not NULL.
front rear
700
720 780
800 760
720 780
800 760
700
700
temp
700
a
720 780
720
780
b
800 760
780
800 760
c
NULL
f
NULL
900
900
900
800
760 900

d Etc
Traversal Overview, Part 1
15
NULL
a
b
c
NULL
d
NULL
NULL NULL
e
NULL
root
Pre-order
#1
#2
#3
#4
#5
#8 #9
#10
#13
#14
#15
#16
#19
NULL
a
b
c
NULL
d
NULL
NULL NULL
e
NULL
root
In-order
#14
#1
#7
#2
#4
#6 #8
#10
#12
#13
#15
#17
#19
#6 #7 #11 #12
#17 #18
#3 #5
#9 #11
#16 #18
1. Process current node
2. Traverse left
3. Traverse right
1. Traverse left
2. Process current node
3. Traverse right
Traversal Overview, Part 2
16
NULL
a
b
c
NULL
d
NULL
NULL NULL
e
NULL
root
Post-order
#19
#1
#12
#2
#5
#6 #7
#10
#11
#13
#14
#17
#18
NULL
a
b
c
NULL
d
NULL
NULL NULL
e
NULL
root
Level-order
#1
#2
#4
#5
#3
#3 #4
#8 #9
#15 #16
1. Traverse left
2. Traverse right
3. Process current node
17
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)
18
Traversal Challenge
Challenge: What order will the
following nodes be printed out if
we use an in-order traversal?
NULL
Larry
Fran Ronda
Danny
NULL NULL
NULL
Jack
NULL
root
Tom
NULL
Sam
NULL NULL
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!
RULES
19
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!
20
Expression Evaluation
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.

ptr
(5+6)*(3-1)
Heres our evaluation function. We start by passing in a
pointer to the root of the tree.
cur
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.
cur
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.
21
Expression Evaluation
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.

ptr
(5+6)*(3-1)
Heres our evaluation function. We start by passing in a
pointer to the root of the tree.
cur
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.
cur
Result = 5
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.
22
Expression Evaluation
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.

ptr
(5+6)*(3-1)
Heres our evaluation function. We start by passing in a
pointer to the root of the tree.
cur
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.
cur
Result = 5
Result = 6
5+6 = 11
23
Expression Evaluation
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.

ptr
(5+6)*(3-1)
Heres our evaluation function. We start by passing in a
pointer to the root of the tree.
cur
3-1 = 2
Result = 11
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.
Result = 3
Result = 1
24
Expression Evaluation
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.

ptr
(5+6)*(3-1)
Heres our evaluation function. We start by passing in a
pointer to the root of the tree.
cur
3-1 = 2
Result = 11
Result = 2
11*2=22
The result is 22.
25
Expression Evaluation
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.
Heres our evaluation function. We start by passing in a
pointer to the root of the tree.
Question: Which other
algorithm does this remind
you of?
26
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.
Like regular Binary Trees,
we store and search for
values in Binary Search
Trees

Heres an example BST
NULL
Larry
Fran Ronda
Danny
NULL NULL
NULL
Jack
NULL
root
Tom
NULL
Sam
NULL NULL
27
Binary Search Trees
BST Definition: A Binary Search Tree is a binary tree
with the following two properties:
NULL
Larry
Fran Ronda
Danny
NULL NULL
NULL
Jack
NULL
root
Tom
NULL
Sam
NULL NULL
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
28
Binary Search Trees
Question: Which of the following are valid BSTs?
NULL
Larry
Fran Ronda
Danny
NULL NULL
NULL
Nick
NULL
NULL
Larry
Fran
Danny
NULL
NULL
Alex
NULL NULL
NULL
Manny
Amy Nick
NULL
Maddy
NULL
NULL NULL NULL
29
Operations on a Binary Search Tree
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

Heres what we can do to a BST:
30
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.
NULL
Larry
Fran Ronda
NULL NULL
NULL
Gary
NULL
NULL
Barry
Lets search for
Gary.
Gary == Larry??
Gary < Larry?? Gary == Fran?? Gary < Fran?? Gary > Fran?? Gary == Gary??
31
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

32
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
33
Recursive BST Search
Lets search for 14.
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));
}
13
7 17
NULL NULL
NULL
NULL
3
NULL NULL
14 19
NULL
pRoot
void main(void)
{
bool bFnd;
bFnd = Search(14,pRoot);
}
ptr->
14 == 13?? 14 < 13??
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));
}
ptr->
14 == 17?? 14 < 17??
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));
}
14 == 14??
ptr->
true
34
Recursive BST Search
Lets search for 14.
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));
}
13
7 17
NULL NULL
NULL
NULL
3
NULL NULL
14 19
NULL
pRoot
void main(void)
{
bool bFnd;
bFnd = Search(14,pRoot);
}
ptr->
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));
}
ptr->
true
true
true
35
Recursive BST Search
Lets search for 14.
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));
}
13
7 17
NULL NULL
NULL
NULL
3
NULL NULL
14 19
NULL
pRoot
void main(void)
{
bool bFnd;
bFnd = Search(14,pRoot);
}
ptr->
true true
true
true
true
36
Big Oh of BST Search
Question:
In the average BST with N values,
how many steps are required to
find our value?
Question:
In the worst case BST with
N values, how many steps are
required find our value?
Question:
If there are 4 billion nodes in a BST, how
many steps will it take to perform a search?
WOW!
Now thats PIMP!
50% eliminated!
50%
eliminated!
50%
eliminated!
50%
eliminated!
Right! log
2
(N) steps
Right! N steps
Just 32!
37
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
Carly
Ken
Ken
Alice
Alice
38
Inserting A New Value Into A BST
If the tree is empty
Allocate a new node and put V into it
Point the root pointer to our new node. DONE!
Input: A value V to insert

Start at the root of the tree
While were not 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!
If V is equal to current nodes value, DONE! (nothing to do...)
If V is less than current nodes value
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!
39
Now the C++ Code!
struct Node
{






std::string value;
Node *left,*right;
};
Just as with a regular
binary tree, we use a node
struct to hold our items.
However lets add a constructor
to our Node so we can easily
create a new one!
Node(const std::string &myVal)
{
value = myVal;
left = right = NULL;
}

class BinarySearchTree
{
public:

BinarySearchTree()
{
m_root = NULL;
}

void insert(const std::string &value)
{

}

private:

Node *m_root;
};

Our BST class has a single
member variable the root
pointer to the tree.
And our constructor initializes that
root pointer to NULL
when we create a new tree.
(This indicates the tree is empty)
And heres our Binary Search
Tree class.
Now lets see our complete
insertion function in C++.
void insert(const std::string &value)
{
if (m_root == NULL)
{ m_root = new Node(value); return; }
Node *cur = m_root;
for (;;)
{
if (value == cur->value) return;
if (value < cur->value)
{
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
{
cur->right = new Node(value);
return;
}
}
}
}
If our tree is
empty,
allocate a
new node and
point the
root pointer
to it then
were done!
Start traversing
down from the
root of the tree.
for(;;) is the
same as an
infinite loop.
If our value is
already in the
tree, then were
done - just
return.
If the value to
insert is less
than the current
nodes value,
then go left.
If there is a
node to our left,
advance to that
node and
continue.
Otherwise weve
found the
proper spot for
our new value!
Add our value
as the left child
of the current
node.
If the value we
want to insert is
greater than the
current nodes
value, then
traverse/insert
to the right.
40
void insert(const std::string &value)
{
if (m_root == NULL)
{ m_root = new Node(value); return; }
Node *cur = m_root;
for (;;)
{
if (value == cur->value) return;
if (value < cur->value)
{
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
{
cur->right = new Node(value);
return;
}
}
}
}
void main(void)
{
BinarySearchTree bst;
bst.insert(Larry);
...
bst.insert(Phil);
}
m_root
NULL

Larry
NULL
NULL
41
void insert(const std::string &value)
{
if (m_root == NULL)
{ m_root = new Node(value); return; }
Node *cur = m_root;
for (;;)
{
if (value == cur->value) return;
if (value < cur->value)
{
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
{
cur->right = new Node(value);
return;
}
}
}
}
void main(void)
{
BinarySearchTree bst;
bst.insert(Larry);
...
bst.insert(Phil);
}
m_root
NULL
Larry
Fran Ronda
NULL NULL
NULL
Barry


Phil == Larry??
Phil < Larry??
Phil > Larry??
?
Phil == Ronda??
Phil < Ronda??
?
Phil
NULL
NULL
cur
42
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?
43
Big Oh of BST Insertion
So, whats the big-oh of BST Insertion?
Right! Its also O(log
2
n)

Why? Because we have to first use a binary search to find
where to insert our node and binary search is O(log
2
n).

Once weve found the right spot, we can insert our new
node in O(1) time.
Groovy Baby!
44
Question: Whats the big-oh to find the minimum or
maximum element?
NULL
Larry
Fran Ronda
NULL NULL
NULL
Barry

Phil
NULL
NULL
Finding Min & Max of a BST
How do we find the minimum and maximum values in a BST?

int GetMin(node *pRoot)
{
if (pRoot == NULL)
return(-1); // empty

while (pRoot->left != NULL)
pRoot = pRoot->left;

return(pRoot->value);
}
int GetMax(node *pRoot)
{
if (pRoot == NULL)
return(-1); // empty

while (pRoot->right != NULL)
pRoot = pRoot->right;

return(pRoot->value);
}
The minimum value is located at the left-most node.
The maximum value is located at the right-most node.
45
Hopefully youre getting the idea that most tree
functions can be done recursively
Finding Min & Max of a BST
And here are recursive versions for you

int GetMin(node *pRoot)
{
if (pRoot == NULL)
return(-1); // empty

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

return(GetMin(pRoot->left));
}
int GetMax(node *pRoot)
{
if (pRoot == NULL)
return(-1); // empty

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

return(GetMax(pRoot->right));
}
46
void InOrder(Node *cur)
{
if (cur == NULL) // if empty, return
return;

InOrder(cur->left); // Process nodes in left sub-tree.

cout << cur->value; // Process the current node.

InOrder(cur-> right); // Process nodes in left sub-tree.
}
NULL
jane
danny waa
NULL
bill
NULL NULL NULL
frank
NULL
root
Output:
cur
cur
cur
bill
cur
cur
danny
frank
cur
cur
jane
cur
waa
cur
Printing a BST In Alphabetical Order
Can anyone guess
what algorithm we
use to print out a
BST in alphabetical
order?
Big-oh Alert!

So whats the big-Oh of printing
all the items in the tree?



Right! O(n) since we have to visit
and print all n items.
47
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
}
48
Freeing The Whole Tree
void FreeTree(Node *cur)
{
if (cur == NULL)
return;

FreeTree(cur->left);

FreeTree (cur-> right);

delete cur;
}
NULL
Larry
Fran Ronda
NULL NULL
NULL
Barry

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

FreeTree(cur->left);

FreeTree (cur-> right);

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

FreeTree(cur->left);

FreeTree (cur-> right);

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

FreeTree(cur->left);

FreeTree (cur-> right);

delete cur;
}
cur = NULL
49
Freeing The Whole Tree
NULL
Larry
Fran Ronda
NULL NULL
NULL
Barry

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

FreeTree(cur->left);

FreeTree (cur-> right);

delete cur;
}
void FreeTree(Node *cur)
{
if (cur == NULL)
return;

FreeTree(cur->left);

FreeTree (cur-> right);

delete cur;
}
void FreeTree(Node *cur)
{
if (cur == NULL)
return;

FreeTree(cur->left);

FreeTree (cur-> right);

delete cur;
}
cur->
50
Freeing The Whole Tree
NULL
Larry
Fran Ronda
NULL

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

FreeTree(cur->left);

FreeTree (cur-> right);

delete cur;
}
void FreeTree(Node *cur)
{
if (cur == NULL)
return;

FreeTree(cur->left);

FreeTree (cur-> right);

delete cur;
}
void FreeTree(Node *cur)
{
if (cur == NULL)
return;

FreeTree(cur->left);

FreeTree (cur-> right);

delete cur;
}
cur->
51
Freeing The Whole Tree
NULL
Larry
Fran Ronda
NULL
cur->
cur->
void FreeTree(Node *cur)
{
if (cur == NULL)
return;

FreeTree(cur->left);

FreeTree (cur-> right);

delete cur;
}
void FreeTree(Node *cur)
{
if (cur == NULL)
return;

FreeTree(cur->left);

FreeTree (cur-> right);

delete cur;
}
And so on
Big-oh Alert!

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.
52
Appendix Slides

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy