5 Trees1
5 Trees1
1
TREES
• A tree is a collection of nodes (containing
information we want to store)
• The collection can be empty.
• Otherwise, the tree has
– A distinguished node r called the root
– Zero or more nonempty (sub)trees T1, T2, ...Tk each
of whose roots are connected by a directed edge
from r
2
TREES
A tree of 3 nodes
Subtree T1 of 1 node
Subtree T2 of 1 node
3
TREES
Root
4
TREES
Parent
Root
Child
5
TREES
Root
Edges
6
TREES
Root
Edges
Leaves
7
TREES
Root Siblings
8
TREES
A sequence of nodes n1, n2, ... nk Root There is exactly one
such that ni-1 is the parent n i is a path n1
path from
of length k - 1 root to each node.
n2
n3
n4
9
TREES
A tree with N nodes has Root
N – 1 edges. Why?
10
TREES
A tree with N nodes has Root
N – 1 edges. Why? Each node except root
has link to its parent.
11
TREES
12
TREES
13
USES OF TREES
• Trees are one of the most versatile data
structures with a large number of applications.
• Trees are used whenever hierarchical
relationships need to be represented.
14
USES OF TREES
• Directory structures
– My Computer (root)
• C
– My Documents
» ...
» ...
– Windows
» ...
» ...
– Program Files
» ....
– Autoexec.bat (leaf)
• D
– ....
15
USES OF TREES
• Organizational Relationships
• Chief Executive Officer
– Vice President of Engineering
• Director of Information Technology
– Manager of Web Services
» Web Programmer
– ...
• Director of Product Development
– Manager of WizardPhone Product
– Vice President of Marketing
• ...
– Vice President of Finance
16
USES OF TREES
• Administrative Relationships
• Adana
– Ceyhan
• ...
– ...
– Seyhan
• ...
• Zonguldak
– ...
• ...
17
IMPLEMENTATION OF TREES
struct TreeNode {
Object element;
TreeNode * firstChild;
TreeNode * nextSibling
}
18
IMPLEMENTATION OF TREES
firstChild points to nextSibling points to
the leftmost child the right sibling
19
SPECIAL FORMS OF TREES
• The general representation of trees are OK but
not necessarily required in many applications.
• Accessing some components may not be very
efficient.
• For many applications, trees with restricted
structures are sufficient.
20
BINARY TREES
• A binary tree is a tree in which no node can
have more than two children.
Right child
Left Child
Right subtree
Left subtree
21
Perfect Binary Tree
22
BINARY TREE - IMPLEMENTATION
struct BinaryNode {
Object element; // the data in the node
BinaryNode *left; // pointer to the left child node
BinaryNode *right; // pointer to the right child node
};
25
BINARY SEARCH TREES
• A binary tree is a binary search tree if for every
node holding a value X
– The values of all nodes in the left subtree are less
than X
– The values of all nodes in the right subtree are
larger than X
26
BINARY SEARCH TREES
3 12
1 5 17
0 2 4 9 14 19
27
BINARY SEARCH TREES
3 12
1 5 17
0 2 4 9 14 19
28
BINARY SEARCH TREES
3 12
1 5 17
0 2 4 9 14 19
29
BINARY SEARCH TREES
3 12
1 5 17
0 2 4 9 14 19
30
BINARY SEARCH TREES
3 12
1 5 17
0 2 4 9 14 19
31
BINARY SEARCH TREES
3 12
1 5 17
0 2 4 9 14 19
32
OPERATIONS ON BSTs
• find
– findMax
– findMin
• insert
• delete
33
find
3 • Searching for 3
6
• Compare with the value
2 8
at the root
1 4
34
find
3 • Searching for 3
6
• Compare with the value
2 8
at the root
• If equal, then found
1 4
35
find
3 • Searching for 3
6
• Compare with the value
2 8
at the root
• If equal, then found
1 4
• If less than, then search
3
in the left subtree (not
found if null)
36
find
• Searching for 3
6
3
• Compare with the value
2 8
at the root
• If equal, then found
1 4
• If less than, then search
3
in the left subtree (not
found if null)
• If greater than, then
search in the right
subtree (not found if null)
37
find
• Searching for 3
6
• Compare with the value
2 8
at the root
3 • If equal, then found
1 4
• If less than, then search
3
in the left subtree (not
found if null)
• If greater than, then
search in the right
subtree (not found if null)
38
find
• Searching for 3
6
• Compare with the value
2 8
at the root
• If equal, then found
1 4
• If less than, then search
3
3 in the left subtree (not
found if null)
• If greater than, then
search in the right
subtree (not found if null)
39
find
• Searching for 5
6
• Compare with the value
2 8
at the root
5 • If equal, then found
1 4
• If less than, then search
3
in the left subtree (not
found if null)
• If greater than, then
search in the right
subtree (not found if null)
40
USE OF RECURSION
• Note the use of recursion
• to do something on the BST
– We do something at root
– If necessary we do something on the left subtree
(which is a BST)
– If necessary we do something on the right subtree
(which is a BST)
• At every move the problem gets smaller.
• Other BST algorithms have the same flavor.
41
findMin
• Check if root has a left
6
child
2 8
• If so, findMin in the left
subtree
1 4
42
findMin
• Check if root has a left
6
child
2 8
• If so, findMin in the left
subtree (recursive step)
1 4
• If not, return the value
at the root.
3
43
findMax
• Check if root has a right
6
child
2 8
• If so, findMax in the
right subtree (recursive
1 4
step)
• If not, return the value
3
at the root.
44
insert
• insert is essentially like find
– search for the element to be inserted
– if already in the tree do nothing
– if not, the point you encounter a null child pointer
(and should return in find) is the point in the tree
you should insert
45
insert
• To insert 5, search for
6
where 5 should go.
2 8
1 4
46
insert
• To insert 5, search for
6
where 5 should go.
2 8
• and insert it as the
appropriate child there.
1 4
3 5
47
insert
• To insert 7, search for
6
where 7 should go.
2 8
• and insert it as the
appropriate child there.
1 4 7
3 5
48
insert
• To insert 17, search for
6
where 17 should go.
2 8
• and insert it as the
appropriate child there.
1 4 7 17
3 5
49
delete
• delete is a bit tricky
– if the node we are deleting is a leaf node then it is
easy, just get rid of the node.
50
delete
• delete is a bit tricky
6
– if the node we are
2 8 deleting is a leaf node
then it is easy, just get rid
1 4 17 of the node.
• deleting one of
3 5 1,3,5,7,17 is easy
• deleting 7 leaves a BST
behind
51
delete
• delete is a bit tricky
6
– if the node we are
2 8 deleting is a leaf node
then it is easy, just get rid
1 4 17 of the node.
– if the node we are
deleting has a single
3 5
child,
52
delete
• delete is a bit tricky
6
– if the node we are
2 8 deleting is a leaf node
then it is easy, just get rid
1 4 17 of the node.
– if the node we are
deleting has a single child
3 5
make that single child the
(appropriate) child of the
grandparent!
53
delete
• delete is a bit tricky
– if the node to be deleted
has both children
6 6
2 17 3 17
1 4 1 4
3 5 5
54
delete
• delete is a bit tricky
6
– if the node to be deleted
2 17 has both children
– find the minimum node
1 5 on the right subtree (or
the maximum node on the left
subtree)
3
55
delete
• delete is a bit tricky
6
– if the node to be deleted
2 17 has both children
– find the minimum node
on the right subtree (or
1 5 the maximum node on the left
subtree)
– Delete that node
3
recursively
• Note that the 2nd delete
4
is an easy case (Why?)
56
delete
• delete is a bit tricky
6
– if the node to be deleted
2 17 has both children
– find the minimum node
on the right subtree (or
1 5 the maximum node on the left
subtree)
– Delete that node
3 4
recursively
– Replace the original node
to be deleted with the
newly deleted node.
57
delete
• delete is a bit tricky
6
– if the node to be deleted
3 17 has both children
– find the minimum node
on the right subtree (or
1 5 the maximum node on the left
subtree)
– Delete that node
4
recursively
– Replace the original node
to be deleted with the
newly deleted node.
58
delete
• Suppose we want to
8
delete 8
3 12 • Find the smallest value
on the right subtree
1 5 17
0 2 4 7 14 19
18 22
59
delete
12
• Suppose we want to
8
delete 8
3 • Find the smallest value
on the right subtree
1 5 17
• Delete that node
(recursively)
0 2 4 7 14 19
18 22
60
delete
• Suppose we want to
12
delete 8
3 • Find the smallest value
on the right subtree
1 5 17
• Delete that node
• Replace the value in the
0 2 4 7 14 19
node to be deleted with
12
18 22
61
delete
• Suppose we want to
12
delete 12 now
3 • Find the smallest value
on the right subtree
1 5 17
0 2 4 7 14 19
18 22
62
delete
• Suppose we want to
12
delete 12 now
3 • Find the smallest value
on the right subtree
1 5 17
• Delete that node
0 2 4 7 14 19
18 22
63
delete
• Suppose we want to
14
delete 12 now
3 • Find the smallest value
on the right subtree
1 5 17
• Delete that node
• Replace the value in the
0 2 4 7 19
node to be deleted with
14
18 22
64
IMPLEMENTING BSTs
template <class Comparable>
class BinarySearchTree;
void makeEmpty( );
void insert( const Comparable & x );
void remove( const Comparable & x );
void makeEmpty( );
void insert( const Comparable & x );
void remove( const Comparable & x );
void makeEmpty( );
void insert( const Comparable & x );
void remove( const Comparable & x );
void makeEmpty( );
void insert( const Comparable & x );
void remove( const Comparable & x );
72
RETURNING FROM find
• Any find function searching for an item in a set
of items should return two pieces of
information
– if the item (partially) specified is found or not
– if found what the complete item is
• Note that the comparison for the search can be
on parts of the object (e.g. student number)
73
RETURNING FROM find
• There is a number of ways of transferring this
information back to the calling client program.
– You can return one piece of the information using
the return value of the function.
– You can return one or both pieces using call-by-
reference variables.
– You can use the exception handling mechanism to
indicate the value of one of the pieces of
information.
74
RETURNING FROM find
• Option 1
– function returns as value the object found
– function raises a notFound() exception if the object
is not found, and let somebody else worry about
the situation.
75
RETURNING FROM find
• Option 2
– function returns found/not found as a value
– function returns the found object as a reference
argument
76
RETURNING FROM find
• Option 3
– function returns both results in reference
arguments.
77
RETURNING FROM find
• Option 4
– function returns the object if found but returns a
special value object to indicate if not found.
78
IMPLEMENTING BSTs
private:
BinaryNode<Comparable> *root;
const Comparable ITEM_NOT_FOUND;
79
IMPLEMENTING BSTs
private:
BinaryNode<Comparable> *root;
const Comparable ITEM_NOT_FOUND;
80
IMPLEMENTING BSTs
private:
BinaryNode<Comparable> *root;
const Comparable ITEM_NOT_FOUND;
81
CONSTRUCTOR
/**
* Construct the tree.
*/
template <class Comparable>
BinarySearchTree<Comparable>::
BinarySearchTree(const Comparable & notFound ) :
ITEM_NOT_FOUND( notFound ), root( NULL )
{
}
82
(private) elementAt
/**
* Internal method to get element field in node t.
* Return the element field or ITEM_NOT_FOUND if t is NULL.
*/
template <class Comparable>
const Comparable & BinarySearchTree<Comparable>::
elementAt( BinaryNode<Comparable> *t ) const
{
return t == NULL ? ITEM_NOT_FOUND : t->element;
}
83
find
/**
* Find item x in the tree.
* Return the matching item or ITEM_NOT_FOUND if not found.
*/
template <class Comparable>
const Comparable & BinarySearchTree<Comparable>::
find( const Comparable & x ) const
{
return elementAt( find( x, root ) ); Public method
}
Private methods
84
(private) find
/**
* Internal method to find an item in a subtree.
* x is item to search for.
* t is the node that roots the tree.
* Return node containing the matched item.
*/
template <class Comparable>
BinaryNode<Comparable> *
BinarySearchTree<Comparable>::
find( const Comparable & x, BinaryNode<Comparable> * t ) const
{
if ( t == NULL )
return NULL;
else if( x < t->element )
return find( x, t->left );
else if( t->element < x )
return find( x, t->right );
else
return t; // Match
85
}
(private) find (non-recursive)
template <class Comparable>
BinaryNode<Comparable> *
BinarySearchTree<Comparable>::
find( const Comparable & x, BinaryNode<Comparable> *t ) const
{
while( t != NULL )
if( x < t->element )
t = t->left;
else if( t->element < x )
t = t->right;
else
return t; // Match
86
TAIL RECURSION
if( t == NULL )
{
while( t != NULL ) return NULL;
if( x < t->element )
else if( x < t->element )
t = t->left;
else if( t->element < x ) return find( x, t->left );
t = t->right;
else else if( t->element < x )
return t; // Match return find( x, t->right );
87
findMin
/**
* Find the smallest item in the tree.
* Return smallest item or ITEM_NOT_FOUND if empty.
*/
template <class Comparable>
const Comparable & BinarySearchTree<Comparable>::findMin( ) const
{
return elementAt( findMin( root ) );
}
Public method
Private methods
88
(private) findMin
/**
* Internal method to find the smallest item in a subtree t.
* Return node containing the smallest item.
*/
template <class Comparable>
BinaryNode<Comparable> *
BinarySearchTree<Comparable>::findMin( BinaryNode<Comparable> *t )
const
{
if( t == NULL )
return NULL;
if( t->left == NULL )
return t;
return findMin( t->left );
}
This is a recursive code
89
findMax
/**
* Find the smallest item in the tree.
* Return smallest item or ITEM_NOT_FOUND if empty.
*/
template <class Comparable>
const Comparable & BinarySearchTree<Comparable>::findMax( ) const
{
return elementAt( findMax( root ) );
}
Public method
Private methods
90
(private) findMax
/**
* Internal method to find the largest item in a subtree t.
* Return node containing the largest item.
*/
template <class Comparable>
BinaryNode<Comparable> *
BinarySearchTree<Comparable>::findMax( BinaryNode<Comparable> *t )
const
{
if( t != NULL )
while( t->right != NULL )
t = t->right;
return t;
}
91
insert
/**
* Insert x into the tree; duplicates are ignored.
*/
template <class Comparable>
void BinarySearchTree<Comparable>::insert( const Comparable & x )
{
insert( x, root );
}
Public method
Private method
92
(private) insert
/**
* Internal method to insert into a subtree.
* x is the item to insert.
* t is the node that roots the tree.
* Set the new root.
*/
template <class Comparable>
void BinarySearchTree<Comparable>::
insert( const Comparable & x, BinaryNode<Comparable> * & t ) const
{
if( t == NULL ) // create a new node at the right place
t = new BinaryNode<Comparable>( x, NULL, NULL );
else if( x < t->element )
insert( x, t->left ); // insert at the left or
else if( t->element < x )
insert( x, t->right ); // right subtree
else
; // Duplicate; do nothing
93
}
* & : reference-to-pointer
void foo(int *r, int *s) int *p = new int;
{ int *q = new int;
r = s; *p = 5;
} *q = 2;
foo(p, q);
r (@150) s (@170)
200 250
94
* & : reference-to-pointer
void foo(int *r, int *s) int *p = new int;
{ int *q = new int;
r = s; *p = 5;
} *q = 2;
foo(p, q);
r (@150) s (@170)
250 250
95
* & : reference-to-pointer
void foo(int *r, int *s) int *p = new int;
{ int *q = new int;
r = s; *p = 5;
} *q = 2;
foo(p, q);
96
* & : reference-to-pointer
void foo(int * & r, int *s) int *p = new int;
{ int *q = new int;
r = s; *p = 5;
} *q = 2;
foo(p, q);
r (@150) s (@170)
50 250
97
* & : reference-to-pointer
void foo(int * & r, int *s) int *p = new int;
{ int *q = new int;
r = s; *p = 5;
} *q = 2;
foo(p, q);
r (@150) s (@170)
50 250
98
* & : reference-to-pointer
void foo(int * & r, int *s) int *p = new int;
{ int *q = new int;
r = s; *p = 5;
} *q = 2;
foo(p, q);
99
remove
/**
* Remove x from the tree. Nothing is done if x is not found.
*/
template <class Comparable>
void BinarySearchTree<Comparable>::remove
( const Comparable & x )
{
remove( x, root );
}
Public method
Private method
100
(private) remove
/**
* Internal method to remove from a subtree.
* x is the item to remove.
* t is the node that roots the tree.
* Set the new root.
*/
template <class Comparable>
void BinarySearchTree<Comparable>::
remove( const Comparable & x, BinaryNode<Comparable> * & t )
const
{
if( t == NULL )
return; // Item not found; do nothing
if( x < t->element )
remove( x, t->left );
else if( t->element < x )
remove( x, t->right ); 101
(private) remove
else if( t->left != NULL && t->right != NULL ) // Two children
{
t->element = findMin( t->right )->element;
remove( t->element, t->right );
}
else // one or no children
{
BinaryNode<Comparable> *oldNode = t;
t = ( t->left != NULL ) ? t->left : t->right;
delete oldNode;
}
}
102
makeEmpty
/**
* Make the tree logically empty.
*/
template <class Comparable>
void BinarySearchTree<Comparable>::makeEmpty( )
{
makeEmpty( root );
}
Public method
Private method
103
(private) makeEmpty
/**
* Internal method to make subtree empty.
*/
template <class Comparable>
void BinarySearchTree<Comparable>::
makeEmpty( BinaryNode<Comparable> * & t ) const
{
if( t != NULL )
{
makeEmpty( t->left );
makeEmpty( t->right );
delete t;
}
t = NULL;
}
104
printTree
/**
* Print the tree contents in sorted order.
*/
template <class Comparable>
void BinarySearchTree<Comparable>::printTree( ) const
{
if( isEmpty( ) )
cout << "Empty tree" << endl;
else
printTree( root );
}
Private method
105
printTree
/**
* Print the tree contents in sorted order.
*/
template <class Comparable>
void BinarySearchTree<Comparable>::printTree( ) const
{
if( isEmpty( ) )
cout << "Empty tree" << endl;
else
printTree( root );
}
Private method
106
DESTRUCTOR
/**
* Destructor for the tree.
*/
template <class Comparable>
BinarySearchTree<Comparable>::~BinarySearchTree( )
{
makeEmpty( );
}
107
COPY CONSTRUCTOR
/**
* Copy constructor.
*/
template <class Comparable>
BinarySearchTree<Comparable>::
BinarySearchTree( const BinarySearchTree<Comparable> & rhs ) :
root( NULL ), ITEM_NOT_FOUND( rhs.ITEM_NOT_FOUND )
{
*this = rhs;
}
108