Unit 4 Binary Tree
Unit 4 Binary Tree
Unit 4 Binary Tree
• The above tree is a binary tree because each node contains the atmost two children.
In the above tree, node 1 contains two pointers, i.e., left and a right pointer pointing to the left and right node respectively. The node 2 contains both the nodes (left
and right node); therefore, it has two pointers (left and right). The nodes 3, 5 and 6 are the leaf nodes, so all these nodes contain NULL pointer on both left and right
parts.
Properties of Binary Tree
► The height of the tree is defined as the longest path from the root node to the leaf node. The tree
which is shown above has a height equal to 3. Therefore, the maximum number of nodes at height 3
is equal to (1+2+4+8) = 15.
► The minimum number of nodes possible at height h is equal to h+1.
2. The complete binary tree is a tree in which all the nodes are completely filled except the last level. In the
last level, all the nodes must be as left as possible. In a complete binary tree, the nodes should be added from
the left.
► Perfect Binary Tree
► A tree is a perfect binary tree if all the internal nodes have 2 children, and all the leaf nodes are at the same
level.
► The below tree is not a perfect binary tree because all the leaf nodes are not at the same level.
► Degenerate Binary Tree
► The degenerate binary tree is a tree in which all the internal nodes have only one children.
► Let's understand the Degenerate binary tree through examples.
► The beside tree is a degenerate binary tree because all the nodes
have only one child.
It is also known as a right-skewed tree as all the nodes have a right child only.
► Balanced Binary Tree
► The balanced binary tree is a tree in which both the left and right trees differ by atmost 1.
Binary tree implementation
A Binary tree is implemented with the help of pointers. The first node in the tree is represented by
the root pointer. Each node in the tree consists of three parts, i.e., data, left pointer and right
pointer. To create a binary tree, we first need to create the node. We will create the node of user-
defined as shown below:
struct node
{
int data,
struct node *left, *right;
}
In the above structure, data is the value, left pointer contains the address of the left node,
and right pointer contains the address of the right node.
void main()
{
struct node *root;
root = create();
}
struct node *create()
{
struct node *temp;
int data;
temp = (struct node *)malloc(sizeof(struct node));
printf("Press 0 to exit");
printf("\n Press 1 for new node");
printf("Enter your choice : ");
scanf("%d", &choice);
if(choice==0)
{
return 0;
}
else
{
printf("Enter the data:");
scanf("%d", &data);
temp->data = data;
printf("Enter the left child of %d", data);
temp->left = create();
printf("Enter the right child of %d", data);
temp->right = create();
return temp;
}
}
The above code is calling the create() function recursively and creating new node on each recursive call. When all the nodes are created, then it forms a binary tree structure.
The process of visiting the nodes is known as tree traversal.
There are three types traversals used to visit a node:
► Inorder traversal
► Preorder traversal
► Postorder traversal
1. In-order Traversal
► In this traversal method, the left subtree is visited first, then the root and later the right sub-tree. We should always remember that every node may represent a subtree itself.
► If a binary tree is traversed in-order, the output will produce sorted key values in an ascending order.
► We start from A, and following in-order traversal, we move to its left subtree B. B is also traversed in-order. The process goes on until all the nodes are visited. The output of inorder
traversal of this tree will be −
► D→B→E→A→F→C→G
Until all nodes are traversed −
Step 1 − Recursively traverse left subtree.
Step 2 − Visit root node.
Step 3 − Recursively traverse right subtree.
Pre-order Traversal
In this traversal method, the root node is visited first, then the left subtree and finally the right
subtree.
We start from A, and following pre-order traversal, we first visit A itself and then move to its left
subtree B. B is also traversed pre-order. The process goes on until all the nodes are visited. The
output of pre-order traversal of this tree will be −
A→B→D→E→C→F→G
Algorithm
Until all nodes are traversed −
Step 1 − Visit root node.
Step 2 − Recursively traverse left subtree.
Step 3 − Recursively traverse right subtree.
Post-order Traversal
In this traversal method, the root node is visited last, hence the name.
First we traverse the left subtree, then the right subtree and finally the root node.
► We start from A, and following Post-order traversal, we first visit the left subtree B. B is also traversed post-
order. The process goes on until all the nodes are visited. The output of post-order traversal of this tree will
be −
► D→E→B→F→G→C→A
Algorithm
Until all nodes are traversed −
Step 1 − Recursively traverse left subtree.
Step 2 − Recursively traverse right subtree.
Step 3 − Visit root node.
void pre_order_traversal(struct node* root) {
if(root != NULL) {
printf("%d ",root->data);
pre_order_traversal(root->leftChild);
pre_order_traversal(root->rightChild);
}
}
return newNode;
void insert(int data) {
//Create a new node
struct node *newNode = createNode(data);
while(true) {
//parent keep track of the parent node of current node.
parent = current;
//If data is less than current's data, node will be inserted to the left of tree
if(data < current->data) {
current = current->left;
if(current == NULL) {
parent->left = newNode;
return;
}
}
//If data is greater than current's data, node will be inserted to the right of tree
else {
current = current->right;
if(current == NULL) {
parent->right = newNode;
return;
}
}
}
}
struct node* deleteNode(struct node *node, int value) {
if(node == NULL){
return NULL;
}
else {
//value is less than node's data then, search the value in left subtree
if(value < node->data)
node->left = deleteNode(node->left, value);
//value is greater than node's data then, search the value in right subtree
else if(value > node->data)
node->right = deleteNode(node->right, value);
//If value is equal to node's data that is, we have found the node to be deleted
else {
//If node to be deleted has no child then, set the node to NULL
if(node->left == NULL && node->right == NULL)
node = NULL;
► Threaded binary tree is a simple binary tree but they have a specialty that null
pointers of leaf node of the binary tree is set to in order predecessor or in order
successor.
► The main idea behind setting such a structure is to make the in order and
preorder traversal of the tree faster without using any additional data
structure(e.g auxilary stack) or memory to do the traversal.
Types of Threaded Binary Tree
► The idea of threaded binary trees is to make inorder traversal of the binary tree
faster and do it without using any extra space, so sometimes in small systems
where hardware is very limited we use threaded binary tree for better efficiency
of the software in a limited hardware space.
Balanced Trees- AVL Tree
Balanced binary tree
● The disadvantage of a binary search tree is that its height can be as large as N-1
● This means that the time needed to perform insertion and deletion and many
other operations can be O(N) in the worst case
● We want a tree with small height
● A binary tree with N node has height at least (log N)
● Thus, our goal is to keep the height of a binary search tree O(log N)
● Such trees are called balanced binary search trees. Examples are AVL tree, red-
black tree.
Binary Search Tree - Best Time
● All BST operations are O(h), where d is tree depth
● minimum d is for a binary tree with N nodes
■ What is the best case tree?
■ What is the worst case tree?
● So, best case running time of BST operations is O(log N) 2h log N
Binary Search Tree - Worst Time
LL Rotation
► Weighted Graph - In a weighted graph, each edge is assigned with some data such as length or weight.
The weight of an edge e can be given as w(e) which must be a positive (+) value indicating the cost of
traversing the edge.
► Digraph - A digraph is a directed graph in which each edge of the graph is associated with some direction
and the traversing can be done only in the specified direction.
► Loop - An edge that is associated with the similar end points can be called as Loop.
► Adjacent Nodes - If two nodes u and v are connected via an edge e, then the nodes u and v are called
as neighbors or adjacent nodes.
► Degree of the Node - A degree of a node is the number of edges that are connected with that node. A
node with degree 0 is called as isolated node.
Linked Representation
► In the linked representation, an adjacency list is used to store the Graph into the computer's memory.
► Consider the undirected graph shown in the following figure and check the adjacency list representation.
An adjacency list is maintained for each node present in the graph which stores the node value and a
pointer to the next adjacent node to the respective node. If all the adjacent nodes are traversed then store
the NULL in the pointer field of last node of the list. The sum of the lengths of adjacency lists is equal to the
twice of the number of edges present in an undirected graph.
Graph Traversal Algorithm
Traversing the graph means examining all the nodes and vertices of the graph. There are two standard
methods by using which, we can traverse the graphs. Lets discuss each one of them in detail.
► Breadth First Search
► Depth First Search
Push H onto the stack Pop the top of the stack i.e. B and push all the neighbours
STACK : H
POP the top element of the stack i.e. H, print it and push all Print B
the neighbours of H onto the stack that are is ready state. Stack : C
Print H Pop the top of the stack i.e. C and push all the neighbours.
STACK : A Print C
Pop the top element of the stack i.e. A, print it and push all the Stack : E, G
neighbours of A onto the stack that are in ready state.
Pop the top of the stack i.e. G and push all its neighbours.
Print A
Print G
Stack : B, D
Stack : E
Pop the top element of the stack i.e. D, print it and push all the
neighbours of D onto the stack that are in ready state. Pop the top of the stack i.e. E and push all its neighbours.
Print D Print E
Stack : B, F Stack :
Pop the top element of the stack i.e. F, print it and push all the Hence, the stack now becomes empty and all the nodes of the
neighbours of F onto the stack that are in ready state. graph have been traversed.
The printing sequence of the graph will be :
Print F H→A→D→F→B→C→G→E
Warshall Algorithm
Floyd-Warshall Algorithm is an algorithm for finding the shortest path between all the pairs of vertices in a
weighted graph. This algorithm works for both the directed and undirected weighted graphs.
Follow the steps below to find the shortest path between all the pairs of vertices.
1. Create a matrix A0 of dimension n*n where n is the number of vertices. The row and the column are
indexed as i and j respectively. i and j are the vertices of the graph.
2. Each cell A[i][j] is filled with the distance from the i th vertex to the jth vertex. If there is no path from ith
vertex to jth vertex, the cell is left as infinity.
Now, create a matrix A1 using matrix A0. The elements in the first column and the first row are left as they
are. The remaining cells are filled in the following way.
Let k be the intermediate vertex in the shortest path from source to destination. In this step, k is the first
vertex. A[i][j] is filled with (A[i][k] + A[k][j]) if (A[i][j] > A[i][k] + A[k][j]).
That is, if the direct distance from the source to the destination is greater than the path through the
vertex k, then the cell is filled with A[i][k] + A[k][j].
In this step, k is vertex 1. We calculate the distance from source vertex to destination vertex through this
vertex k.
► or example: For A1[2, 4], the direct distance from vertex 2 to 4 is 4 and the sum of the distance from
vertex 2 to 4 through vertex (ie. from vertex 2 to 1 and from vertex 1 to 4) is 7. Since 4 < 7, A0[2, 4] is
filled with 4.
► Similarly, A2 is created using A1. The elements in the second column and the second row are left as they
are.
In this step, k is the second vertex (i.e. vertex 2). The remaining steps are the same as in step 2.