Professional Documents
Culture Documents
A Tree is a recursive data structure containing the set of one or more data nodes where one node is
designated as the root of the tree while the remaining nodes are called as the children of the root.
The nodes other than the root node are partitioned into the non empty sets where each one of them is
to be called sub-tree.
Nodes of a tree either maintain a parent-child relationship between them or they are sister nodes.
In a general tree, A node can have any number of children nodes but it can have only a single parent.
The following image shows a tree, where the node A is the root node of the tree while the other nodes
can be seen as the children of A.
Page 1 of 41
int father;
int son;
int next;
}
Types of Tree:
Topics to be covered:
Binary Tree
Traversal
BFS
DFS
Binary Tree
Binary Tree is a special type of generic tree in which, each node can have at most two children. Binary
tree is generally partitioned into three disjoint subsets.
Page 2 of 41
1. Root of the node
2. left sub-tree which is also a binary tree.
3. Right binary sub-tree
A binary Tree is shown in the following image.
In Strictly Binary Tree, every non-leaf node contain non-empty left and right sub-trees. In other words,
the degree of every non-leaf node will always be 2. A strictly binary tree with n leaves, will have (2n - 1)
nodes.
Page 3 of 41
2. Complete Binary Tree
A Binary Tree is said to be a complete binary tree if all of the leaves are located at the same level d. A
complete binary tree is a binary tree that contains exactly 2^l nodes at each level between level 0 and
d. The total number of nodes in a complete binary tree with depth d is 2d+1-1 where leaf nodes are 2d
while non-leaf nodes are 2d-1.
Page 4 of 41
Binary Tree implementation in java
For the implementation, there’s an auxiliary Node class that will store int values and keeps a reference
to each child. The first step is to find the place where we want to add a new node in order to keep the
tree sorted. We’ll follow these rules starting from the root node:
• if the new node’s value is lower than the current node’s, go to the left child
• if the new node’s value is greater than the current node’s, go to the right child
• when the current node is null, we’ve reached a leaf node, we insert the new node in that
position
Now let’s see how we can implement this logic with the help of an example:
Page 5 of 41
Code:
class Main
int value;
Node(int value)
this.value = value;
left = null;
right = null;
Page 6 of 41
if (node.left != null)
insert(node.left, value);
else
if (node.right != null)
insert(node.right, value);
else
Page 7 of 41
if (node != null)
traverseInOrder(node.left);
traverseInOrder(node.right);
tree.insert(root, 2);
tree.insert(root, 4);
tree.insert(root, 8);
tree.insert(root, 6);
tree.insert(root, 7);
tree.insert(root, 3);
tree.insert(root, 9);
Page 8 of 41
Level order traversal of the above tree is 1 2 3 4 5
Algorithm:
There are basically two functions in this method. One is to print all nodes at a given level
(printGivenLevel), and other is to print level order traversal of the tree (printLevelorder).
printLevelorder makes use of printGivenLevel to print nodes at all levels one by one starting from root.
Code:
class Node
int data;
Page 9 of 41
public Node(int item)
data = item;
class BinaryTree
Node root;
public BinaryTree()
root = null;
void printLevelOrder()
int h = height(root);
int i;
printGivenLevel(root, i);
Page 10 of 41
/* Compute the "height" of a tree -- the number of nodes along the longest path from the root
node
if (root == null)
return 0;
else
return(lheight+1);
else return(rheight+1);
if (root == null)
Page 11 of 41
return;
if (level == 1)
printGivenLevel(root.left, level-1);
printGivenLevel(root.right, level-1);
tree.printLevelOrder();
Page 12 of 41
Traversal means visiting all the nodes of a graph. Breadth first traversal or Breadth first Search is a
recursive algorithm for searching all the vertices of a graph or tree data structure. In this article, you
will learn with the help of examples the BFS algorithm, BFS pseudocode and the code of the breadth
first search algorithm with implementation in C++, C, Java and Python programs.
Algorithm:
A standard BFS implementation puts each vertex of the graph into one of two categories:
1. Visited
2. Not Visited
The purpose of the algorithm is to mark each vertex as visited while avoiding cycles.
1. Start by putting any one of the graph's vertices at the back of a queue.
2. Take the front item of the queue and add it to the visited list.
3. Create a list of that vertex's adjacent nodes. Add the ones which aren't in the visited list to the
back of the queue.
4. Keep repeating steps 2 and 3 until the queue is empty.
The graph might have two different disconnected parts so to make sure that we cover every vertex, we
can also run the BFS algorithm on every node
Let's see how the Breadth First Search algorithm works with an example. We use an undirected graph
with 5 vertices.
We start from vertex 0, the BFS algorithm starts by putting it in the Visited list and putting all its
adjacent vertices in the stack.
Page 13 of 41
Next, we visit the element at the front of queue i.e. 1 and go to its adjacent nodes. Since 0 has already
been visited, we visit 2 instead.
Vertex 2 has an unvisited adjacent vertex in 4, so we add that to the back of the queue and visit 3,
which is at the front of the queue.
Page 14 of 41
Only 4 remains in the queue since the only adjacent node of 3 i.e. 0 is already visited. We visit it.
Since the queue is empty, we have completed the Depth First Traversal of the graph.
BFS pseudocode
create a queue Q
while Q is non-empty
Page 15 of 41
Minimum Path P can be found by applying breadth first search algorithm that will begin at node A and
will end at E. the algorithm uses two queues, namely QUEUE1 and QUEUE2. QUEUE1 holds all the
nodes that are to be processed while QUEUE2 holds all the nodes that are processed and deleted from
QUEUE1.
1. QUEUE1 = {A}
2. QUEUE2 = {NULL}
2. Delete the Node A from QUEUE1 and insert all its neighbours. Insert Node A into QUEUE2
1. QUEUE1 = {B, D}
2. QUEUE2 = {A}
3. Delete the node B from QUEUE1 and insert all its neighbours. Insert node B into QUEUE2.
1. QUEUE1 = {D, C, F}
2. QUEUE2 = {A, B}
4. Delete the node D from QUEUE1 and insert all its neighbours. Since F is the only neighbour of it
which has been inserted, we will not insert it again. Insert node D into QUEUE2.
1. QUEUE1 = {C, F}
2. QUEUE2 = { A, B, D}
5. Delete the node C from QUEUE1 and insert all its neighbours. Add node C to QUEUE2.
1. QUEUE1 = {F, E, G}
2. QUEUE2 = {A, B, D, C}
Page 16 of 41
6. Remove F from QUEUE1 and add all its neighbours. Since all of its neighbours has already been
added, we will not add them again. Add node F to QUEUE2.
1. QUEUE1 = {E, G}
2. QUEUE2 = {A, B, D, C, F}
7. Remove E from QUEUE1, all of E's neighbours has already been added to QUEUE1 therefore we
will not add them again. All the nodes are visited and the target node i.e. E is encountered into
QUEUE2.
1. QUEUE1 = {G}
2. QUEUE2 = {A, B, D, C, F, E}
DFS algorithm
A standard DFS implementation puts each vertex of the graph into one of two categories:
1. Visited
2. Not Visited
The purpose of the algorithm is to mark each vertex as visited while avoiding cycles.
Page 17 of 41
We start from vertex 0, the DFS algorithm starts by putting it in the Visited list and putting all its
adjacent vertices in the stack.
Next, we visit the element at the top of stack i.e. 1 and go to its adjacent nodes. Since 0 has already
been visited, we visit 2 instead.
Vertex 2 has an unvisited adjacent vertex in 4, so we add that to the top of the stack and visit it.
Page 18 of 41
Vertex 2 has an unvisited adjacent vertex in 4, so we add that to the top of the stack and visit it.
After we visit the last element 3, it doesn't have any unvisited adjacent nodes, so we have completed
the Depth First Traversal of the graph.
After we visit the last element 3, it doesn't have any unvisited adjacent nodes, so we have completed
the Depth First Traversal of the graph.
DFS(G, u)
Page 19 of 41
u.visited = true
for each v ∈ G.Adj[u]
if v.visited == false
DFS(G,v)
init() {
For each u ∈ G
u.visited = false
For each u ∈ G
DFS(G, u)
}
Inorder Traversal
In this program, we need to create a binary search tree, delete a node from the tree, and display the
nodes of the tree by traversing the tree using in-order traversal. In in-order traversal, for a given node,
first, we traverse the left child then root then right child (Left -> Root -> Right).
Page 20 of 41
In Binary Search Tree, all nodes which are present to the left of root will be less than root node and
nodes which are present to the right will be greater than the root node.
Insertion:
1. If the value of the new node is less than the root node then, it will be inserted to the left subtree.
2. If the value of the new node is greater than root node then, it will be inserted to the right subtree.
Deletion:
1. If the node to be deleted is a leaf node then, parent of that node will point to null. For eg. If we
delete 90, then parent node 70 will point to null.
2. If the node to be deleted has one child node, then child node will become a child node of the parent
node. For eg. If we delete 30, then node 10 which was left child of 30 will become left child of 50.
3. If the node to be deleted has two children then, we find the node(minNode) with minimum value
from the right subtree of that current node. The current node will be replaced by its
successor(minNode).
Algorithm:
1. Define Node class which has three attributes namely: data, left and right. Here, left represents
the left child of the node and right represents the right child of the node.
2. When a node is created, data will pass to the data attribute of the node and both left and right
will be set to null.
3. Define another class which has an attribute root.
a. Root represents the root node of the tree and initializes it to null.
4. insert() will insert the new value into a binary search tree:
a. It checks whether root is null, which means tree is empty. New node will become root
node of tree.
b. If tree is not empty, it will compare value of new node with root node. If value of new
node is greater than root, new node will be inserted to right subtree. Else, it will be
inserted in left subtree.
5. deleteNode() will delete a particular node from the tree:
a. If value of node to be deleted is less than root node, search node in left subtree. Else,
search in right subtree.
b. If node is found and it has no children, then set the node to null.
c. If node has one child then, child node will take position of node.
Page 21 of 41
d. If node has two children then, find a minimum value node from its right subtree. This
minimum value node will replace the current node.
Block of code:
Code:
class Node
int key;
key = item;
Page 22 of 41
}
class Main
Node root;
Main()
root = null;
if (node == null)
return;
printInorder(node.left);
Page 23 of 41
/* now recur on right child */
printInorder(node.right);
// Driver method
tree.printInorder();
Preorder Traversal
Page 24 of 41
In PreOrder traversal,each node is processed before either of its sub-trees.In simpler words,Visit each
node before its children.
Algorithm:
Block of Code:
Page 25 of 41
Code:
class Node
int key;
key = item;
class Main
Page 26 of 41
// Root of Binary Tree
Node root;
Main()
root = null;
if (node == null)
return;
printPreorder(node.left);
printPreorder(node.right);
Page 27 of 41
// Wrappers over above recursive functions
// Driver method
tree.printPreorder();
Postorder Traversal
In PostOrder traversal, each node is processed after subtrees traversal.In simpler words,Visit left
subtree, right subtree and then node.
Page 28 of 41
Algorithm:
Block of Code:
Page 29 of 41
Code:
class Node
int key;
key = item;
class Main
Page 30 of 41
// Root of Binary Tree
Node root;
Main()
root = null;
if (node == null)
return;
printPostorder(node.left);
printPostorder(node.right);
Page 31 of 41
// Wrappers over above recursive functions
// Driver method
tree.printPostorder();
Page 32 of 41
Page 33 of 41
Page 34 of 41
Page 35 of 41
Page 36 of 41
Page 37 of 41
Page 38 of 41
Page 39 of 41
Page 40 of 41
Page 41 of 41