0% found this document useful (0 votes)
88 views

Data Structures (Tree)

The document discusses data structures, specifically trees and binary trees. It provides definitions and examples of key tree concepts like root, leaf nodes, height, and binary tree properties. It also explains different types of binary trees and covers algorithms for traversing binary trees using inorder, preorder, and postorder traversal methods. Code snippets in C++ are included to demonstrate implementing these traversal algorithms.
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
88 views

Data Structures (Tree)

The document discusses data structures, specifically trees and binary trees. It provides definitions and examples of key tree concepts like root, leaf nodes, height, and binary tree properties. It also explains different types of binary trees and covers algorithms for traversing binary trees using inorder, preorder, and postorder traversal methods. Code snippets in C++ are included to demonstrate implementing these traversal algorithms.
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 42

DATA STRUCTURES(BASICS) Himanshu Kumar

DATA STRUCTURE (BASICS)


[TREES]
PLACEMENT PREPARATION [EXCLUSIVE NOTES]

SAVE AND SHARE


Curated By- HIMANSHU KUMAR(LINKEDIN)
https://www.linkedin.com/in/himanshukumarmahuri

TOPICS COVERED-
▪ Introduction to Trees
▪ Binary Tree Traversals
▪ Level Order Traversal of a Binary Tree
▪ Insertion in a Binary Tree
▪ Deletion in a Binary Tree
▪ Finding LCA in Binary Tree
▪ Diameter of a Binary Tree
▪ Left, Right, Top and Bottom View of a Binary Tree
▪ Threaded Binary Tree Sample
▪ Problems on Trees

Introduction to Trees-
A Tree is a non-linear data structure where each node is connected to a
number of nodes with the help of pointers or references.

A Sample tree is as shown below:

pg. 1 | HIMANSHU KUMAR (LINKEDIN)


DATA STRUCTURES(BASICS) Himanshu Kumar

Basic Tree Terminologies:

• Root: The root of a tree is the first node of the tree. In the above image, the
root node is the node 30.
• Edge: An edge is a link connecting any two nodes in the tree. For example, in
the above image there is an edge between node 11 and 6.
• Siblings: The children nodes of same parent are called siblings. That is, the
nodes with same parent are called siblings. In the above tree, nodes 5, 11,
and 63 are siblings.
• Leaf Node: A node is said to be the leaf node if it has no children. In the
above tree, node 15 is one of the leaf nodes.
• Height of a Tree: Height of a tree is defined as the total number of levels in
the tree or the length of the path from the root node to the node present at
the last level. The above tree is of height 2.

Binary Tree
A Tree is said to be a Binary Tree if all of its nodes have atmost 2 children.
That is, all of its node can have either no child, 1 child, or 2 child nodes.

pg. 2 | HIMANSHU KUMAR (LINKEDIN)


DATA STRUCTURES(BASICS) Himanshu Kumar

Below is a sample Binary Tree:

Properties of a Binary Tree:

1. The maximum number of nodes at level 'l' of a binary tree is (2l - 1). Level of
root is 1.

This can be proved by induction.


For root, l = 1, number of nodes = 21-1 = 1
Assume that the maximum number of nodes on level l is 2l-1.
Since in Binary tree every node has at most 2 children, next level would have
twice nodes, i.e. 2 * 2l-1.
2. Maximum number of nodes in a binary tree of height 'h' is (2h – 1).
Here height of a tree is the maximum number of nodes on the root to leaf
path. The height of a tree with a single node is considered as 1.
This result can be derived from point 2 above. A tree has maximum nodes if
all levels have maximum nodes. So maximum number of nodes in a binary
tree of height h is 1 + 2 + 4 + .. + 2h-1. This is a simple geometric series with
h terms and sum of this series is 2h – 1.
In some books, the height of the root is considered as 0. In that convention,
the above formula becomes 2h+1 – 1.
3. In a Binary Tree with N nodes, the minimum possible height or the
minimum number of levels is Log2(N+1). This can be directly derived from
point 2 above. If we consider the convention where the height of a leaf node
is considered 0, then above formula for minimum possible height becomes
Log2(N+1) – 1.

pg. 3 | HIMANSHU KUMAR (LINKEDIN)


DATA STRUCTURES(BASICS) Himanshu Kumar

4. A Binary Tree with L leaves has at least (Log2L + 1) levels. A Binary tree
has maximum number of leaves (and minimum number of levels) when all
levels are fully filled. Let all leaves be at level l, then below is true for
number of leaves L.

L <= 2l-1 [From Point 1]


l = Log2L + 1
where l is the minimum number of levels.

5. In a Binary tree in which every node has 0 or 2 children, the number of leaf
nodes is always one more than the nodes with two children.

L = T + 1
Where L = Number of leaf nodes
T = Number of internal nodes with two children

Types of Binary Trees: Based on the structure and number of parents and children
nodes, a Binary Tree is classified into the following common types:

• Full Binary Tree: A Binary Tree is full if every node has either 0 or 2 children.
The following are examples of a full binary tree. We can also say that a full
binary tree is a binary tree in which all nodes except leave nodes have two
children.

pg. 4 | HIMANSHU KUMAR (LINKEDIN)


DATA STRUCTURES(BASICS) Himanshu Kumar

In a Full Binary, the number of leaf nodes is number of internal


nodes plus 1.

• Complete Binary Tree: A Binary Tree is a complete Binary Tree if all levels
are completely filled except possibly the last level and the last level has all
keys as left as possible

Following are the examples of Complete Binary Trees:

• Perfect Binary Tree: A Binary tree is a Perfect Binary Tree when all internal
nodes have two children and all the leave nodes are at the same level.

Following are the examples of Perfect Binary Trees:

pg. 5 | HIMANSHU KUMAR (LINKEDIN)


DATA STRUCTURES(BASICS) Himanshu Kumar

A Perfect Binary Tree of height h (where height is the number of nodes on


the path from the root to leaf) has 2h – 1 node.

Binary Tree Traversals-


Unlike linear data structures (Array, Linked List, Queues, Stacks, etc.), which have
only one logical way to traverse them, trees can be traversed in different ways.
Following are the generally used ways for traversing trees:

• Inorder (Left, Root, Right) : 4 2 5 1 3


• Preorder (Root, Left, Right) : 1 2 4 5 3.
• Postorder (Left, Right, Root) : 4 5 2 3 1

Let's look at each of these tree traversal algorithms in details:

pg. 6 | HIMANSHU KUMAR (LINKEDIN)


DATA STRUCTURES(BASICS) Himanshu Kumar

• Inorder Traversal: In Inorder traversal, a node is processed after processing


all the nodes in its left subtree. The right subtree of the node is processed
after processing the node itself.

Algorithm Inorder(tree)
1. Traverse the left subtree, i.e.,
call Inorder(left->subtree)
2. Visit the root.
3. Traverse the right subtree, i.e.,
call Inorder(right->subtree)

Example: Inorder traversal for the above-given tree is 4 2 5 1 3.

• Preorder Traversal: In preorder traversal, a node is processed before


processing any of the nodes in its subtree.

Algorithm Preorder(tree)
1. Visit the root.
2. Traverse the left subtree, i.e.,
call Preorder(left-subtree)
3. Traverse the right subtree, i.e.,
call Preorder(right-subtree)

Example: Preorder traversal for the above-given tree is 1 2 4 5 3.

• Postorder Traversal: In post order traversal, a node is processed after


processing all the nodes in its subtrees.

Algorithm Postorder(tree)
1. Traverse the left subtree, i.e.,
call Postorder(left-subtree)
2. Traverse the right subtree, i.e.,
call Postorder(right-subtree)
3. Visit the root.

Example: Postorder traversal for the above-given Tree is 4 5 2 3 1.

pg. 7 | HIMANSHU KUMAR (LINKEDIN)


DATA STRUCTURES(BASICS) Himanshu Kumar

C++ :-
// C++ program for different tree traversals /* now recur on right child */

#include <iostream> printInorder(node->right);

using namespace std; }

/* A binary tree node has data, pointer to left child // Function to print the PreOrder traversal

and a pointer to right child */ // of a Binary Tree

struct Node void printPreorder(struct Node* node)

{ {

int data; if (node == NULL)

struct Node* left, *right; return;

Node(int data) /* first print data of node */

{ cout << node->data << " ";

this->data = data; /* then recur on left sutree */

left = right = NULL; printPreorder(node->left);

} /* now recur on right subtree */

}; printPreorder(node->right);

// Function to print the postorder traversal }

// of a Binary Tree // Driver Code

void printPostorder(struct Node* node) int main()

{ {

if (node == NULL) // Contrust the Tree

return; // 1

// first recur on left subtree // / \

printPostorder(node->left); // 2 3

// then recur on right subtree // / \

printPostorder(node->right); // 4 5

// now deal with the node struct Node *root = new Node(1);

cout << node->data << " "; root->left = new Node(2);

} root->right = new Node(3);

// Function to print the Inorder traversal root->left->left = new Node(4);

// of a Binary Tree root->left->right = new Node(5);

void printInorder(struct Node* node) cout << "Preorder traversal of binary tree is \n";

{ printPreorder(root);

if (node == NULL) cout << "\nInorder traversal of binary tree is \n";

return; printInorder(root);

/* first recur on left child */ cout << "\nPostorder traversal of binary tree is \n";

printInorder(node->left); printPostorder(root);

/* then print the data of node */ return 0;

cout << node->data << " "; }

pg. 8 | HIMANSHU KUMAR (LINKEDIN)


DATA STRUCTURES(BASICS) Himanshu Kumar

Java :-
// Java program for different tree traversals if (node == null)

/* Class containing left and right child of current return;

node and key value*/ /* first recur on left child */

class Node printInorder(node.left);

{ /* then print the data of node */

int key; System.out.print(node.key + " ");

Node left, right; /* now recur on right child */

public Node(int item) printInorder(node.right);

{ }

key = item; // Method to print preorder traversal

left = right = null; void printPreorder(Node node)

} {

} if (node == null)

class BinaryTree return;

{ /* first print data of node */

// Root of Binary Tree System.out.print(node.key + " ");

Node root; /* then recur on left sutree */

BinaryTree() printPreorder(node.left);

{ /* now recur on right subtree */

root = null; printPreorder(node.right);

} }

// Method to print postorder traversal. // Wrappers over above recursive functions

void printPostorder(Node node) void printPostorder() { printPostorder(root); }

{ void printInorder() { printInorder(root); }

if (node == null) void printPreorder() { printPreorder(root); }

return; // Driver method

// first recur on left subtree public static void main(String[] args)

printPostorder(node.left); {

// then recur on right subtree BinaryTree tree = new BinaryTree();

printPostorder(node.right); tree.root = new Node(1);

tree.root.left = new Node(2);

// now deal with the node tree.root.right = new Node(3);

System.out.print(node.key + " "); tree.root.left.left = new Node(4);

} tree.root.left.right = new Node(5);

// Method to print inorder traversal System.out.println("Preorder traversal of binary


tree is ");
void printInorder(Node node)
tree.printPreorder();
{

pg. 9 | HIMANSHU KUMAR (LINKEDIN)


DATA STRUCTURES(BASICS) Himanshu Kumar

System.out.println("\nInorder traversal of binary tree.printPostorder();


tree is ");
}
tree.printInorder();
}
System.out.println("\nPostorder traversal of
binary tree is ");

Output:
Preorder traversal of binary tree is

1 2 4 5 3

Inorder traversal of binary tree is

4 2 5 1 3

Postorder traversal of binary tree is

4 5 2 3 1

One more example:

pg. 10 | HIMANSHU KUMAR (LINKEDIN)


DATA STRUCTURES(BASICS) Himanshu Kumar

Level Order Traversal of a Binary Tree-


We have seen the three basic traversals(Preorder, postorder, and Inorder) of a
Binary Tree. We can also traverse a Binary Tree using the Level Order Traversal.

In the Level Order Traversal, the binary tree is traversed level-wise starting from
the first to last level sequentially.

Consider the below binary tree:

The Level Order Traversal of the above Binary Tree will be: 10 20 30 40 50 60 70
80.

Algorithm: The Level Order Traversal can be implemented efficiently using a


Queue.

1. Create an empty queue q.


2. Push the root node of tree to q. That is, q.push(root).
3. Loop while the queue is not empty:

o Pop the top node from queue and print the node.
o Enqueue node's children (first left then right children) to q
o Repeat the process until queue is not empty.

pg. 11 | HIMANSHU KUMAR (LINKEDIN)


DATA STRUCTURES(BASICS) Himanshu Kumar

Implementation:

C++ :-
// C++ program to print level order traversal {

// of a Tree // Print front of queue and remove

#include <iostream> // it from queue

#include <queue> Node *node = q.front();

using namespace std; cout << node->data << " ";

// A Binary Tree Node q.pop();

struct Node /* Enqueue left child */

{ if (node->left != NULL)

int data; q.push(node->left);

struct Node *left, *right; /* Enqueue right child */

}; if (node->right != NULL)

// Utility function to create a new tree node q.push(node->right);

Node* newNode(int data) }

{ }

Node *temp = new Node; // Driver Code

temp->data = data; int main()

temp->left = temp->right = NULL; {

return temp; // Create the following Binary Tree

} // 1

// Function to print Level Order Traversal // /\

// of the Binary Tree // 2 3

void printLevelOrder(Node *root) // / \

{ // 4 5

// Base Case Node *root = newNode(1);

if (root == NULL) return; root->left = newNode(2);

// Create an empty queue for root->right = newNode(3);

// level order tarversal root->left->left = newNode(4);

queue<Node *> q; root->left->right = newNode(5);

// Enqueue Root and initialize height cout << "Level Order traversal of binary
tree is \n";
q.push(root);
printLevelOrder(root);

return 0; }
while (q.empty() == false)

pg. 12 | HIMANSHU KUMAR (LINKEDIN)


DATA STRUCTURES(BASICS) Himanshu Kumar

java :-
// Iterative Queue based Java program to do if (tempNode.left != null) {

// level order traversal of Binary Tree queue.add(tempNode.left);

import java.util.Queue; }

import java.util.LinkedList; /* Enqueue right child */

/* Class to represent Tree node */ if (tempNode.right != null) {

class Node { queue.add(tempNode.right);

int data; }

Node left, right; }

public Node(int item) { }

data = item; // Driver Code

left = null; public static void main(String args[])

right = null; {

} // Create the following Binary Tree

} // 1

/* Class to print Level Order Traversal */ // /\

class BinaryTree { // 2 3

Node root; // /\

/* Given a binary tree. Print its nodes in // 4 5

level order using array for implementing queue */ BinaryTree tree_level = new BinaryTree();

void printLevelOrder() tree_level.root = new Node(1);

{ tree_level.root.left = new Node(2);

Queue<Node> queue = new LinkedList<Node>(); tree_level.root.right = new Node(3);

queue.add(root); tree_level.root.left.left = new Node(4);

while (!queue.isEmpty()) tree_level.root.left.right = new Node(5);

{ System.out.println("Level order traversal " + "of


binary tree is - ");
Node tempNode = queue.poll();
tree_level.printLevelOrder();
System.out.print(tempNode.data + " ");
}
/* Enqueue left child */
}

Output:

1 2 3 4 5

Time Complexity: O(N), where N is the number of nodes in the Tree.


Auxiliary Space: O(N)

pg. 13 | HIMANSHU KUMAR (LINKEDIN)


DATA STRUCTURES(BASICS) Himanshu Kumar

Insertion in a Binary Tree-


Problem: Given a Binary Tree and a Key. The task is to insert the key into the binary tree
at first position available in level order.

The idea is to do iterative level order traversal of the given tree using a queue. If we find a
node whose left child is empty, we make new key as the left child of the node. Else if we
find a node whose right child is empty, we make new key as the right child of that node.
We keep traversing the tree until we find a node whose either left or right child is empty.

Below is the implementation of this approach:

C++ :-
// C++ program to insert element in binary tree };

#include <iostream> // Function to print InOrder traversal

#include <queue> // of a Binary Tree

using namespace std; void inorder(struct Node* temp)

// A binary tree node {

struct Node { if (!temp)

int key; return;

struct Node* left, *right; inorder(temp->left);

}; cout << temp->key << " ";

// Utility function to create a new Node inorder(temp->right);

struct Node* newNode(int key) }

{ // Function to insert a new element in a Binary Tree

struct Node* temp = new Node; void insert(struct Node* temp, int key)

temp->key = key; {

temp->left = temp->right = NULL; queue<struct Node*> q;

return temp; q.push(temp);

pg. 14 | HIMANSHU KUMAR (LINKEDIN)


DATA STRUCTURES(BASICS) Himanshu Kumar

// Do level order traversal until we find // 10

// an empty place. // / \

while (!q.empty()) { // 11 9

struct Node* temp = q.front(); // / \

q.pop(); // 7 8

if (!temp->left) { struct Node* root = newNode(10);

temp->left = newNode(key); root->left = newNode(11);

break; root->left->left = newNode(7);

} else root->right = newNode(9);

q.push(temp->left); root->right->left = newNode(15);

if (!temp->right) { root->right->right = newNode(8);

temp->right = newNode(key); cout << "Inorder traversal before insertion:";

break; inorder(root);

} else int key = 12;

q.push(temp->right); insert(root, key);

} cout << endl;

} cout << "Inorder traversal after insertion:";

// Driver code inorder(root);

int main() return 0;

{ }

// Create the following Binary Tree

Java :-
// Java program to insert element in binary tree static Node root;

import java.util.LinkedList; static Node temp = root;

import java.util.Queue; // Function to perform InOrder traversal

public class GFG { // of the Binary Tree

// Binary Tree Node static void inorder(Node temp)

static class Node { {

int key; if (temp == null)

Node left, right; return;

// constructor inorder(temp.left);

Node(int key){ System.out.print(temp.key+" ");

this.key = key; inorder(temp.right);

left = null; }

right = null; // Function to insert a new element in the

} // Binary Tree

} static void insert(Node temp, int key)

pg. 15 | HIMANSHU KUMAR (LINKEDIN)


DATA STRUCTURES(BASICS) Himanshu Kumar

Queue<Node> q = new LinkedList<Node>(); // Create the following Binary Tree

q.add(temp); // 10

// Do level order traversal until we find // / \

// an empty place. // 11 9

while (!q.isEmpty()) { // / \

temp = q.peek(); // 7 8

q.remove(); root = new Node(10);

if (temp.left == null) { root.left = new Node(11);

temp.left = new Node(key); root.left.left = new Node(7);

break; root.right = new Node(9);

} else root.right.left = new Node(15);

q.add(temp.left); root.right.right = new Node(8);

if (temp.right == null) { System.out.print( "Inorder traversal before


insertion: ");
temp.right = new Node(key);
inorder(root);
break;
int key = 12;
} else
insert(root, key);
q.add(temp.right);
System.out.print("\nInorder traversal after
} insertion: ");
} inorder(root);
// Driver code }
public static void main(String args[]) }
{

Output:

Inorder traversal before insertion: 7 11 10 15 9 8


Inorder traversal after insertion: 7 11 12 10 15 9 8

Deletion in a Binary Tree-


Problem: Given a Binary Tree and a node to be deleted from this tree. The task is to
delete the given node from it.

Examples:

Delete 10 in below tree

Output :

pg. 16 | HIMANSHU KUMAR (LINKEDIN)


DATA STRUCTURES(BASICS) Himanshu Kumar

Delete 20 in below tree

Output :

While performing the delete operation on binary trees, there arise a few cases:

1. The node to be deleted is a leaf node. That is it does not have any children.
2. The node to be deleted is a internal node. That is it have left or right child.
3. The node to be deleted is the root node.

In the first case 1, since the node to be deleted is a leaf node, we can simply delete
the node without any overheads. But in the next 2 cases, we will have to take care
of the children of the node to be deleted.

In order to handle all of the cases, one way to delete a node is to:

1. Starting at the root, find the deepest and rightmost node in binary tree and
node which we want to delete.
2. Replace the deepest rightmost node’s data with the node to be deleted.
3. Then delete the deepest rightmost node.

pg. 17 | HIMANSHU KUMAR (LINKEDIN)


DATA STRUCTURES(BASICS) Himanshu Kumar

Below is the implementation of the above approach:

C++ :-
// C++ program to delete element in binary tree };

#include <bits/stdc++.h> // Function to perform Inorder Traversal

using namespace std; void inorder(struct Node* temp)

// Binary Tree Node {

struct Node if (!temp)

{ return;

int key; inorder(temp->left);

struct Node* left, *right; cout << temp->key << " ";

}; inorder(temp->right);

// Utility function to create a new }

// Binary Tree Node // Function to delete the given deepest node

struct Node* newNode(int key) // (d_node) in binary tree

{ void deletDeepest(struct Node *root, struct Node


*d_node)
struct Node* temp = new Node;
{
temp->key = key;
queue<struct Node*> q;
temp->left = temp->right = NULL;
q.push(root);
return temp;
// Do level order traversal until last node

pg. 18 | HIMANSHU KUMAR (LINKEDIN)


DATA STRUCTURES(BASICS) Himanshu Kumar

struct Node* temp; {

while(!q.empty()) temp = q.front();

{ q.pop();

temp = q.front(); if (temp->key == key)

q.pop(); key_node = temp;

if (temp->right) if (temp->left)

{ q.push(temp->left);

if (temp->right == d_node) if (temp->right)

{ q.push(temp->right);

temp->right = NULL; }

delete(d_node); int x = temp->key;

return; deletDeepest(root, temp);

} key_node->key = x;

else }

q.push(temp->right); // Driver code

} int main()

if (temp->left) {

{ // Create the following Binary Tree

if (temp->left == d_node) // 10

{ // / \

temp->left=NULL; // 11 9

delete(d_node); // / \ /\

return; // 7 12 15 8

} struct Node* root = newNode(10);

else root->left = newNode(11);

q.push(temp->left); root->left->left = newNode(7);

} root->left->right = newNode(12);

} root->right = newNode(9);

} root->right->left = newNode(15);

// Function to delete element in binary tree root->right->right = newNode(8);

void deletion(struct Node* root, int key) cout << "Inorder traversal before deletion : ";

{ inorder(root);

queue<struct Node*> q; int key = 11;

q.push(root); deletion(root, key);

struct Node *temp; cout << endl;

struct Node *key_node = NULL; cout << "Inorder traversal after deletion : ";

// Do level order traversal to find deepest inorder(root);

// node(temp) and node to be deleted (key_node) return 0;

while (!q.empty()) }

pg. 19 | HIMANSHU KUMAR (LINKEDIN)


DATA STRUCTURES(BASICS) Himanshu Kumar

Java-
// Java program to delete element in binary tree temp = q.peek();

import java.util.LinkedList; q.remove();

import java.util.Queue; if (temp.right!=null)

public class GFG { {

// Binary Tree Node if (temp.right == d_node)

static class Node { {

int key; temp.right = null;

Node left, right; d_node = null;

// constructor return;

Node(int key){ }

this.key = key; else

left = null; q.add(temp.right);

right = null; }

} if (temp.left!=null)

} {

static Node root; if (temp.left == d_node)

static Node temp = root; {

// Function to perform Inorder traversal temp.left=null;

// of a binary tree d_node = null;

static void inorder(Node temp) return;

{ }

if (temp == null) else

return; q.add(temp.left);

inorder(temp.left); }

System.out.print(temp.key+" "); }

inorder(temp.right); }

} // Function to delete element in binary tree

// Function to delete the given deepest node static void deletion(Node root, int key)

// (d_node) in binary tree {

static void deleteDeepest(Node root, Node d_node) Queue<Node> q = new LinkedList<Node>();

{ q.add(root);

Queue<Node> q = new LinkedList<Node>(); Node temp = null;

q.add(root); Node key_node = null;

// Do level order traversal until last node // Do level order traversal to find deepest

Node temp; // node(temp) and node to be deleted (key_node)

while(!q.isEmpty()) while (!q.isEmpty())

{ {

pg. 20 | HIMANSHU KUMAR (LINKEDIN)


DATA STRUCTURES(BASICS) Himanshu Kumar

temp = q.peek(); // 11 9

q.remove(); // / \ /\

if (temp.key == key) // 7 12 15 8

key_node = temp; root = new Node(10);

if (temp.left!=null) root.left = new Node(11);

q.add(temp.left); root.left.left = new Node(7);

if (temp.right!=null) root.left.right = new Node(12);

q.add(temp.right); root.right = new Node(9);

} root.right.left = new Node(15);

int x = temp.key; root.right.right = new Node(8);

deleteDeepest(root, temp); System.out.print( "Inorder traversal before


Deletion:");
key_node.key = x;
inorder(root);
}
int key = 11;
// Driver code
deletion(root, key);
public static void main(String args[])
System.out.print("\nInorder traversal after
{ Deletion:");
// Create the following Binary Tree inorder(root);
// 10 }
// / \ }

Output:

Inorder traversal before Deletion: 7 11 12 10 15 9 8


Inorder traversal after Deletion: 7 8 12 10 15 9

Finding LCA in Binary Tree-


Given a Binary Tree and the value of two nodes n1 and n2. The task is to find
the lowest common ancestor of the nodes n1 and n2 in the given Binary Tree.

The LCA or Lowest Common Ancestor of any two nodes N1 and N2 is


defined as the common ancestor of both the nodes which is closest to them.
That is the distance of the common ancestor from the nodes N1 and N2
should be least possible.

pg. 21 | HIMANSHU KUMAR (LINKEDIN)


DATA STRUCTURES(BASICS) Himanshu Kumar

Below image represents a tree and LCA of different pair of nodes (N1, N2) in it:

Finding LCA
Method 1: The simplest method of finding LCA of two nodes in a Binary Tree is to
observe that the LCA of the given nodes will be the last common node in the paths
from the root node to the given nodes.

For Example: consider the above-given tree and nodes 4 and 5.

• Path from root to node 4: [1, 2, 4]


• Path from root to node 5: [1, 2, 5].

The last common node is 2 which will be the LCA.

Algorithm:

1. Find the path from the root node to node n1 and store it in a vector or array.
2. Find the path from the root node to node n2 and store it in another vector or
array.
3. Traverse both paths untill the values in arrays are same. Return the common
element just before the mismatch.

pg. 22 | HIMANSHU KUMAR (LINKEDIN)


DATA STRUCTURES(BASICS) Himanshu Kumar

Implementation:

C++ :-
// C++ Program for Lowest Common Ancestor return true;

// in a Binary Tree // Check if k is found in left or right sub-tree

#include <iostream> if ((root->left && findPath(root->left, path, k)) ||

#include <vector> (root->right && findPath(root->right, path, k)))

using namespace std; return true;

// A Binary Tree node // If not present in subtree rooted with root,

struct Node { // remove root from path[] and return false

int key; path.pop_back();

struct Node *left, *right; return false;

}; }

// Utility function creates a new binary tree // Function to return LCA if node n1, n2 are

// node with given key // present in the given binary tree, otherwise

Node* newNode(int k) // return -1

{ int findLCA(Node* root, int n1, int n2)

Node* temp = new Node; {

temp->key = k; // to store paths to n1 and n2 from the root

temp->left = temp->right = NULL; vector<int> path1, path2;

return temp; // Find paths from root to n1 and root to n1.

} // If either n1 or n2 is not present, return -1

// Function to find the path from root node to if (!findPath(root, path1, n1) || !findPath(root, path2,
n2))
// given root of the tree, Stores the path in a
return -1;
// vector path[], returns true if path exists
// Compare the paths to get the first
// otherwise false
// different value
bool findPath(Node* root, vector<int>& path, int k)
int i;
{
for (i = 0; i < path1.size() && i < path2.size(); i++)
// base case
if (path1[i] != path2[i])
if (root == NULL)
break;
return false;
return path1[i - 1];
// Store this node in path vector.
}
// The node will be removed if
// Driver Code
// not in path from root to k
int main()
path.push_back(root->key);
{

// Let us create the Binary Tree


// See if the k is same as root's key
// as shown in the above diagram
if (root->key == k)
Node* root = newNode(1);

pg. 23 | HIMANSHU KUMAR (LINKEDIN)


DATA STRUCTURES(BASICS) Himanshu Kumar

root->left = newNode(2); cout << "LCA(4, 5) = " << findLCA(root, 4, 5);

root->right = newNode(3); cout << "\nLCA(4, 6) = " << findLCA(root, 4, 6);

root->left->left = newNode(4); cout << "\nLCA(3, 4) = " << findLCA(root, 3, 4);

root->left->right = newNode(5); cout << "\nLCA(2, 4) = " << findLCA(root, 2, 4);

root->right->left = newNode(6); return 0;

root->right->right = newNode(7); }

Java :-
// Java Program for Lowest Common Ancestor System.out.println((path2.size() > 0) ?

// in a Binary Tree "n2 is present" : "n2 is missing");

import java.util.ArrayList; return -1;

import java.util.List; }

// A Binary Tree node int i;

class Node { for (i = 0; i < path1.size() && i < path2.size(); i++) {

int data; if (!path1.get(i).equals(path2.get(i)))

Node left, right; break;

Node(int value) }

{ return path1.get(i - 1);

data = value; }

left = right = null; // Finds the path from root node to given

} // root of the tree, Stores the path in a

} // vector path[], returns true if path

public class FindLCA { // exists otherwise false

Node root; private boolean findPath(Node root, int n,

private List<Integer> path1 = new ArrayList<>(); List<Integer> path)

private List<Integer> path2 = new ArrayList<>(); {

// Finds the path from root node to given root of the // base case
tree
if (root == null) {
int findLCA(int n1, int n2)
return false;
{
}
path1.clear();
// Store this node. The node will be removed if
path2.clear();
// not in path from root to n.
return findLCAInternal(root, n1, n2);
path.add(root.data);
}
if (root.data == n) {
private int findLCAInternal(Node root, int n1, int n2)
return true;
{
}
if (!findPath(root, n1, path1) || !findPath(root, n2,
path2)) { if (root.left != null && findPath(root.left, n, path)) {

System.out.println((path1.size() > 0) ? return true;

"n1 is present" : "n1 is missing"); }

pg. 24 | HIMANSHU KUMAR (LINKEDIN)


DATA STRUCTURES(BASICS) Himanshu Kumar

if (root.right != null && findPath(root.right, n, tree.root.left = new Node(2);


path)) {
tree.root.right = new Node(3);
return true;
tree.root.left.left = new Node(4);
}
tree.root.left.right = new Node(5);
// If not present in subtree rooted with root,
tree.root.right.left = new Node(6);
// remove root from path[] and return false
tree.root.right.right = new Node(7);
path.remove(path.size() - 1);
System.out.println("LCA(4, 5): " + tree.findLCA(4,
return false; 5));

} System.out.println("LCA(4, 6): " + tree.findLCA(4,


6));

System.out.println("LCA(3, 4): " + tree.findLCA(3,


// Driver code 4));

public static void main(String[] args) System.out.println("LCA(2, 4): " + tree.findLCA(2,


4));
{
}
FindLCA tree = new FindLCA();
}
tree.root = new Node(1);

Output:
LCA(4, 5) = 2
LCA(4, 6) = 1
LCA(3, 4) = 1
LCA(2, 4) = 2

Analysis: The time complexity of the above solution is O(N) where N is the number
of nodes in the given Tree and the above solution also takes O(N) extra space.

Method 2: The method 1 finds LCA in O(N) time but requires three tree traversals
plus extra spaces for path arrays. If we assume that the keys are present in Binary
Tree, we can find LCA using single traversal of Binary Tree and without extra
storage for path arrays.

The idea is to traverse the tree starting from the root node. If any of the given keys
(n1 and n2) matches with root, then root is LCA (assuming that both keys are
present). If root doesn't match with any of the keys, we recur for left and right
subtrees. The node which has one key present in its left subtree and the other key
present in the right subtree is the LCA. If both keys lie in left subtree, then left
subtree has LCA also, otherwise, LCA lies in the right subtree.

Below is the implementation of the above approach:

pg. 25 | HIMANSHU KUMAR (LINKEDIN)


DATA STRUCTURES(BASICS) Himanshu Kumar

C++ :-
// C++ Program to find LCA of n1 and n2 using return root;

// one traversal of Binary Tree // Look for keys in left and right subtrees

Node* left_lca = findLCA(root->left, n1, n2);

#include <iostream> Node* right_lca = findLCA(root->right, n1, n2);

using namespace std; // If both of the above calls return Non-NULL,

// then one key is present in once subtree and

// A Binary Tree Node // other is present in other,

struct Node { // So this node is the LCA

struct Node *left, *right; if (left_lca && right_lca)

int key; return root;

};

// Otherwise check if left subtree or

// Utility function to create a new tree Node // right subtree is LCA

Node* newNode(int key) return (left_lca != NULL) ? left_lca : right_lca;

{ }

Node* temp = new Node;

temp->key = key; // Driver Code

temp->left = temp->right = NULL; int main()

return temp; {

} // Let us create binary tree given in the above example

Node* root = newNode(1);

// This function returns pointer to LCA of two given root->left = newNode(2);

// values n1 and n2. This function assumes that root->right = newNode(3);

// n1 and n2 are present in Binary Tree root->left->left = newNode(4);

struct Node* findLCA(struct Node* root, int n1, int n2) root->left->right = newNode(5);

{ root->right->left = newNode(6);

// Base case root->right->right = newNode(7);

if (root == NULL)

return NULL; cout << "LCA(4, 5) = " << findLCA(root, 4, 5)->key;

cout << "nLCA(4, 6) = " << findLCA(root, 4, 6)->key;

// If either n1 or n2 matches with root's key, report cout << "nLCA(3, 4) = " << findLCA(root, 3, 4)->key;

// the presence by returning root (Note that if a key is cout << "nLCA(2, 4) = " << findLCA(root, 2, 4)->key;

// ancestor of other, then the ancestor key becomes


LCA
return 0;
if (root->key == n1 || root->key == n2)
}

pg. 26 | HIMANSHU KUMAR (LINKEDIN)


DATA STRUCTURES(BASICS) Himanshu Kumar

Java :-
// Java implementation to find lowest common if (node.data == n1 || node.data == n2)
ancestor of
return node;
// n1 and n2 using one traversal of binary tree
// Look for keys in left and right subtrees
// Class containing left and right child of current
Node left_lca = findLCA(node.left, n1, n2);
// node and key value
Node right_lca = findLCA(node.right, n1, n2);
class Node {
// If both of the above calls return Non-NULL, then
int data; one key

Node left, right; // is present in once subtree and other is present


in other,
public Node(int item)
// So this node is the LCA
{
if (left_lca != null && right_lca != null)
data = item;
return node;
left = right = null;
// Otherwise check if left subtree or right subtree
} is LCA
} return (left_lca != null) ? left_lca : right_lca;
// Binary Tree Class }
public class BinaryTree { // Driver Code
// Root of the Binary Tree public static void main(String args[])
Node root; {
Node findLCA(int n1, int n2) BinaryTree tree = new BinaryTree();
{ tree.root = new Node(1);
return findLCA(root, n1, n2); tree.root.left = new Node(2);
} tree.root.right = new Node(3);

// This function returns pointer to LCA of two given tree.root.left.left = new Node(4);
// values n1 and n2. This function assumes that n1 tree.root.left.right = new Node(5);
and
tree.root.right.left = new Node(6);
// n2 are present in Binary Tree
tree.root.right.right = new Node(7);
Node findLCA(Node node, int n1, int n2)
System.out.println("LCA(4, 5) = " +
{ tree.findLCA(4, 5).data);
// Base case System.out.println("LCA(4, 6) = " +
tree.findLCA(4, 6).data);
if (node == null)
System.out.println("LCA(3, 4) = " +
return null; tree.findLCA(3, 4).data);
// If either n1 or n2 matches with root's key, report System.out.println("LCA(2, 4) = " +
tree.findLCA(2, 4).data);
// the presence by returning root (Note that if a
key is }
// ancestor of other, then the ancestor key }
becomes LCA

Output:
LCA(4, 5) = 2nLCA(4, 6) = 1nLCA(3, 4) = 1nLCA(2, 4) = 2

pg. 27 | HIMANSHU KUMAR (LINKEDIN)


DATA STRUCTURES(BASICS) Himanshu Kumar

Diameter of a Binary Tree-


The diameter of a tree (sometimes called the width) is the number of nodes on the
longest path between two end nodes. The diagram below shows two trees each
with diameter nine, the leaves that form the ends of a longest path are shaded
(note that there is more than one path in each tree of length nine, but no path
longer than nine nodes).

Solution: The diameter of a tree T is the largest of the following quantities:

• The diameter of T's left subtree.


• The diameter of T's right subtree.
• The longest path between leaves that goes through the root of T (this can be
computed from the heights of the subtrees of T).

The longest path between leaves that goes through a particular node say, nd can
be calculated as:

1 + height of left subtree of nd + height of right subtree of nd

Therefore, final Diameter of a node can be calculated as:

Diameter = maximum(lDiameter, rDiameter, 1 + lHeight + rHeight)


Where,
lDiameter = Diameter of left subtree
rDiameter = Diameter of right subtree
lHeight = Height of left subtree
rHeight = Height of right subtree

pg. 28 | HIMANSHU KUMAR (LINKEDIN)


DATA STRUCTURES(BASICS) Himanshu Kumar

Implementation:
// C++ program to calculate Diameter of a Binary Tree number f nodes along the longest path from the
root node
#include <bits/stdc++.h>
down to the farthest leaf node.*/
using namespace std;
int height(struct node* node)
// Binary Tree Node
{
struct node
/* base case tree is empty */
{
if(node == NULL)
int data;
return 0;
struct node* left, *right;
/* If tree is not empty then height = 1 + max of left
};
height and right heights */
// Function to create a new node of tree
return 1 + max(height(node->left), height(node-
// and returns pointer >right));
struct node* newNode(int data); }
// Function to Compute height of a tree /* Helper function that allocates a new node with the
int height(struct node* node); given data and NULL left and right pointers. */
// Function to get diameter of a binary tree struct node* newNode(int data)
int diameter(struct node * tree) {
{ struct node* node = (struct node*)
/* base case where tree is empty */ malloc(sizeof(struct node));
if (tree == NULL) node->data = data;

return 0; node->left = NULL;


/* get the height of left and right sub-trees */ node->right = NULL;
int lheight = height(tree->left); return(node);

int rheight = height(tree->right); }


/* get the diameter of left and right sub-trees */ // Driver Code
int ldiameter = diameter(tree->left); int main()
int rdiameter = diameter(tree->right); {
/* Return max of following three

1) Diameter of left subtree /* Constructed binary tree is


2) Diameter of right subtree 1

3) Height of left subtree + height of right subtree + 1 /\


*/
2 3
return max(lheight + rheight + 1, max(ldiameter,
rdiameter)); /\

} 4 5

/* UTILITY FUNCTIONS TO TEST diameter() FUNCTION */


*/
struct node *root = newNode(1);
/* The function Compute the "height" of a tree. Height
is the root->left = newNode(2);

pg. 29 | HIMANSHU KUMAR (LINKEDIN)


DATA STRUCTURES(BASICS) Himanshu Kumar

root->right = newNode(3); cout<<"Diameter of the given binary tree is


"<<diameter(root);
root->left->left = newNode(4);
return 0;
root->left->right = newNode(5);
}

Java :-
// Recursive optimized Java program to find the 3) Height of left subtree + height of right subtree
diameter of a + 1 */

// Binary Tree return Math.max(lheight + rheight + 1,

/* Class containing left and right child of current Math.max(ldiameter, rdiameter));

node and key value*/ }

class Node /* A wrapper over diameter(Node root) */

{ int diameter()

int data; {

Node left, right; return diameter(root);

public Node(int item) }

{ /*The function Compute the "height" of a tree.


Height is the
data = item;
number f nodes along the longest path from the
left = right = null; root node
} down to the farthest leaf node.*/
} static int height(Node node)
/* Class to print the Diameter */ {

class BinaryTree /* base case tree is empty */


{ if (node == null)
Node root; return 0;
/* Method to calculate the diameter and return it to /* If tree is not empty then height = 1 + max of left
main */
height and right heights */
int diameter(Node root)
return (1 + Math.max(height(node.left),
{ height(node.right)));
/* base case if tree is empty */ }
if (root == null) public static void main(String args[])

return 0; {
/* get the height of left and right sub trees */ /* creating a binary tree and entering the nodes */
int lheight = height(root.left); BinaryTree tree = new BinaryTree();
int rheight = height(root.right); tree.root = new Node(1);
/* get the diameter of left and right subtrees */ tree.root.left = new Node(2);
int ldiameter = diameter(root.left); tree.root.right = new Node(3);
int rdiameter = diameter(root.right); tree.root.left.left = new Node(4);
/* Return max of following three tree.root.left.right = new Node(5);
1) Diameter of left subtree System.out.println("The diameter of given binary
tree is : "
2) Diameter of right subtree

pg. 30 | HIMANSHU KUMAR (LINKEDIN)


DATA STRUCTURES(BASICS) Himanshu Kumar

+ tree.diameter()); }

Output:

Diameter of the given binary tree is 4

Time Complexity: O(N2), where N is the number of nodes in the binary tree.

Left, Right, Top and Bottom View of a Binary Tree-


Problem: Given a Binary Tree. The task is to print the nodes of the binary tree when
viewed from different sides. That is, the left view of the binary tree will contain only
those nodes which can be seen when the Binary tree is viewed from left.

Example:

Consider the Below Binary Tree:

Left View of above Tree will be: 1, 2, 4


Right View of above Tree will be: 1, 3, 7
Top View of above Tree will be: 4, 2, 1, 3, 7
Bottom View of above Tree will be: 4, 5, 6, 7

Let us now look at each of the solutions in details:

• Left View: A simple solution is to notice that the nodes appearing in the left
view of the binary tree are the first nodes at every level. So, the idea is to do
a level order traversal of the binary tree using a marker to identify levels and
print the first node at every level.

pg. 31 | HIMANSHU KUMAR (LINKEDIN)


DATA STRUCTURES(BASICS) Himanshu Kumar

Below is the complete function to print left view:

// Function to print the left view of the binary tree // If left child is present

void leftViewUtil(Node root) // push into queue

{ if (temp->left)

// Declare a queue for Level order Traversal q.push(temp->left);

queue<Node*> q; // If right child is present

if (root == NULL) // push into queue

return; if (temp->right)

// Push root q.push(temp->right);

q.push(root); // Pop the current node

// Delimiter q.pop();

q.push(NULL); temp = q.front();

while (!q.empty()) { }

Node* temp = q.front(); // Push delimiter

if (temp) { // for the next level

// Prints first node q.push(NULL);

// of each level }

print temp->data; // Pop the delimiter of

// Push children of all nodes at // the previous level

// current level q.pop();

while (q.front() != NULL) { }}

• Right View: Printing Right View of the Binary Tree is similar to the above
approach of printing the Left view of the tree. The idea is to print the last
node present at every level. So, perform a level order traversal using a
delimeter to identify levels and print the last node present at every level.

• Top View: Top view of a binary tree is the set of nodes visible when the tree
is viewed from the top. A node x is there in output if x is the topmost node at
its horizontal distance. Horizontal distance of left child of a node x is equal to
the horizontal distance of x minus 1, and that of right child is the horizontal
distance of x plus 1.

So, the idea is to do a level order traversal of the tree and calculate the
horizontal distance of every node from the root node and print those nodes

pg. 32 | HIMANSHU KUMAR (LINKEDIN)


DATA STRUCTURES(BASICS) Himanshu Kumar

which are the first nodes of a particular horizontal distance.

Hashing can be used to keep a check on whether any node with a particular
horizontal distance is encountered yet or not.

Below is the function implementing the above approach:

// Structure of binary tree print "The top view of the tree is : ";

// Binary Tree node is modified to contain while(q.size())

// an extra parameter hd, which is the {

// horizontal distance of the node from root node. hd = root->hd;

struct Node // Check if any node with this horizontal distance

{ // is encontered yet or not.

Node * left; // If not insert, current node's data to Map

Node* right; if(m.count(hd)==0)

int hd; m[hd]=root->data;

int data; // Push the left child with its

}; // horizontal distance to queue

// Function to print the topView of if(root->left)

// the binary tree {

void topview(Node* root) root->left->hd=hd-1;

{ q.push(root->left);

if(root==NULL) }

return; // Push the right child with its

queue<Node*>q; // horizontal distance to queue

map<int,int> m; if(root->right)

int hd=0; {

root->hd = hd; root->right->hd=hd+1;

// push node and horizontal distance to queue q.push(root->right);

q.push(root); }

q.pop();

pg. 33 | HIMANSHU KUMAR (LINKEDIN)


DATA STRUCTURES(BASICS) Himanshu Kumar

root=q.front(); {

} cout<<i->second<<" ";

// Print the map as it stores the nodes }

// appearing in the Top View }

for(auto i=m.begin();i!=m.end();i++)

• Bottom View: The Bottom View of a binary tree can be printed using the
similar approach as that of printing the Top View. A node x is there in output
if x is the bottom most instead of the top most node at its horizontal distance.

The process of printing the bottom view is almost the same as that of top
view with a little modification that while storing the node's data along with a
particular horizontal distance in the map, keep updating the node's data in
the map for a particular horizontal distance so that the map contains the last
node appearing with a particular horizontal distance instead of first.

Threaded Binary Tree Sample-


The Inorder traversal of a Binary tree can either be done using recursion or with the
use of an auxiliary stack. Threaded Binary Trees are used to make the inorder
traversal faster and do it without stack and without recursion. A binary tree is made
threaded by making all right child pointers that would normally be NULL point to
the inorder successor of the node (if it exists).

There are two types of threaded binary trees:

1. Single Threaded: Where a NULL right pointers is made to point to the


inorder successor (if successor exists).
2. Double Threaded: Where both left and right NULL pointers are made to
point to inorder predecessor and inorder successor respectively. The
predecessor threads are useful for reverse inorder traversal and postorder
traversal.

Note: The threads are also useful for fast accessing ancestors of a node.

Following diagram shows an example Single Threaded Binary Tree. The dotted
lines represent threads.

pg. 34 | HIMANSHU KUMAR (LINKEDIN)


DATA STRUCTURES(BASICS) Himanshu Kumar

Representation of a Threaded Node:


C++ :- Java-
struct Node class Node

{ {

int data; int data;

Node *left, *right; Node left, right;

bool rightThread; boolean rightThread;

} public Node(int item)

data = item;

left = right = null;

}}

Since the right pointer in a Threaded Binary Tree is used for two purposes, the
boolean variable rightThread is used to indicate whether the right pointer points to
a right child or an inorder successor. Similarly, we can add leftThread for a double
threaded binary tree.

Inorder Traversal in a Threaded Binary Tree: Below is the algorithm to perform


inorder traversal in a Threaded Binary Tree using threads:

1. Start from the root node, go to the leftmost node and print the node.

pg. 35 | HIMANSHU KUMAR (LINKEDIN)


DATA STRUCTURES(BASICS) Himanshu Kumar

2. Check if there is a thread towards the right for the current node.

o If Yes, then follow the thread to the node and print the data of node
linked with this thread.
o Otherwise follow the link to the right subtree, find the leftmost node
in the right subtree and print the leftmost node.

Repeat the above process until the complete tree is traversed.

Following diagram demonstrates the inorder traversal in a Threaded Binary Tree:

pg. 36 | HIMANSHU KUMAR (LINKEDIN)


DATA STRUCTURES(BASICS) Himanshu Kumar

Below functions implements the inorder traversal in a threaded binary tree:

// Utility function to find leftmost node Node *cur = leftmost(root);

// in a tree rooted with N

Node* leftMost(Node *N) // Until the complete tree is traversed

{ while (cur != NULL)

if (N == NULL) {

return NULL; print cur->data;

while (N->left != NULL) // If this node is a thread node, then go to

N = N->left; // inorder successor

if (cur->rightThread)

return N; cur = cur->right;

} // Else go to the leftmost child in

// right subtree

// Function to do inorder traversal in a else

// threaded binary tree cur = leftmost(cur->right);

void inOrder(Node *root) }

{ }

// Find leftmost node of the root node

Problems on Trees-

#1 : Print Nodes in Top View of Binary Tree


Description - Top view of a binary tree is the set of nodes visible when the tree is viewed
from the top. Given a binary tree, print the top view of it. The output nodes can be printed in
any order. Expected time complexity is O(n)

A node x is there in output if x is the topmost node at its horizontal distance. The horizontal
distance of left child of a node x is equal to a horizontal distance of x minus 1, and that of a
right child is the horizontal distance of x plus 1.

Top view of the above binary tree is


4 2 1 3 7

pg. 37 | HIMANSHU KUMAR (LINKEDIN)


DATA STRUCTURES(BASICS) Himanshu Kumar

Top view of the above binary tree is


2 1 3 6
Solution - The idea is to do something similar to vertical Order Traversal. Like vertical
Order Traversal, we need to put nodes of same horizontal distance together. We do a level
order traversal so that the topmost node at a horizontal node is visited before any other
node of same horizontal distance below it. Hashing is used to check if a node at a given
horizontal distance is seen or not.
Pseudo Code

// function should print the topView of


// the binary tree
void topview(Node* root)
{
if(root==NULL)
return;
queue < Node* > q
map < int,int > m
int hd=0
root->hd=hd

// push node and horizontal distance to queue


q.push(root);
while(!q.empty())
{
hd=root->hd
// check whether node at hd distance seen or not
if(m.find(hd)==false)
m[hd]=root->data
if(root->left)
{
root->left->hd=hd-1
q.push(root->left)
}
if(root->right)
{
root->right->hd=hd+1
q.push(root->right)

pg. 38 | HIMANSHU KUMAR (LINKEDIN)


DATA STRUCTURES(BASICS) Himanshu Kumar

}
q.pop()
root=q.front()
}
for(it=m.begin();it!=m.end();it++)
{
print(it->second)
}
}

Problem #2 : Diameter of a Binary Tree


Description - The diameter of a tree (sometimes called the width) is the number of nodes
on the longest path between two end nodes. The diagram below shows two trees each
with diameter nine, the leaves that form the ends of a longest path are shaded (note that
there is more than one path in each tree of length nine, but no path longer than nine nodes).

Solution - The diameter of a tree T is the largest of the following quantities:

1. the diameter of T’s left subtree


2. the diameter of T’s right subtree
3. the longest path between leaves that goes through the root of T (this can be
computed from the heights of the subtrees of T)

Pseudo Code
int diameter(struct node *root, int* height)
{
/* lh --> Height of left subtree
rh --> Height of right subtree */
int lh = 0, rh = 0

/* ldiameter --> diameter of left subtree


rdiameter --> Diameter of right subtree */
int ldiameter = 0, rdiameter = 0

pg. 39 | HIMANSHU KUMAR (LINKEDIN)


DATA STRUCTURES(BASICS) Himanshu Kumar

if(root == NULL)
{
*height = 0
return 0 /* diameter is also 0 */
}

/* Get the heights of left and right subtrees in lh and rh


And store the returned values in ldiameter and ldiameter */
ldiameter = diameter(root->left, &lh)
rdiameter = diameter(root->right, &rh)

/* Height of current node is max of heights of left and


right subtrees plus 1*/
*height = max(lh, rh) + 1

return max(lh + rh + 1, max(ldiameter, rdiameter))


}

Problem #3 : Convert a Binary Tree into its Mirror Tree


Description - Mirror of a Binary Tree T is another Binary Tree M(T) with left and right
children of all non-leaf nodes interchanged.Trees in the below figure are mirror of each
other.

Solution - The idea is to recursively call for left and right subtrees of a given node. On each
recursive call swap the pointers of the children nodes.
Pseudo Code

// function to convert binary tree to it's mirror


void mirror(struct Node* node)
{
if (node == NULL)
return
else
{
struct Node* temp

/* Recur for subtrees */


mirror(node->left)

pg. 40 | HIMANSHU KUMAR (LINKEDIN)


DATA STRUCTURES(BASICS) Himanshu Kumar

mirror(node->right)

/* swap the pointers in this node */


temp = node->left
node->left = node->right
node->right = temp
}
}

Problem #4 : Convert a given Binary Tree to Doubly


Linked List
Description - Given a Binary Tree (BT), convert it to a Doubly Linked List(DLL) In-Place.
The left and right pointers in nodes are to be used as previous and next pointers
respectively in converted DLL. The order of nodes in DLL must be same as Inorder of the
given Binary Tree. The first node of Inorder traversal (left most node in BT) must be head
node of the DLL.

Solution - The idea is to


do inorder traversal of the binary tree. While doing inorder traversal, keep track of the
previously visited node in a variable say prev. For every visited node, make it next of prev
and previous of this node as prev.
Pseudo Code

// A simple recursive function to convert a given Binary tree to Doubly


// Linked List
// root --> Root of Binary Tree
// head --> Pointer to head node of created doubly linked list
void BinaryTree2DoubleLinkedList(node *root, node **head)
{
// Base case
if (root == NULL)
return

// Initialize previously visited node as NULL. This is


// static so that the same value is accessible in all recursive
// calls

pg. 41 | HIMANSHU KUMAR (LINKEDIN)


DATA STRUCTURES(BASICS) Himanshu Kumar

static node* prev = NULL

// Recursively convert left subtree


BinaryTree2DoubleLinkedList(root->left, head)

// Now convert this node


if (prev == NULL)
*head = root
else
{
root->left = prev
prev->right = root
}
prev = root

// Finally convert right subtree


BinaryTree2DoubleLinkedList(root->right, head)
}

HIMANSHU KUMAR(LINKEDIN)

https://www.linkedin.com/in/himanshukumarmahuri

CREDITS- INTERNET

DISCLOSURE- ALL THE DATA AND IMAGES ARE TAKEN FROM GOOGLE AND INTERNET.

pg. 42 | HIMANSHU KUMAR (LINKEDIN)

You might also like