3. Graph
ī¤ Graph: set of elements (nodes) connected with lines (edges)
ī¤ G = (V,E)
ī¤ V: set of nodes
ī¤ E: set of edges such that an element in E connects a pair of
elements in V
V = (1,2,3,4,5)
E = (a,b,c,d)
1
2
3
4
5
a
b
c
d
4. Graph
ī¤ Graph types
ī¤ Directed graph: graph in which edges are characterized by a
direction(from node A to node B)
ī¤ Undirected graph: graph which does not contain directed edges;
if an edge is drawn from node A to node B, it means that we can
move both from A to B and from B to A
ī¤ Famous examples of graphs
ī¤ Social networks (nodes: users; edges: friendship)
ī¤ Computer networks (nodes: computers; edges: physical
connections)
ī¤ Transportation networks(nodes: cities; edges: routes)
7. What is a tree?
ī¤ Tree: plant characterized by a
trunk with branches in the
upper part, called foliage
root
leaves
branch
8. What is a tree?
ī¤ Tree: undirected graph in
which two nodes are
connected by one and
only one path
ī¤ Node: contains some
data
ī¤ Edge: specifies a
hierarchical
connection between
nodes
root
leaves
branch
9. What is a tree?
ī¤ Tree: undirected graph in
which two nodes are
connected by one and
only one path
ī¤ Node: contains some
data
ī¤ Edge: specifies a
hierarchical
connection between
nodes
root
leaves
branchpath
10. What is a tree?
ī¤ Tree: undirected graph in
which two nodes are
connected by one and
only one path
ī¤ Node: contains some
data
ī¤ Edge: specifies a
hierarchical
connection between
nodes
root
leaves
branchpath
A tree is acyclic
There does not exist any alternative
path to go from node A to node B
11. Using trees
ī¤ When do you use trees?
ī¤ To represent hierarchical data
ī¤ To rapidly look for objects
ī¤ To represent decision flows
ī¤ To represent object orderings
Answer A Answer B
Decision tree Tree of possible orderings
12. Using trees
ī¤ Video phylogeny: trace a documentâs copy process on the
Web, e.g., when it is protected by copyright laws
Similarity
relationships
15. Tree components:
Root node
ī¤ It is strictly required that a tree contains a unique node which
does not have incoming edges
ī¤ This node is called root node
ī¤ There does not exist a tree without a root node
16. Tree components:
Leaf node
ī¤ Every node which does not have outgoing edges is called leaf
node
ī¤ Every finite tree (i.e., which contains a finite number of nodes)
there exists at least a leaf node
17. Tree components:
Edges
ī¤ An edge (or: branch) defines a hierarchical connection
between nodes
A parent node is a node with
an outgoing edge
i.e., the parent node is higher than
a child node
18. Tree components:
Edges
A child node is a node with an
incoming edge
i.e., a child node is lower than its
parent node
ī¤ An edge (or: branch) defines a hierarchical connection
between nodes
19. Tree components:
Nodes and edges
ī¤ A node can be a parent node and a child node at the same time,
and this happens if it has both incoming edges and outgoing
edges
ī¤ In this case the node is called internal node
ī¤ An internal node is not a leaf node
Root
Parent of
Parent of
Child of Root
Father of
Child of
Leaf
Child of
The root does not have a parent
A leaf does not have children
20. Balanced and unbalanced trees
ī¤ The leaves could be positioned at different levels; their
positioning defines the tree balancing property
ī¤ If leaves are position âcloselyâ (e.g., at maximum a single level
separates them) then the tree is balanced
Tree (perfectly) balanced Unbalanced tree
21. Definitions
ī¤ Node height: length of the longest path between the node and
a leaf
ī¤ Node depth: length of path from the node and the tree root
Height
Depth
22. Definitions
ī¤ Sub-tree of a tree T: tree consisting in a node n belonging to tree
T, together with all its descendants in T
ī¤ The sub-tree corresponding to the root T is the whole tree T
24. Binary tree vs. N-ary tree
ī¤ A binary tree is a tree whose nodes can have two children at
maximum
ī¤ An n-ary tree is a tree where there does not exist a limit on the
number of children a node could have
25. Binary complete trees vs. Binary
incomplete trees
ī¤ A tree is complete if it is a binary tree and:
ī¤ Each level (except the last) is full of nodes
ī¤ The nodes are at the leftmost positions
ī¤ The last level may contain few nodes, but it has to be filled
from left to right
Complete tree Incomplete tree
26. Binary tree: from concept to
implementation
ī¤ We are going to store the tree as a dynamic data structure
ī¤ Ideas?
27. Binary tree: from concept to
implementation
ī¤ We are going to store the tree as a dynamic data structure
ī¤ How to position them?
Ingredients What to represent
Struct
Pointers
Nodes
Edges
28. Binary tree: from concept to
implementation
Ingredients What to represent
Struct
Pointers
Nodes
Edges
ī¤ We are going to store the tree as a dynamic data structure
ī¤ Weâll use the same principles used with linked lists:
29. Binary tree: Structure
ī¤ Each node in a binary tree contains:
ī¤ A left pointer
ī¤ A right pointer
ī¤ Data
ī¤ The pointers in the node point recursively at two sub-trees
(i.e., smaller trees) positioned on its left side and right side
Left
Sub-tree
Right
Sub-tree
Left
Sub-tree
Right
Sub-Tree
30. Binary tree: Structure
ī¤ Weâll see then a node as follows:
ī¤ Note. Since the node structure is dynamic, we have to be very
careful in handling the pointer to the root: if we lose it, we lose
every possibility of accessing to the tree!
Data contained in
the node
Left sub-tree Right sub-tree
40. Counting nodes
ī¤ Aim: counting the number of nodes in the tree
ī¤ The approach we propose for any algorithm involving tree
manipulation is recursive. Thus, it is necessary to define:
ī¤ A base case
ī¤ A recursion step
ī¤ Hint: always look for base case in the leaves of the treeâĻ
41. Counting nodes
1+ nodes-left + nodes-right 1+ nodes-left + nodes-right
1+ nodes-left + nodes-right
To visit the child nodes of n,
we visit first its left sub-tree
and then its right sub-tree
Given a node n, we count the number of
nodes in the sub-tree having n as root
as:
1 + âthe number of child nodes
on the leftâ + âthe number of
child nodes on the rightâ
42. Counting nodes
1+ nodes-left + nodes-right
1+ nodes-left + nodes-right
1+ nodes-left + nodes-right
=
0
=
0
1+ nodes-left + nodes-right
1+ 1 + nodes-right
When we reach a leaf, we go back to its
parent node
īŧ If we were visiting the left sub-tree,
we move to the right sub-tree
47. Counting nodes
ī¤ The proposed procedure is, again, recursive
ī¤ When we reach a node (any node):
ī¤ We add +1 to count the current node
ī¤ We ask to count nodes in the left sub-tree
ī¤ We ask to count nodes in the right sub-tree
ī¤ The base case is on a null pointer (i.e., a âmissingâ left sub-tree
or right sub-tree). It is NOT a node:
ī¤ It does not have left children
ī¤ It does not have right children
ī¤ Its contribution to the total count is 0
48. Counting nodes
ī¤ Question: while performing the recursive calls, do the pointers
to the nodes have to be passed by copy or by reference?
49. Counting nodes
ī¤ Question: while performing the recursive calls, do the pointers
to the nodes have to be passed by copy or by reference?
Do I have to propagate any updates to the pointer when I
return from the recursive call execution?
50. Counting nodes
ī¤ Question: while performing the recursive calls, do the pointers
to the nodes have to be passed by copy or by reference?
Do I have to propagate any updates to the pointer when I
return from the recursive call execution?
Do I need to change the tree structure?
51. Counting nodes
ī¤ Answer: counting nodes does not have to change the tree
structure
ī¤ If I passed any pointer by reference, and it was modified by the
function, it would update the pointer in the caller, changing the
structure of the tree (âwhere is the root of the tree now?â)
54. Computing tree height
ī¤ Tree height: length of the longest path between the root and a
leaf
Height
55. Computing tree height
ī¤ The common trick to write correctly tree manipulation functions
is to understand which are the base case and the recursion
step
ī¤ The base case is usually set on the leaves of the tree
ī¤ Which is the right approach to compute tree height?
56. Computing tree height
ī¤ The common trick to write correctly tree manipulation functions
is to understand which are the base case and the recursion
step
ī¤ The base case is usually set on the leaves of the tree
ī¤ Which is the right approach to compute tree height?
ī¤ Base case: if the current pointer is NULL, it means we are at the
âendâ (lower end) of the tree. Thus, the current height is 0 (we are
at the base of the tree)
Height
57. Computing tree height
ī¤ The common trick to write correctly tree manipulation functions
is to understand which are the base case and the recursion
step
ī¤ The base case is usually set on the leaves of the tree
ī¤ Which is the right approach to compute tree height?
ī¤ Base case: if the current pointer is NULL, it means we are at the
âendâ (lower end) of the tree. Thus, the current height is 0 (we are
at the base of the tree)
ī¤ Generic case: if the current pointer is NULL, the current nodeâs
height is 1 + the height of its chidren
Height
58. Computing tree height
Base
Height with respect to
the base: 0
Height (with respect to
the base): 1
Height (with respect to
the base): 2
Height (with respect to
the base): 3
59. Computing tree height
My childâs height: 0
My height: 1+0 = 1
My childâs height: 1
My height: 1+1 = 2
My left childâs height: 1
My right childâs height: 2
My height: 1+max(1,2) = 3
Base
Height with respect to
the base: 0
Height (with respect to
the base): 1
Height (with respect to
the base): 2
Height (with respect to
the base): 3
62. Element search in the tree
ī¤ Element search returns:
ī¤ NULL if the element is not in the tree
ī¤ A pointer to the node that contains the element, if the element is in
the tree
ī¤ The tree is not ordered. Thus, given a node, the element that
we are looking for could be:
ī¤ The current node
ī¤ A node in the left sub-tree
ī¤ A node in the right sub-tree
ī¤ âĻnot present, too!
64. Element search in the tree
ī¤ We will return currentNode if:
ī¤ currentNode is NULL (i.e., we got to the end of the tree and we
did not find anything along the path we followed)
ī¤ currentNode contains the element (i.e., the search is done)
65. Element search in the tree
ī¤ We will return currentNode if:
ī¤ currentNode is NULL (i.e., we got to the end of the tree and we
did not find anything along the path we followed)
ī¤ currentNode contains the element (i.e., the search is done)
ī¤ In case currentNode is not NULL and not containing the
element we want to findâĻ?
66. Element search in the tree
ī¤ We will return currentNode if:
ī¤ currentNode is NULL (i.e., we got to the end of the tree and we
did not find anything along the path we followed)
ī¤ currentNode contains the element (i.e., the search is done)
ī¤ In case currentNode is not NULL and not containing the
element we want to find:
ī¤ We look for the element in the left sub-tree. If the element is here,
Iâll return it
ī¤ If the element is NOT in the left sub-tree, Iâll return the result of the
search in the right sub-tree
ī¤ Either the element, if present, or NULL
70. Printing tree nodes
ī¤ Paths in the tree may have different lengths
ī¤ Approach:
ī¤ navigate the tree first at the left side, then at the right side
ī¤ store each path in a linked list
ī¤ when we reach a leaf, the path is as its end, thus we can print it
(i.e., we print the content of the linked list)
1
2 3
4 5
72. Printing tree nodes
ī¤ How do we print paths?
ī¤ That is:
ī¤ How do we navigate through the tree so as to visit every path, one
after another?
ī¤ How to store a path in a linked list?
73. Printing tree nodes
ī¤ How do we navigate through the tree so as to visit every
path, one after another?
ī¤ We visit the tree by traversing the left sub-trees first and the right
sub-trees after
ī¤ This is similar to what happened with the nodes printing procedure
ī¤ How to store a path in a linked list?
ī¤ At first, we initialize the list as an empty list
ī¤ As we visit nodes along a path, we attach those nodes in the list
ī¤ On the head? On the tail?
74. Printing tree nodes
ī¤ How do we navigate through the tree so as to visit every
path, one after another?
ī¤ We visit the tree by traversing the left sub-trees first and the right sub-
trees after
ī¤ This is similar to what happened with the nodes printing procedure
ī¤ How to store a path in a linked list?
ī¤ At first, we initialize the list as an empty list
ī¤ As we visit nodes along a path, we attach those nodes in the list
ī¤ On the tail, otherwise we will print the path in the wrong direction!
75. Printing tree nodes: initializing the linked
list
ī¤ In printPaths():
ī¤ We initialize the list head
ī¤ We initialize the list tail
ī¤ We start the tree printing procedure
1
2 3
4 5
rootNode
pathHead
pathTail
overload
76. Printing tree nodes
1
2 3
4 5
rootNode
At first we print this
pathâĻ 1
2 3
4 5
rootNode
âĻthen this one.
1
2 3
4 5
rootNode
We go to the left
sub-treeâĻ
1
2 3
4 5
rootNode
âĻand again to
the left sub-tree.
We are at a leaf:
we print the list
77. Printing tree nodes
1
2 3
4 5
rootNode
1
2 3
4 5
rootNode
1
2 3
4 5
rootNode To print this path we go
back to the rootâĻ
1
2 3
4 5
rootNode
âĻand we go to
the right child.
We are at a leaf:
we can print the
list.
We go back to
the parentâĻ
âĻand then to the right child.
We are at a leaf: we print the
list
78. Printing tree nodes
ī¤ We insert the root in the list: 1
ī¤ We require to print the left child
ī¤ We insert the left child in the list: 1 2
ī¤ We require to print the left child
ī¤ We insert the left child in the list: 1 2 4
ī¤ We are at a leaf: we print the list
ī¤ We remove the leaf node from the list: 1 2
ī¤ We require to print the right child
ī¤ We insert the right child in the list: 1 2 5
ī¤ We are at a leaf: we print the list
ī¤ We remove the leaf node from the list: 1 2
ī¤ We remove the left child from the list: 1
ī¤ We require to print the right child
ī¤ We insert the right child in the list: 1 3
ī¤ We are at a leaf: we print the list
ī¤ We remove the leaf node from the list: 1
ī¤ We remove the root from the list:
1
2 3
4 5
79. ī¤ We insert the root in the list: 1
ī¤ We require to print the left child
ī¤ We insert the left child in the list: 1 2
ī¤ We require to print the left child
ī¤ We insert the left child in the list: 1 2 4
ī¤ We are at a leaf: we print the list
ī¤ We remove the leaf node from the list: 1 2
ī¤ We require to print the right child
ī¤ We insert the right child in the list: 1 2 5
ī¤ We are at a leaf: we print the list
ī¤ We remove the leaf node from the list: 1 2
ī¤ We remove the left child from the list: 1
ī¤ We require to print the right child
ī¤ We insert the right child in the list: 1 3
ī¤ We are at a leaf: we print the list
ī¤ We remove the leaf node from the list: 1
ī¤ We remove the root from the list:
Printing tree nodes
First
level
1
2 3
4 5
80. ī¤ We insert the root in the list: 1
ī¤ We require to print the left child
ī¤ We insert the left child in the list: 1 2
ī¤ We require to print the left child
ī¤ We insert the left child in the list: 1 2 4
ī¤ We are at a leaf: we print the list
ī¤ We remove the leaf node from the list: 1 2
ī¤ We require to print the right child
ī¤ We insert the right child in the list: 1 2 5
ī¤ We are at a leaf: we print the list
ī¤ We remove the leaf node from the list: 1 2
ī¤ We remove the left child from the list: 1
ī¤ We require to print the right child
ī¤ We insert the right child in the list: 1 3
ī¤ We are at a leaf: we print the list
ī¤ We remove the leaf node from the list: 1
ī¤ We remove the root from the list:
Printing tree nodes
Second
level
1
2 3
4 5
81. ī¤ We insert the root in the list: 1
ī¤ We require to print the left child
ī¤ We insert the left child in the list: 1 2
ī¤ We require to print the left child
ī¤ We insert the left child in the list: 1 2 4
ī¤ We are at a leaf: we print the list
ī¤ We remove the leaf node from the list: 1 2
ī¤ We require to print the right child
ī¤ We insert the right child in the list: 1 2 5
ī¤ We are at a leaf: we print the list
ī¤ We remove the leaf node from the list: 1 2
ī¤ We remove the left child from the list: 1
ī¤ We require to print the right child
ī¤ We insert the right child in the list: 1 3
ī¤ We are at a leaf: we print the list
ī¤ We remove the leaf node from the list: 1
ī¤ We remove the root from the list:
Printing tree nodes
Base case: leaf node
1
2 3
4 5
82. Printing tree nodes
ī¤ The procedure is recursive
ī¤ When we reach a node
ī¤ We add its content to the list
ī¤ We ask to print the left tree
ī¤ We ask to print the right tree
ī¤ We remove its content from the list
ī¤ Base case: on the leaf
ī¤ We insert its content in the list
ī¤ We ask to print the path from the root to that leaf
ī¤ We remove its content from the list
93. Graph
ī¤ A graph is a set of nodes connected via edges
ī¤ It is usually represented as G(V,E), where:
ī¤ V is the set of nodes
ī¤ E is the set of edges
ī¤ Trees vs. graphs
ī¤ A tree has a unique root, while the graph could have multiple roots
ī¤ Tree nodes have just an incoming edge, while graph edges could
have multiple incoming edges
94. N-ary trees
ī¤ Generalization of binary trees
ī¤ Every node could have an arbitrary number of children
ī¤ It is generally used to represent hierarchical structures (e.g.,
company employees hierarchy)
96. Counting leaf and non-leaf nodes
ī¤ Write:
ī¤ A function that counts the number of leaf nodes
ī¤ A function that counts the number of non-leaf nodes
97. Counting leaf and non-leaf nodes
ī¤ A leaf node is a node without children
ī¤ leftPtr is NULL
ī¤ rightPtr is NULL
ī¤ The non-leaf nodes (called internal nodes) areâĻ all the other
nodes!
non_leaf_nodes = total_nodes â leaf_nodes
99. Counting nodes on even levels
ī¤ Write a function that counts the number of nodes on even
levels of the tree
ī¤ Even levels are the ones having even ID
Level 1
Level 2
Level 3
Level 4
100. Counting nodes on even levels
ī¤ We keep track of the current depth with an integer
ī¤ depth = 1 is we are on the root
ī¤ depth = 2 if we are on the rootâs children
ī¤ âĻ
ī¤ If dividing depth by 2 has null reminder, then we add 1 to the
count of nodes on even levels
102. Equal trees
ī¤ Write a function that, given two trees, returns
ī¤ true if the trees are identical
ī¤ false if the trees are not identical
103. Equal trees
ī¤ Given a node n and a node m, the sub-trees having n and m as
root are identical if:
ī¤ n and m contain the same value
ī¤ The sub-trees having n->leftPtr and m->leftPtr as root are
identical
ī¤ The sub-trees having n->rightPtr and m->rightPtr as root
are identical
109. Sum of leaf nodes (2)
ī¤ Assume that every path is associated with a score, which can
be computed by summing the node values along that path.
Thus, if the tree contains N paths, it contains N scores too (one
for each path)
ī¤ Write a function that returns the highest score
112. Serialize leaves
ī¤ Write a function that extracts all the leaves from the tree and
builds a linked list, in which each node represents one of the
leaves of the tree
113. Serialize leaves
We go down
at the left
We go back and
go down at the
right
We go back and
go down at the
right
115. Ordered tree insertion
ī¤ Write a function that, given a vector<string> as an
input,inserts the words in a tree in an ordered manner: for
every node n in the tree, every word in the left sub-tree come
before the word in n alphabetically, while all the others are in
the right sub-tree
Vector: dog, cat, horse, alpaca, bee, shark, fox, mosquito, sheep
116. Ordered tree insertion
ī¤ For each word from the vector:
ī¤ If it precedes the word contained in the current node, it has to go
down in the left sub-tree
ī¤ If it follows the word contained in the current node, it has to go
down in the right sub-tree
cat < dog
horse > dog alpaca < dog
alpaca < cat
120. Even or odd levels?
ī¤ Write a function that returns true if every number contained in
the even levels are even and every number in the odd levels
are odd, or false otherwise
122. Equal sum on trees
ī¤ Write a function that, given two binary trees, returns true if:
ī¤ The sum of the leaves of the two trees is equal
ī¤ OR
ī¤ The first tree has at least a leaf whose value is equal to the sum of
the values in the leaves of the second tree
ī¤ or false otherwise
127. The mirror
ī¤ Mirroring the tree means that:
ī¤ What is on the left has to go on the right
ī¤ What is on the right has to go on the left
ī¤ We are building a new tree, thus every time we return the
pointer to the new node
ī¤ Behavior:
ī¤ What to do when the pointer is NULL?
ī¤ What to do on the nodes?
128. The mirror
ī¤ Mirroring the tree means that:
ī¤ What is on the left has to go on the right
ī¤ What is on the right has to go on the left
ī¤ We are building a new tree, thus every time we return the
pointer to the new node
ī¤ Behavior:
ī¤ When the pointer is NULL: we return NULL (nothing has to be
created)
ī¤ On the nodes: we return the current node and its sub-trees, which
are swapped