0% found this document useful (0 votes)
5 views

Binary Trees

Uploaded by

harsh kumar
Copyright
© © All Rights Reserved
Available Formats
Download as KEY, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
5 views

Binary Trees

Uploaded by

harsh kumar
Copyright
© © All Rights Reserved
Available Formats
Download as KEY, PDF, TXT or read online on Scribd
You are on page 1/ 90

Binary Trees

Outline
Tree Stuff
Trees
Binary Trees
Implementation of a Binary Tree
Tree Traversals – Depth First
Preorder
Inorder
Postorder
Breadth First Tree Traversal
Binary Search Trees
Tree Stuff
Trees:
Another Abstract Data Type
Data structure made of nodes and pointers
Much like a linked list
The difference between the two is how they are
organized.
A linked list represents a linear structure
A predecessor/successor relationship between the
nodes of the list
A tree represents a hierarchical relationship
between the nodes (ancestral relationship)
A node in a tree can have several successors, which
we refer to as children
A nodes predecessor would be its parent
Tree Stuff
Trees:
General Tree Information:
Top node in a tree is called the root
the root node has no parent above because it’s the
root!
Every node in the tree can have “children”
nodes
Each child node can, in turn, be a parent to its
children and so on
Nodes having no children are called leaves
Any node that is not a root or a leaf is an
interior node
The height of a tree is defined to be the
length of the longest path from the root to a
leaf in that tree.
Tree Stuff
Trees:
Here’s a picture of a tree:
2 is the root
2, 5, 11, and 4 are leaves
7, 5, 6, and 9 are interiornodes
Tree Stuff
Binary Trees:
A tree in which each node can have a
maximum of two children
Each node can have no child, one child, or two
children
And a child can only have one parent
Pointers help us to identify if it is a right child or
a left oneof
Examples
two
Binary Trees:
Tree Stuff
Examples of trees that are NOT Binary
Trees:
Tree Stuff
More Binary Tree Goodies:
A full binary tree:
Every node, other than the leaves, has two
children
a

b c

d e g, h, e, and c
are leaves: so
g h they have no
children.
Tree Stuff
More Binary Tree Goodies:
A complete binary tree:
Every level, except possibly the last, is
completely filled, and all nodes are as far left
as possible.
Tree Stuff
More Binary Tree Goodies:
The root of the tree is at level 0
The level of any other node in the tree is
one more than the level of its parent
Total # of nodes (n) in acomplete binary
tree:
n = 2h+1 – 1 (maximum)
Height (h) of the tree:
h = log((n + 1)/2)
If we have 15 nodes
h = log(16/2) = log(8) = 3
Tree Stuff
Implementation of a Binary Tree:
A binary tree has a natural
implementation using linked storage
Each node of a binary tree has both left
and right subtrees that can be reached
with pointers:
struct tree_node { left_child data
int data;
right_child
struct tree_node *left_child;
struct tree_node *right_child;
}
Tree Traversals
Traversal of Binary Trees:
We need a way of zipping through a tree for
searching, inserting, etc.
But how can we do this?
If you remember…
Linked lists are traversed from the head to the last
node
…sequentially

Can’t we just “do that” for binary trees.?.


NO! There is no such natural linear ordering for nodes of
a tree.
Turns out, there are THREE ways/orderings of
Tree Traversals

But before we get into


the nitty gritty of
those three,
let’s describe..
Tree Traversals – Depth First
A depth-first search (DFS)
A
explores a path all the way
to a leaf before
B C
backtracking and
exploring another path
For example, after
D E F G searching A, then B, then
D, the search backtracks
and tries another path
H I J K from B
Node are explored in the
L M N O P Q order A B D E H L M N I O P
CFGJKQ
N will be found before J
Tree Traversals
Traversal of Binary Trees:
There are 3 ways/orderings of traversing
a binary tree (all 3 are depth first search
methods):
Preorder, Inorder, and Postorder
These names are chosen according to the step
at which the root node is visited:
With preorder traversal, the root is visited before
its left and right subtrees.
With inorder traversal, the root is visited between
the subtrees.
With postorder traversal, the root is visited after
both subtrees.
Tree Traversals - Preorder
Preorder Traversal
the root is visited before its left and right
subtrees
For the following example, the “visiting” of a
node is represented by printing that node
Code for Preorder Traversal:
void preorder (struct tree_node *p) {
if (p != NULL) {
printf(“%d ”, p->data);
preorder(p->left_child);
preorder(p->right_child);
}
}
Tree Traversals - Preorder
Preorder Traversal – Example 1
the root is visited before its left and right
subtrees
a

b c

abc
Tree Traversals - Preorder
Preorder Traversal – Example 2
a

b c
f
d e
g h i j

Order of Visiting abdghei c f j


Nodes:
Tree Traversals - Inorder
Inorder Traversal
the root is visited between the left and
right subtrees
For the following example, the “visiting” of a
node is represented by printing that node
Code for Inorder Traversal:
void inorder (struct tree_node *p) {
if (p != NULL) {
inorder(p->left_child);
printf(“%d ”, p->data);
inorder(p->right_child);
}
}
Tree Traversals - Inorder
Inorder Traversal – Example 1
the root is visited between the subtrees

b c

bac
Tree Traversals - Inorder
Inorder Traversal – Example 2
a

b c
f
d e
g h i j

Order of Visiting gdhbei af j c


Nodes:
Tree Traversals – Postorder
Postorder Traversal
the root is visited after both the left and
right subtrees
For the following example, the “visiting” of a
node is represented by printing that node
Code for Postorder Traversal:
void postorder (struct tree_node *p) {
if (p != NULL) {
postorder(p->left_child);
postorder(p->right_child);
printf(“%d ”, p->data);
}
}
Tree Traversals – Postorder
Postorder Traversal – Example 1
the root is visited after both subtrees

b c

bc a
Tree Traversals – Postorder
Postorder Traversal – Example 2
a

b c
f
d e
g h i j

Order of Visiting ghdi ebj f c a


Nodes:
Tree Traversals
Final Traversal Example
Breadth-First Traversal

A A breadth-first search
(BFS) explores nodes
nearest the root before
B C exploring nodes further
away
D E F G For example, after
searching A, then B, then
C, the search proceeds
H I J K
with D, E, F, G
Node are explored in the
L M N O P Q order A B C D E F G H I J K L M
NOPQ
J will be found before N
Breadth-First Traversal
H

D L

B F J N

A C E G I K M O

O M K I G E C A N J F B L D H
Breadth-First Traversal
Coding the Breadth-First Traversal
Let’s say you want to Traverse and Print all
nodes?
Think about it, how would you make this happen?
SOLUTION:
Enqueue the root node.
while (more nodes still in queue) {
Dequeue node at front (of queue)
Print this node (that we just dequeued)
Enqueue its children (if applicable): left then
right
…continue till no more nodes in queue
}
Binary Search Tree
Binary Search Trees
We’ve seen how to traverse binary trees
But it is not quite clear how this data
structure helps us
What is the purpose of binary trees?
What if we added a restriction…
Consider the followingbinary tree:
What pattern can you see?
Binary Search Tree
Binary Search Trees
What pattern can you see?
For each node N, all the values stored in the left
subtree of N are LESS than the value stored in N.
Also, all the values stored in the right subtree of N
are GREATER than the value stored in N.
Why might this property be a desireable one?
Searching for a node is super fast!
Normally, if we search through n nodes, it takes
O(n) time
But notice what is going on here:
This ordering property of the tree tells us where to
search
We choose to look to the left OR …O(log
look to the
n) right of a
node time
Binary Search Tree
Binary Search Trees
Details:
ALL of the data values in the left subtree of each
node are smaller than the data value in the node
itself (root of said subtree)
Stated another way, the value of the node itself is
larger than the value of every node in its left subtree.
ALL of the data values in the right subtree of each
node are larger than the data value in the node
itself (root of the subtree)
Stated another way, the value of the node itself is
smaller than the value of every node in its right
subtree.
Both the left and right subtrees, of any given node,
are themselves binary search trees.
Binary Search Tree
4
4

2 6
4 5

2 3 5 8
0 6 6 8

1 2 4 6
5 8 0 2

8 1 3 4 5 6
9 0 2 8 4

A Binary Search Tree


Binary Search Tree
Binary Search Trees
Details:
A binary search tree, commonly referred to as a
BST, is extremely useful for efficient
searching
Basically, a BST amounts to embedding the binary
search into the data structure itself.
Notice how the root of every subtree in the BST on the
previous page is the root of a BST.
This ordering of nodes in the tree means that
insertions into a BST are not placed arbitrarily
Rather, there is a specific way to insert
Binary Search Trees:
Search & Insert
Binary Search Tree
Binary Search Trees
Ordering Property:
For each node N, all the values stored in the left
subtree of N are LESS than the value stored in N.
Also, all the values stored in the right subtree of N
are GREATER than the value stored in N.
Why might this property be a desireable one?
Searching for a node is super fast!
Normally, if we search through n nodes, it takes
O(n) time
But notice what is going on here:
This ordering property of the tree tells us where to
search
We choose to look to the left or look to then)right of a
…O(log
node time
Binary Search Tree:
Searching
Binary Search Trees
Searching for a node:
Algorithm:
IF the tree is NULL, return false.
ELSE
1)

1)

1) Check the root node. If the value we are


searching for is in the root, return 1
(representing “found”).
2) If not, if the value is less than that stored in the
root node, recursively search in the left subtree.
3) Otherwise, recursively search in the right
subtree.
Binary Search Tree:
Searching
Binary Search Trees
Searching for a node (Code):
int find (struct tree_node *current_ptr, int val) {
// Check if there are nodes in the tree.
if (current_ptr != NULL) {
// Found the value at the root.
if (current_ptr->data == val)
return 1;
// Search to the left.
if (val < current_ptr->data)
return find(current_ptr->left, val);
// Or...search to the right.
else
return find(current_ptr->right, val);
}
else
return 0;
}
Binary Search Tree: Creation

Insertion into a Binary Search Tree


Before we can insert a node into a BST,
what is the one obvious thing that we must
do?
We have to actually create the node that
we want to insert
malloc space for the node
And save appropriate data value(s) into it
Here’s our struct defined earlier:
struct tree_node {
int data;
struct tree_node *left;
struct tree_node *right;
}
Binary Search Tree: Creation

Creating a Binary Search Tree


In main, we simply make a pointer of type
struct tree_node and initialize it to NULL
struct tree_node *my_root = NULL;
So this is the ROOT of our tree
You then get your values to insert into the
tree
This could be automated
You could have the user enter a value(s)
However you want (this really isn’t that
important)
We then call the create_node function to
create a new node with this specific value
Binary Search Tree: Creation

Creating a Binary Search Tree


create_node function:
struct tree_node* create_node(int val) {
// Allocate space for the node
struct tree_node* temp;
temp = (struct tree_node*)malloc(sizeof(struct tree_node));
// Initialize the fields
temp->data = val;
temp->left = NULL;
temp->right = NULL;
// Return a pointer to the created node.
return temp;
}
Binary Search Tree:
Insertion
Insertion (of nodes) into a Binary Search
Tree
Now that we have nodes, it is time to
insert!
BSTs must maintain their ordering property
Smaller items to the left of any given root
And greater items to the right of that root
So when we insert, we MUST follow these
rules
You simply start at the root and either
Go right if the new value is greater than the root
Go left if the new value is less than the root
Keep doing this till you come to an empty
Binary Search Tree:
Insertion
Insertion into a Binary Search Tree
Let’s assume we insert the following data
values, in their order of appearance into an
initially empty BST:
10, 14, 6, 2, 5, 15, and 17 1
0

Step 1:
Create a new node with
value 10
Insert node into tree
The tree is currently empty
New node becomes the root
Binary Search Tree:
Insertion
Insertion into a Binary Search Tree
10, 14, 6, 2, 5, 15, and 17

Step 2: 1
Create a new node with value 14 0
This node belongs in the right
1
subtree of node 10 4
Since 14 > 10
The right subtree of node 10 is
empty
So node 14 becomes the
right child of node 10
Binary Search Tree:
Insertion
Insertion into a Binary Search Tree
10, 14, 6, 2, 5, 15, and 17

Step 3: 1
Create a new node with value 6 0
This node belongs in the left
6 1
subtree of node 10 4
Since 6 < 10
The left subtree of node 10 is
empty
So node 6 becomes the left
child of node 10
Binary Search Tree:
Insertion
Insertion into a Binary Search Tree
10, 14, 6, 2, 5, 15, and 17

Step 4: 1
Create a new node with value 2 0
This node belongs in the left
6 1
subtree of node 10 4
Since 2 < 10
The root of the left subtree is 6 2
The new node belongs in the left
subtree of node 6
Since 2 < 6
So node 2 becomes the left child
of node 6
Binary Search Tree:
Insertion
Insertion into a Binary Search Tree
10, 14, 6, 2, 5, 15, and 17

Step 5: 1
Create a new node with value 5 0
This node belongs in the left
6 1
subtree of node 10 4
Since 5 < 10
The new node belongs in the left 2
subtree of node 6
Since 5 < 6
5
And the new node belongs in the
right subtree of node 2
Since 5 > 2
Binary Search Tree:
Insertion
Insertion into a Binary Search Tree
10, 14, 6, 2, 5, 15, and 17

Step 6: 1
Create a new node with value 15 0
This node belongs in the right
6 1
subtree of node 10 4
Since 15 > 10
The new node belongs in the 2 1
right subtree of node 14 5
Since 15 > 14
5
The right subtree of node 14 is
empty
So node 15 becomes right child
of node 14
Binary Search Tree:
Insertion
Insertion into a Binary Search Tree
10, 14, 6, 2, 5, 15, and 17

Step 7: 1
Create a new node with value 17 0
This node belongs in the right
6 1
subtree of node 10 4
Since 17 > 10
The new node belongs in the 2 1
right subtree of node 14 5
Since 17 > 14
5 1
And the new node belongs in the 7
right subtree of node 15
Since 17 > 15
Binary Search Tree:
Insertion
Insertion into a Binary Search Tree
In main, we have the following:
struct tree_node *my_root=NULL, *temp_node;
// ***************
// OTHER CODE HERE
// ***************
While (something_here) {
printf("What value would you like to insert?");
scanf("%d", &val);
temp_node = create_node(val); // Create the node.
// Insert the value.
my_root = insert(my_root, temp_node);
// more code
Binary Search Tree:
Insertion
Insertion into a Binary Search Tree
Here’s our basic plan to do this recursively:
1) If the tree is empty, just return a pointer to a
node containing the new value
cuz this value WILL be the ROOT
2) Otherwise, see which subtree the node should be
inserted into
How?
Compare the value to insert with the value stored at
the root.
3) Based on this comparison, recursively either
insert into the right subtree, or into the left
subtree.
Binary Search Tree:
Insertion
Insertion into a Binary Search Tree
And here’s the matching code:
struct tree_node* insert(struct tree_node *root, struct tree_node *element) {
// Inserting into an empty tree.
if (root == NULL)
return element;
else {
// element should be inserted to the right.
if (element->data > root->data)
root->right = insert(root->right, element);
// element should be inserted to the left.
else
root->left = insert(root->left, element);
// Finally, return the root pointer of the updated tree.
return root;
}
}
Binary Search Tree: Creation

Creating a Binary Search Tree


What we get from this:
Creating a BST is really nothing more than a
series of insertions (calling the insert function
over and over)
You simply get the values
Create the nodes
And then call this insert function over and
over
For every node
Binary Search Tree: Sum
Nodes
Summing the Nodes of a Binary Search
Tree
How would you do this?
If it is not clear, think about how you did
this with linked lists.
How did you sum the nodes in a linked list?
You simply traversed the list and summed the
values
Similarly, we traverse the tree and sum the
values
How do we traverse the tree?
...so choose
We already
onewent over that
You have three traversal options: preorder,
Binary Search Tree: Sum
Nodes
Summing the Nodes of a Binary Search
Tree
But it’s really even easier than this!
All we do is add the values (root, left, and
right) and then return the answer
Here’s the code, and notice how succinct it
is:
int add(struct tree_node *current_ptr) {
if (current_ptr != NULL)
return current_ptr->data +
add(current_ptr->left)+ add(current_ptr->right);
else
return 0;
}
Binary Search Tree: Search
Search of an Arbitrary Binary Tree
We’ve seen how to search for a node in a
binary search tree
Now consider the problem if the tree is NOT
a binary search tree
It does not have the ordering property
You could simply perform one of the
traversal methods, checking each node in
the process
Unfortunately, this won’t be O(log n) anymore
It degenerates to O(n) since we possibly check
all nodes
Binary Search Tree: Search
Search of an Arbitrary Binary Tree
Here’s another way we could do this
The whole idea here is to be comfortable
with binary trees:
int Find(struct tree_node *current_ptr, int val) {
if (current_ptr != NULL) {
if (current_prt->data == val)
return 1;
return (Find(current_ptr->left, val) ||
Find(current_ptr->right, val))
}
else
return 0;
}
Binary Search Trees:
Deletion
Binary Trees: Deletion
Deletion From a Binary Search Tree
Deleting nodes from a BST requires some
thought
There are 3 possible cases
And we deal with each in a different fashion
The 3 cases are:
Deleting of a leaf node
Deleting a node with one child
Deleting a node with two children
We examine each case separately
Binary Trees: Deletion
Deleting a Leaf Node
This one is pretty easy

1 1
0 0

6 1 6 1
4 4

4 8 1 1 4 8 1
2 8 8

2 1 2 1
6 6
Initial BST with BST after deletion of
node 12 marked for node 12
deletion
Binary Trees: Deletion
Deleting a Leaf Node
This one is pretty easy
We start by identifying the parent of the
node we wish to delete
Which we actually do in ALL three cases
We then free that node, accessing it via
parent:
free(parent->left) or
free(parent->right)
Now we need to simply update the parent’s
left or right pointer, signifying that the
parent no longer has that child
Binary Trees: Deletion
Deleting a Leaf Node
This one is pretty easy
We start by identifying the parent of the
node we wish to delete
Which we actually do in ALL three cases
Just set the appropriate node to NULL:
parent->left = NULL or
parent->right = NULL
So now instead of pointing to the
toBeDeleted node
The parent simply points to NULL
Binary Trees: Deletion
Deleting a Node with One Child
This one is also not too complicated
But does require more thought than deleting a
leaf node
Again, we start by finding the parent
meaning, the parent of the node we want to
delete
The parent’s pointer to the node is
changed to now point to the deleted
node’s child
This has the effect of lifting up the deleted
nodes child by one level in the tree
All great-great-…-great-grandchildren will lose
Binary Trees: Deletion
Deleting a Node with One Child
parent->left = parent->left->left;

1 1
0 0

6 1 6 1
4 4

4 8 1 1 2 8 1 1
2 8 2 8

2 1 1
6 6
Initial BST with node BST after deletion of node
4 marked for deletion 4. Node 2 has taken the
place of the deleted node
Binary Trees: Deletion
Deleting a Node with One Child
The previous example illustrated when we
delete a left node that has a left child
Notice that it makes no difference whether
the only child is a left child or a right child
The next example illustrated when we
delete a right node that has a right
child
Again, the deletion simply lifts up the subtree of
the deleted node by one level
The other possibilities is a left node that
has a right child or a right node that has a
left child
Binary Trees: Deletion
Deleting a Node with One Child
parent->right = parent->right->right;

1 1
0 0
6 1
6 1 8
4
4 8 1
4 8 1 6
8
1 1
2 1 2 7
5
6
Initial BST with node 14 1 BST after deletion of node 14. Node
1
marked for deletion 5 7 18 has taken the place of the deleted
node and the entire subtree moved
up one level.
d

Binary Trees: Deletion b

a c
Deleting a Node with two children
This is the scenario that requires a bit of
thought
If we wish to delete node b (example above)
We can’t just raise up b’s children
since node d can’t use its left pointer to point to
more than one child
d‘s left can’t point to both node a and node c
So think about what we need to do in
order to maintain the structure (and
ordering property)
Binary Trees: Deletion
Deleting a Node with two children
Consider this example tree
We want to delete node 18
Ask yourself:
What two nodes could I replacethe 18 with and
5
still maintainthe binary search tree property?
9

1 6
8 7

1 3 6 7
3 2 3 2

1 1 2 4
0 5 5 3
5
9

Binary Trees: Deletion


1
1
8
3 6
6
7
7
3 2 3 2
1 1 2 4
Deleting a Node with two children
0 5 5 3

Remember:
All the nodes to the left of 18 MUST be smaller
than 18
All the nodes right of 18 MUST be greater than
18
Thus, if we delete 18
there are only two nodes we could put at 18’s
position without causing serious repercussions:
The maximum value in the left subtree of
node 18
Which is 15
The minimum value in the right subtree of
node 18
5
9

Binary Trees: Deletion


1
1
8
3 6
6
7
7
3 2 3 2
1 1 2 4
Deleting a Node with two children
0 5 5 3

Thus, if we delete 18
There are two possible nodes that could go into
18’s position:
Node 15 (greatest value in left subtree)
Node 25 (smallest value in right subtree)
We simply pick one of these to put at 18’s
position
We essentially copy the node to 18’s position
Then we have to delete the actual node that we
just copied
Meaning, if we copy node 15 into 18’s positon
We will have two 15s
So we now need to delete the leaf node 15
5
9

Binary Trees: Deletion


1
1
8
3 6
6
7
7
3 2 3 2
1 1 2 4
Deleting a Node with two children
0 5 5 3

We are guaranteed that this node


Node 15 in this example
Has AT MOST only one child
Meaning it will be easy to delete!
Why is that? How is this guarantee true?
The greatest node in a left subtree cannot have
two children
If it did, its right child would be greater than it
Similarly, the smallest node in a right subtree
cannot have two children
If it did, its left child would be smaller than it
Binary Trees: Deletion
Deleting a Node with two children
(example) 5 5
9 9

1 6 1 6
8 7 8 7

1 3 6 7 1 3 6 7
3 2 3 2 3 2 3 2

1 1 2 4 1 1 2 4
0 5 5 3 0 5 5 3

Initial BST with node 18 marked This node contains the logical
for deletion. Note that this predecessor of the node to be
node has two children with deleted. Note that it is the greatest
values 13 and 32. node in the left subtree of the node
to be deleted.
Binary Trees: Deletion
Deleting a Node with two children
(example) 5 5
9 9

1 6 1 6
8 7 8 7

1 3 6 7 1 3 6 7
3 2 3 2 3 2 3 2

1 1 2 4 1 1 2 4
0 5 5 3 0 5 5 3

Initial BST with node 18 marked This node contains the logical
for deletion. Note that this successor of the node to be deleted.
node has two children with Note that it is the smallest node in
values 13 and 32. the right subtree of the node to be
deleted.
Binary Trees: Deletion
Deleting a Node with two children
(example) 5 5
9 9

1 6 1 6
8 7 5 7

1 3 6 7 1 3 6 7
3 2 3 2 3 2 3 2

1 1 2 4 1 2 4
0 5 5 3 0 5 3

This node contains the logical The BST after the deletion of
predecessor of the node to be node 18 using the
deleted. Note that it is the greatest replacement by the logical
node in the left subtree of the node predecessor node.
to be deleted.
Binary Trees: Deletion
Deleting a Node with two children
(example) 5 5
9 9

1 6 2 6
8 7 5 7

1 3 6 7 1 3 6 7
3 2 3 2 3 2 3 2

1 1 2 4 1 1 4
0 5 5 3 0 5 3

This node contains the logical The BST after the deletion of
successor of the node to be deleted. node 18 using the
Note that it is the smallest node in replacement by the logical
the right subtree of the node to be successor node.
deleted.
Binary Trees: Deletion
Deleting a Node with two children
For the previous example,
The nodes that we copied to 18’s position were
both leaf nodes
How did this help?
Once copied over, we need to delete those nodes
Since they are leaves, this process is easy
But what if they are not leaf nodes?
Meaning, they have one child
Remember, we are guaranteed that they have AT MOST
one kid
It is still easy!
We would simply be deleting a node with one child
Which simply “lifts” up that subtree one level
Binary Trees: Deletion
Deleting a Node with two children
There’s a lot going on for deletion
So when you examine the code,
You will see many auxiliary functions used, such
as:
findNode: returns a pointer to a node in a given tree that
stores a particular value
parent: finds the parent of a given node in a given binary
tree
minVal: finds the minimum value in a given binary tree
maxVal: finds the maximum value in a given binary tree
isLeaf: determines if a node is a leaf node or not
hasOnlyLeftChild: determines if a node ONLY has a left
child
hasOnlyRightChild: determines if a node ONLY has right
kid
Binary Trees: Deletion
Auxiliary functions:
findNode: returns a pointer to a node in a
given tree that stores a particular value
The first step in deletion is finding the node in
the tree
This is basically the search function from last
time
The arguments to the function are:
A pointer to the root of some tree (or subtree)
The value we are searching for
IF found, the function returns a pointer to the
node
Else, NULL is returned
Binary Trees: Deletion
Auxiliary functions:
findNode: returns a pointer to a node in a
given tree that stores a particular value
struct tree_node* findNode(struct tree_node *current_ptr, int value) {
if (current_ptr != NULL) {
// Found the value at the root.
if (current_ptr->data == value)
return current_ptr;
// Search to the left.
if (value < current_ptr->data)
return findNode(current_ptr->left, value);
// Or...search to the right.
else
return findNode(current_ptr->right, value);
}
else
return NULL; // No node found.
}
Binary Trees: Deletion
Auxiliary functions:
parent: finds the parent of a given node in
a given binary tree
Remember: we need to know the parent of the
node we wish to delete
This allows us to modify the left/right pointers of
the parent, effectively removing the child node
The arguments to the function are:
1) The root of the tree
2) A pointer to the node we want to find the parents of
If found, a pointer to the parent node is returned
Binary Trees: Deletion
Auxiliary functions:
parent: finds the parent of a given node in
a given binary tree
struct tree_node* parent(struct tree_node *root, struct tree_node *node) {
// Take care of NULL cases.
if (root == NULL || root == node)
return NULL;
// The root is the direct parent of node.
if (root->left == node || root->right == node)
return root;
// Look for node's parent in the left side of the tree.
if (node->data < root->data)
return parent(root->left, node);
// Look for node's parent in the right side of the tree.
else if (node->data > root->data)
return parent(root->right, node);
return NULL; // Catch any other extraneous cases.
}
Binary Trees: Deletion
Auxiliary functions:
minVal: finds the minimum value in a given
binary tree
Remember: when we delete a node with two
children
We need to replace that node with either:
The minimum value in the right subtree, or
The maximum value in the left subtree
The argument to the function is the root of the
tree
The function simply returns a pointer to the node
containing the minimum value
Binary Trees: Deletion
Auxiliary functions:
minVal: finds the minimum value in a given
binary tree
Remember:
The minimum value in a given binary tree will either
be the root OR it will be found in the left subtree

struct tree_node* minVal(struct tree_node *root) {


// Root stores the minimal value.
if (root->left == NULL)
return root;
// The left subtree of the root stores the minimal value.
else
return minVal(root->left);
}
Binary Trees: Deletion
Auxiliary functions:
maxVal: finds the maximum value in a
given binary tree
Remember:
The maximum value in a given binary tree will either
be the root OR it will be found in the right subtree

struct tree_node* maxVal(struct tree_node *root) {


// Root stores the maximal value.
if (root->right == NULL)
return root;
// The right subtree of the root stores the maximal value.
else
return maxVal(root->right);
}
Binary Trees: Deletion
Auxiliary functions:
isLeaf: determines if a node is a leaf node or
not
Remember:
The easiest form of deletion is when the node to
be deleted is a leaf node
That’s why we need this function
How can you tell if a node is a leaf?
Leaves don’t have kids!
BOTH the left and right pointers will be NULL
// Returns 1 if node is a leaf node, 0 otherwise.
int isLeaf(struct tree_node *node) {
return (node->left == NULL && node->right == NULL);
}
Binary Trees: Deletion
Auxiliary functions:
hasOnlyLeftChild: determines if a node
ONLY has a left child
Remember:
The second easiest form of deletion is when the
node to be deleted has only one child
We simply delete that node and “lift” the child
subtree 1 level
How would you determine if a node has only a
left kid?
// Returns 1 if node has a left child and no right child.
int hasOnlyLeftChild(struct tree_node *node) {
return (node->left!= NULL && node->right == NULL);
}
Binary Trees: Deletion
Auxiliary functions:
hasOnlyRightChild: determines if a node
ONLY has a right child
Same as with left child
Just we’re now checking for an only right child

// Returns 1 if node has a right child and no left child.


int hasOnlyRightChild(struct tree_node *node) {
return (node->left== NULL && node->right != NULL);
}
Binary Tree Traversals – Practice
Problems 3

Practice Tree #1 1 2
Solutions on page 3 8
33

2 9 1 3
2 5 6

7 1
3 5 0 7 4
1 3 4
9

2 1 8 6 6
6 4 7 3 9

5 7 1 8 5 5 6
4 1 1 6 9 8
Binary Tree Traversals – Practice
Problems 3

2 1 Practice Tree #2
8 3
Solutions on Page
34
3 1 9 2
6 5 2

1 7
4 7 0 5 3
4 3 1
9

6 6 8 1 2
9 3 7 4 6

6 5 5 8 1 7 5
8 9 6 1 1 4
Practice Problem Solutions –
Tree #1
Preorder Traversal:
3, 13, 22, 19, 26, 54, 71, 33, 14, 11, 87, 8, 56, 9, 75, 28, 15, 10,
63, 36, 7, 69, 59, 68, 44
Inorder Traversal:
54, 26, 71, 19, 22, 11, 14, 33, 8, 87, 56, 13, 9, 75, 3, 63, 10, 15,
28, 59, 69, 68, 7, 36, 44
Postorder Traversal:
54, 71, 26, 19, 11, 14, 8, 56, 87, 33, 22, 75, 9, 13, 63, 10, 15, 59,
68, 69, 7, 44, 36, 28, 3
Practice Problem Solutions –
Tree #2
Preorder Traversal:
3, 28, 36, 44, 7, 69, 68, 59, 15, 10, 63, 13, 9, 75, 22, 33, 87, 56,
8, 14, 11, 19, 26, 71, 54
Inorder Traversal:
44, 36, 7, 68, 69, 59, 28, 15, 10, 63, 3, 75, 9, 13, 56, 87, 8, 33,
14, 11, 22, 19, 71, 26, 54
Postorder Traversal:
44, 68, 59, 69, 7, 36, 63, 10, 15, 28, 75, 9, 56, 8, 87, 11, 14, 33,
71, 54, 26, 19, 22, 13, 3

You might also like