Data Structures Lab 8 9 Binary Trees
Data Structures Lab 8 9 Binary Trees
BINARY TREES
Outline
• Binary tree Introduction.
• Types of Binary tree.
• Representation of Binary tree using arrays and
linked list.
• Operations of Binary tree pseudocode.
• Applications of Binary tree.
• Exercise.
• Prelab Questions.
Introduction - Binary Tree
• We can represent any tree as a binary tree. Binary trees are an important type of tree
structure that occurs very often.
• In a normal tree, every node can have any number of children. Binary tree is a special
type of tree data structure in which every node can have a maximum of 2 children. One
is known as left child and the other is known as right child.
• A tree is called Binary Tree if each node has zero, one or two children,
• Empty tree is also a valid binary tree.
• We can visualize a binary tree as consisting of root, and two disjoint binary trees, called
the left and right sub-tree of the root.
• A Binary tree is a tree whose root has at most 2 children, each of which is a binary tree
Types of Binary Trees
• Strict Binary Tree: each node has exactly two children or no children.
• Full Binary Tree: each node has exactly two children or no children, and all leaf nodes are
at same level. (Also called as proper binary tree)
• Complete Binary Tree: if all leaf nodes are at level ‘h’ or ‘h-1’ and also all nodes are as far
left as possible
Properties of Binary Trees
Let us assume that the height of the tree is h.
1.Number of nodes in a FULL BINARY tree is : 2h+1-1
Since, there are h levels we need to add all nodes at
each level: [20 + 21+ 22 + ··· + 2h = 2h+1 – 1].
• Disadvantages :
– Wastage of space
– insertion/deletion problem
Representing Binary Trees : Linked Representation
• For simplicity, assume that the data of the nodes are integers.
• One way to represent a node (which contains data) is to have two links which point to left and right
children along with data fields as shown below:
struct BinaryTreeNode
{
int data;
struct BinaryTreeNode *left;
struct BinaryTreeNode *right;
};
left_child right_child
Operations on Binary Trees
• Basic Operations:
– Inserting an element into the tree
– Deleting an element from the tree
– Searching for an element
– Traversing the Tree (algorithm for visiting every node in a tree)
• Level Order Traversal ( Breadth-First Traversal) : Starting from the root node, visit both of
its children first, then all of its grandchildren, then great-grandchildren, until all the levels
are covered
• PreOrder : Root – Left – Right (Depth-first traversal)
• InOrder : Left – Root – Right
• PostOrder : Left – Right – Root
• Auxiliary Operations:
– Finding the size of a node/tree
– Finding the height/depth of the tree
– Finding height/depth of a node
– Finding minimum/maximum element in a binary tree
– Finding the level which has maximum sum
– Finding the parent/child of a given node
– Finding ancestors/descendants of a given node
– Finding the least common ancestor (LCA) for a given pair of nodes
Level Order Traversal – Uses Queue
• Algorithm
– Visit the root
– While traversing level l, keep all the elements at level l+1 in queue
– Go to the next level and visit all nodes at that level
– Repeat this until all levels are completed.
PseudoCode:
PseudoCode:
PseudoCode:
• Given a Binary Tree, return true if a node with the given data is found in the tree.
Algorithm
– Start with the root node.
– Recurse down the tree,
– Choose the left or right branch by comparing data with each node’s data.
if (temp->right)
Enqueue(temp->right, que);
}
return 0;
}
Insert Operation : Binary Tree
• Given a Binary Tree, we can insert the element wherever we want. To insert an
element, we can use level order traversal and insert the element wherever we
find the node whose left child or right child is NULL.
• Algorithm
– If the tree is empty, initialize the root with new node
– Else, Push root into Queue
– Get the front node of the queue
• If the left child of this front node doesn’t exist, set the new node as the
left child
• Else if the right child of this front node doesn’t exist, set the new node
as the right child
– If the front node has both left child and right child, Dequeue it
– Enqueue the new node.
Insert Operation : Binary Tree
PseudoCode:
void insert(struct BinaryNode *root, int data)
{
struct Queue *Q;
struct BinaryNode *temp;
struct BinaryNode *newNode = (struct BinaryNode*) malloc(sizeof(struct BinaryNode));
newNode->data = data;
newNode->left = newNode->right = NULL;
if (!root)
{
root = newNode;
return;
}
Q=CreateQueue();
EnQueue(Q,root);
while(!IsEmptyQueue(Q))
{
temp = DeQueue(Q);
if (temp->left)
EnQueue(Q,temp->left);
else
{
temp->left=newNode;
DeleteQueue(Q);
return;
}
if (temp->right)
EnQueue(Q,temp->right);
else
{
temp->right=newNode;
DeleteQueue(Q);
return;
}
}
DeleteQueue(Q);
}
Delete Operation : Binary Tree
• Binary Tree Shrinks from the bottom
• Algorithm
– Starting at root, find the node which we want to delete
– Find the deepest, right most node in the tree.
– Replace the deepest right most node’s data with node to be deleted.
– Then delete the deepest rightmost node.
Delete Operation : Binary Tree
PseudoCode:
//Deleted node is replaced by deepest node - bottom most and rightmost node
struct node* delete(struct node* root, int key)
{
struct Queue* que = createQueue(SIZE);
struct node *del, *last, *temp;
Enqueue(root, que);
while (!isEmpty(que))
{
temp = Dequeue(que);
if( temp->data == key)
del= temp;
if (temp->left)
Enqueue(temp->left, que);
if (temp->right)
Enqueue(temp->right, que);
}
if (del == temp) // if the node to be deleted is the deepest node
root=del_node(root, temp);
else // if the node to be deleted is not the deepest node
{
del->data=temp->data; //copy data of the deepest node into the node whose key has to be deleted
root=del_node(root, temp);
}
return root;
}
Delete Operation : Binary Tree
PseudoCode- continuation:
struct node* del_node(struct node* root, struct node* del_node) {
struct Queue* que = createQueue(SIZE);
Enqueue(root, que);
while (!isEmpty(que)) {
struct node* temp = Dequeue(que);
if (temp==del_node){ //deleting the last remaining node of the tree
root=NULL; free(temp); return NULL;
}
if (temp->right){
if(temp->right == del_node){
temp->right=NULL; free(del_node); return root;
}
else
Enqueue(temp->right, que);
}
if (temp->left){
if(temp->left == del_node) {
temp->left=NULL; free(del_node); return root;
}
else
Enqueue(temp->left, que);
}
}
}
Binary Tree Construction
preorder = ab a a
postorder = ba b b
gdhbei fjc
Inorder And Preorder
a
gdhbei fjc
• preorder = a b d g h e i c f j
• b is the next root; gdh are in the left
subtree; ei are in the right subtree.
a
b fjc
gdh ei
Inorder And Preorder
a
b fjc
gdh ei
• preorder = a b d g h e i c f j
• d is the next root; g is in the left
subtree; h is in the right subtree.
a
b fjc
d ei
g h
Inorder And Postorder
In the following link questions look interesting, all the students try
to learn all and code by yourself.
https://medium.com/techie-delight/binary-tree-interview-
questions-and-practice-problems-439df7e5ea1f