Tree
Tree
Tree
The content of this book comes from geeksforgeeks.org and it's licensed under Creative
Commons Attribution-NonCommercial-NoDerivs 2.5 India
Made by Jing. 2015.
Updated on September 30, 2015
Head over to this github repo to report issues or contribute.
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.
Example Tree
Depth First Traversals:
(a) Inorder
(b) Preorder
(c) Postorder
Breadth First or Level Order Traversal
Please see thispost for Breadth First Traversal.
Inorder Traversal:
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)
Uses of Inorder
In case of binary search trees (BST), Inorder traversal gives nodes in non-decreasing order.
To get nodes of BST in non-increasing order, a variation of Inorder traversal where Inorder
itraversal s reversed, can be used.
Example: Inorder traversal for the above given figure is 4 2 5 1 3.
Preorder Traversal:
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)
Uses of Preorder
Preorder traversal is used to create a copy of the tree. Preorder traversal is also used to get
prefix expression on of an expression tree. Please see
http://en.wikipedia.org/wiki/Polish_notation to know why prefix expressions are useful.
Example: Preorder traversal for the above given figure is 1 2 4 5 3.
Postorder Traversal:
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.
Uses of Postorder
Postorder traversal is used to delete the tree. Please see the question for deletion of tree
for details. Postorder traversal is also useful to get the postfix expression of an expression
tree. Please see http://en.wikipedia.org/wiki/Reverse_Polish_notation to for the usage of
postfix expression.
Example: Postorder traversal for the above given figure is 4 5 2 3 1.
#include <stdio.h>
#include <stdlib.h>
return(node);
}
getchar();
return 0;
}
.
T(n) = (n-1)T(0) + T(1) + (n-1)c
T(n) = nT(0) + (n)c
Value of T(0) will be some constant say d. (traversing a empty tree will take some constants
time)
T(n) = n(c+d)
T(n) = (-)(n) (Theta of n)
Case 2: Both left and right subtrees have equal number of nodes.
T(n) = 2T(|_n/2_|) + c
This recursive function is in the standard form (T(n) = aT(n/b) + (-)(n) ) for master method
http://en.wikipedia.org/wiki/Master_theorem. If we solve it by master method we get (-
)(n)
Auxiliary Space : If we dont consider size of stack for function calls then O(1) otherwise
O(n).
Source
http://www.geeksforgeeks.org/618/
size(tree)
1. If tree is empty then return 0
2. Else
(a) Get the size of left subtree recursively i.e., call
size( tree->left-subtree)
(a) Get the size of right subtree recursively i.e., call
size( tree->right-subtree)
(c) Calculate size of the tree as following:
tree_size = size(left-subtree) + size(right-
subtree) + 1
(d) Return tree_size
#include <stdio.h>
#include <stdlib.h>
return(node);
}
Time & Space Complexities: Since this program is similar to traversal of tree, time and
space complexities will be same as Tree traversal (Please see our Tree Traversal post for
details)
Source
http://www.geeksforgeeks.org/write-a-c-program-to-calculate-size-of-a-tree/
Category: Trees Tags: Size of a Tree, Tree Size, TreeSize
Write C Code to Determine if Two Trees are Identical
Two trees are identical when they have same data and arrangement of data is also same.
To identify if two trees are identical, we need to traverse both trees simultaneously, and
while traversing we need to compare data and children of the trees.
Algorithm:
sameTree(tree1, tree2)
1. If both trees are empty then return 1.
2. Else If both trees are non -empty
(a) Check data of the root nodes (tree1->data == tree2->data)
(b) Check left subtrees recursively i.e., call sameTree(
tree1->left_subtree, tree2->left_subtree)
(c) Check right subtrees recursively i.e., call sameTree(
tree1->right_subtree, tree2->right_subtree)
(d) If a,b and c are true then return 1.
3 Else return 0 (one is empty and other is not)
#include <stdio.h>
#include <stdlib.h>
return(node);
}
root2->left = newNode(2);
root2->right = newNode(3);
root2->left->left = newNode(4);
root2->left->right = newNode(5);
if(identicalTrees(root1, root2))
printf("Both tree are identical.");
else
printf("Trees are not identical.");
getchar();
return 0;
}
Time Complexity:
Complexity of the identicalTree() will be according to the tree with lesser number of
nodes. Let number of nodes in two trees be m and n then complexity of sameTree() is O(m)
where m
Source
http://www.geeksforgeeks.org/write-c-code-to-determine-if-two-trees-are-identical/
Category: Trees Tags: Tree Traveral, Trees
Example Tree
Recursively calculate height of left and right subtrees of a node and assign height to the
node as max of the heights of two children plus 1. See below pseudo code and program for
details.
Algorithm:
maxDepth()
1. If tree is empty then return 0
2. Else
(a) Get the max depth of left subtree recursively i.e.,
call maxDepth( tree->left-subtree)
(a) Get the max depth of right subtree recursively i.e.,
call maxDepth( tree->right-subtree)
(c) Get the max of max depths of left and right
subtrees and add 1 to it for the current node.
max_depth = max(max dept of left subtree,
max depth of right subtree)
+ 1
(d) Return max_depth
See the below diagram for more clarity about execution of the recursive function
maxDepth() for above example tree.
Implementation:
#include<stdio.h>
#include<stdlib.h>
return(node);
}
int main()
{
struct node *root = newNode(1);
root->left = newNode(2);
root->right = newNode(3);
root->left->left = newNode(4);
root->left->right = newNode(5);
getchar();
return 0;
}
Time Complexity: O(n) (Please see our post Tree Traversalfor details)
References:
http://cslibrary.stanford.edu/110/BinaryTrees.html
Source
http://www.geeksforgeeks.org/write-a-c-program-to-find-the-maximum-depth-or-height-
of-a-tree/
Category: Trees Tags: Height of a Tree, Tree Traveral, Trees
Example Tree
Program
#include<stdio.h>
#include<stdlib.h>
node->data = data;
node->left = NULL;
node->right = NULL;
return(node);
}
deleteTree(root);
root = NULL;
getchar();
return 0;
}
The above deleteTree() function deletes the tree, but doesnt change root to NULL which
may cause problems if the user of deleteTree() doesnt change root to NULL and tires to
access values using root pointer. We can modify the deleteTree() function to take reference
to the root node so that this problem doesnt occur. See the following code.
#include<stdio.h>
#include<stdlib.h>
node->data = data;
node->left = NULL;
node->right = NULL;
return(node);
}
getchar();
return 0;
}
Source
http://www.geeksforgeeks.org/write-a-c-program-to-delete-a-tree/
Category: Trees Tags: Delete Tree, Tree Traveral, Trees
Algorithm Mirror(tree):
Program:
#include<stdio.h>
#include<stdlib.h>
{
struct node* node = (struct node*)
malloc(sizeof(struct node));
node->data = data;
node->left = NULL;
node->right = NULL;
return(node);
}
So the tree...
4
/ \
2 5
/ \
1 3
is changed to...
4
/ \
5 2
/ \
3 1
*/
void mirror(struct node* node)
{
if (node==NULL)
return;
else
{
struct node* temp;
/* do the subtrees */
mirror(node->left);
mirror(node->right);
inOrder(node->left);
printf("%d ", node->data);
inOrder(node->right);
}
getchar();
return 0;
}
Time & Space Complexities: This program is similar to traversal of tree space and time
complexities will be same as Tree traversal (Please see our Tree Traversal post for details)
Source
http://www.geeksforgeeks.org/write-an-efficient-c-function-to-convert-a-tree-into-its-
mirror-tree/
Category: Trees Tags: Convert to Mirror, Get the Mirror, Mirror Tree, Tree Traveral, Trees
If you are given two traversal sequences, can you construct the binary
tree?
It depends on what traversals are given. If one of the traversal methods is Inorder then the
tree can be constructed, otherwise not.
Source
http://www.geeksforgeeks.org/if-you-are-given-two-traversal-sequences-can-you-
construct-the-binary-tree/
Category: Trees Tags: Binary Tree, Tree Traveral
Given a binary tree, print out all of its root-to-leaf paths one per line.
Asked by Varun Bhatia
Here is the solution.
Algorithm:
Example:
Example Tree
Output for the above example will be
1 2 4
1 2 5
1 3
Implementation:
return(node);
}
getchar();
return 0;
}
References:
http://cslibrary.stanford.edu/110/BinaryTrees.html
Source
http://www.geeksforgeeks.org/given-a-binary-tree-print-out-all-of-its-root-to-leaf-paths-
one-per-line/
Category: Trees
Post navigation
Write a program to add two numbers in base 14 Lowest Common Ancestor in a Binary
Search Tree.
Writing code in comment? Please use code.geeksforgeeks.org, generate link and share the
link here.
LCA of 10 and 14 is 12
LCA of 14 and 8 is 8
LCA of 10 and 22 is 20
Time complexity of above solution is O(h) where h is height of tree. Also, the above solution
requires O(h) extra space in function call stack for recursive function calls. We can avoid
extra space using iterative solution.
/* Function to find LCA of n1 and n2. The function assumes that both
n1 and n2 are present in BST */
struct node *lca(struct node* root, int n1, int n2)
{
while (root != NULL)
{
// If both n1 and n2 are smaller than root, then LCA lies in left
if (root->data > n1 && root->data > n2)
root = root->left;
// If both n1 and n2 are greater than root, then LCA lies in right
else if (root->data < n1 && root->data < n2)
root = root->right;
else break;
}
return root;
}
Source
http://www.geeksforgeeks.org/lowest-common-ancestor-in-a-binary-search-tree/
Source
http://www.geeksforgeeks.org/the-great-tree-list-recursion-problem/
Category: Linked Lists Trees
For the above tree, we start with 20, then we move left 8, we keep on moving to left until
we see NULL. Since left of 4 is NULL, 4 is the node with minimum value.
#include <stdio.h>
#include<stdlib.h>
/* A binary tree node has data, pointer to left child
and a pointer to right child */
struct node
{
int data;
struct node* left;
struct node* right;
};
return(node);
}
Time Complexity: O(n) Worst case happens for left skewed trees.
Similarly we can get the maximum value by recursively traversing the right node of a
binary search tree.
References:
http://cslibrary.stanford.edu/110/BinaryTrees.html
Source
http://www.geeksforgeeks.org/find-the-minimum-element-in-a-binary-search-tree/
Category: Trees
Level Order Tree Traversal
Level order traversal of a tree is breadth first traversal for the tree.
Example Tree
Level order traversal of the above tree is 1 2 3 4 5
METHOD 1 (Use function to print a given level)
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.
/*Function to print level order traversal of tree*/
printLevelorder(tree)
for d = 1 to height(tree)
printGivenLevel(tree, d);
Implementation:
#include <stdio.h>
#include <stdlib.h>
/*Function protoypes*/
void printGivenLevel(struct node* root, int level);
int height(struct node* node);
struct node* newNode(int data);
return(node);
}
getchar();
return 0;
}
Time Complexity: O(n^2) in worst case. For a skewed tree, printGivenLevel() takes O(n)
time where n is the number of nodes in the skewed tree. So time complexity of
printLevelOrder() is O(n) + O(n-1) + O(n-2) + .. + O(1) which is O(n^2).
Implementation:
Here is a simple implementation of the above algorithm. Queue is implemented using an
array with maximum size of 500. We can implement queue as linked list also.
#include <stdio.h>
#include <stdlib.h>
#define MAX_Q_SIZE 500
/* frunction prototypes */
struct node** createQueue(int *, int *);
void enQueue(struct node **, int *, struct node *);
struct node *deQueue(struct node **, int *);
while(temp_node)
{
printf("%d ", temp_node->data);
/*UTILITY FUNCTIONS*/
struct node** createQueue(int *front, int *rear)
{
struct node **queue =
(struct node **)malloc(sizeof(struct node*)*MAX_Q_SIZE);
*front = *rear = 0;
return queue;
}
return(node);
}
getchar();
return 0;
}
Source
http://www.geeksforgeeks.org/level-order-tree-traversal/
Category: Trees
Post navigation
Compute the minimum or maximum of two integers without branching Program to
count leaf nodes in a binary tree
Writing code in comment? Please use code.geeksforgeeks.org, generate link and share the
link here.
getLeafCount(node)
1) If node is NULL then return 0.
2) Else If left and right child nodes are NULL return 1.
3) Else recursively calculate leaf count of the tree using below formula.
Leaf count of a tree = Leaf count of left subtree +
Leaf count of right subtree
Example Tree
Leaf count for the above tree is 3.
Implementation:
#include <stdio.h>
#include <stdlib.h>
return(node);
}
getchar();
return 0;
}
Time & Space Complexities: Since this program is similar to traversal of tree, time and
space complexities will be same as Tree traversal (Please see our Tree Traversal post for
details)
Please write comments if you find any bug in the above programs/algorithms or other
ways to solve the same problem.
Source
http://www.geeksforgeeks.org/write-a-c-program-to-get-count-of-leaf-nodes-in-a-binary-
tree/
Category: Trees
A program to check if a binary tree is BST or not
A binary search tree (BST) is a node based binary tree data structure which has the
following properties.
The left subtree of a node contains only nodes with keys less than the nodes key.
The right subtree of a node contains only nodes with keys greater than the nodes key.
Both the left and right subtrees must also be binary search trees.
From the above properties it naturally follows that:
Each node (item in the tree) has a distinct key.
This approach is wrong as this will return true for below binary tree (and below tree
is not a BST because 4 is in left subtree of 3)
It is assumed that you have helper functions minValue() and maxValue() that return the
min or max int value from a non-empty tree
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
return(node);
}
if(isBST(root))
printf("Is BST");
else
printf("Not a BST");
getchar();
return 0;
}
// traverse the tree in inorder fashion and keep track of prev node
if (root)
{
if (!isBST(root->left))
return false;
prev = root;
return isBST(root->right);
}
return true;
}
The use of static variable can also be avoided by using reference to prev node as a
parameter (Similar to thispost).
Sources:
http://en.wikipedia.org/wiki/Binary_search_tree
http://cslibrary.stanford.edu/110/BinaryTrees.html
Please write comments if you find any bug in the above programs/algorithms or other
ways to solve the same problem.
Source
http://www.geeksforgeeks.org/a-program-to-check-if-a-binary-tree-is-bst-or-not/
Method 1 (Recursive)
This problem can bee seen as an extension of the level order traversal post.
To print the nodes in spiral order, nodes at different levels should be printed in alternating
order. An additional Boolean variable ltr is used to change printing order of levels. If ltr is 1
then printGivenLevel() prints nodes from left to right else from right to left. Value of ltr is
flipped in each iteration to change the order.
Function to print level order traversal of tree
printSpiral(tree)
bool ltr = 0;
for d = 1 to height(tree)
printGivenLevel(tree, d, ltr);
ltr ~= ltr /*flip ltr*/
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
/* Function protoypes */
void printGivenLevel(struct node* root, int level, int ltr);
int height(struct node* node);
struct node* newNode(int data);
return 0;
}
Output:
Spiral Order traversal of binary tree is
1 2 3 4 5 6 7
Time Complexity: Worst case time complexity of the above method is O(n^2). Worst case
occurs in case of skewed trees.
Method 2 (Iterative)
We can print spiral order traversal in O(n) time and O(n) extra space. The idea is to use
two stacks. We can use one stack for printing from left to right and other stack for printing
from right to left. In every iteration, we have nodes of one level in one of the stacks. We
print the nodes, and push nodes of next level in other stack.
return(node);
}
int main()
{
struct node *root = newNode(1);
root->left = newNode(2);
root->right = newNode(3);
root->left->left = newNode(7);
root->left->right = newNode(6);
root->right->left = newNode(5);
root->right->right = newNode(4);
cout << "Spiral Order traversal of binary tree is \n";
printSpiral(root);
return 0;
}
Output:
Spiral Order traversal of binary tree is
1 2 3 4 5 6 7
Please write comments if you find any bug in the above program/algorithm; or if you want
to share more information about spiral traversal.
Source
http://www.geeksforgeeks.org/level-order-traversal-in-spiral-form/
Category: Trees
Post navigation
Babylonian method for square root Data Structures and Algorithms | Set 7
Writing code in comment? Please use code.geeksforgeeks.org, generate link and share the
link here.
Check for Children Sum Property in a Binary Tree.
Given a binary tree, write a function that returns true if the tree satisfies below property.
For every node, data value must be equal to sum of data values in left and right children.
Consider data value as 0 for NULL children. Below tree is an example
Algorithm:
Traverse the given binary tree. For each node check (recursively) if the node and both its
children satisfy the Children Sum Property, if so then return true else return false.
Implementation:
/* A binary tree node has data, left child and right child */
struct node
{
int data;
struct node* left;
struct node* right;
};
/*
Helper function that allocates a new node
with the given data and NULL left and right
pointers.
*/
struct node* newNode(int data)
{
struct node* node =
(struct node*)malloc(sizeof(struct node));
node->data = data;
node->left = NULL;
node->right = NULL;
return(node);
}
getchar();
return 0;
}
Source
http://www.geeksforgeeks.org/check-for-children-sum-property-in-a-binary-tree/
Category: Trees
50
/ \
/ \
7 2
/ \ /\
/ \ / \
3 5 1 30
Algorithm:
Traverse given tree in post order to convert it, i.e., first change left and right children to
hold the children sum property then change the parent node.
Let difference between nodes data and children sum be diff.
50
/ \
/ \
8 31
/ \ / \
/ \ / \
3 5 1 30
Now convert the root, we have to increment left subtree for converting the root.
50
/ \
/ \
19 31
/ \ / \
/ \ / \
14 5 1 30
Please note the last step we have incremented 8 to 19, and to fix the subtree we have
incremented 3 to 14.
Implementation:
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
struct node* left;
struct node* right;
};
convertTree(root);
getchar();
return 0;
}
Time Complexity: O(n^2), Worst case complexity is for a skewed tree such that nodes are
in decreasing order from root to leaf.
Please write comments if you find any bug in the above algorithm or a better way to solve
the same problem.
Source
http://www.geeksforgeeks.org/convert-an-arbitrary-binary-tree-to-a-tree-that-holds-
children-sum-property/
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 leaves in the tree. 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).
#include <stdio.h>
#include <stdlib.h>
getchar();
return 0;
}
int height = 0;
struct node *root = SomeFunctionToMakeTree();
int diameter = diameterOpt(root, &height); */
int diameterOpt(struct node *root, int* height)
{
/* lh --> Height of left subtree
rh --> Height of right subtree */
int lh = 0, rh = 0;
if(root == NULL)
{
*height = 0;
return 0; /* diameter is also 0 */
}
Source
http://www.geeksforgeeks.org/diameter-of-a-binary-tree/
Category: Trees
To check if a tree is height-balanced, get the height of left and right subtrees. Return true if
difference between heights is not more than 1 and left and right subtrees are balanced,
otherwise return false.
return(node);
}
int main()
{
struct node *root = newNode(1);
root->left = newNode(2);
root->right = newNode(3);
root->left->left = newNode(4);
root->left->right = newNode(5);
root->left->left->left = newNode(8);
if(isBalanced(root))
printf("Tree is balanced");
else
printf("Tree is not balanced");
getchar();
return 0;
}
if(root == NULL)
{
*height = 0;
return 1;
}
return(node);
}
int main()
{
int height = 0;
if(isBalanced(root, &height))
printf("Tree is balanced");
else
printf("Tree is not balanced");
getchar();
return 0;
}
Source
http://www.geeksforgeeks.org/how-to-determine-if-a-binary-tree-is-balanced/
Category: Trees
Inorder Tree Traversal without Recursion
Using Stackis the obvious way to traverse tree without recursion. Below is an algorithm for
traversing binary tree using stack. See this for step wise step execution of the algorithm.
1
/ \
2 3
/ \
4 5
Step 3 Pushes the current node and set current = current->left until current
is NULL
current -> 1
push 1: Stack S -> 1
current -> 2
push 2: Stack S -> 2, 1
current -> 4
push 4: Stack S -> 4, 2, 1
current = NULL
Implementation:
#include<stdio.h>
#include<stdlib.h>
#define bool int
while (!done)
{
/* Reach the left most tNode of the current tNode */
if(current != NULL)
{
/* place pointer to a tree node on the stack before traversing
the node's left subtree */
push(&s, current);
current = current->left;
}
if(new_tNode == NULL)
{
printf("Stack Overflow \n");
getchar();
exit(0);
}
return(tNode);
}
inOrder(root);
getchar();
return 0;
}
http://neural.cs.nthu.edu.tw/jang/courses/cs2351/slide/animation/Iterative%20Inorder
%20Traversal.pps
See this post for another approach of Inorder Tree Traversal without recursion and
without stack!
Please write comments if you find any bug in above code/algorithm, or want to share more
information about stack based Inorder Tree Traversal.
Source
http://www.geeksforgeeks.org/inorder-tree-traversal-without-recursion/
Category: Trees Tags: Tree Traveral
Although the tree is modified through the traversal, it is reverted back to its original shape
after the completion. Unlike Stack based traversal, no extra space is required for this
traversal.
#include<stdio.h>
#include<stdlib.h>
if(root == NULL)
return;
current = root;
while(current != NULL)
{
if(current->left == NULL)
{
printf(" %d ", current->data);
current = current->right;
}
else
{
/* Find the inorder predecessor of current */
pre = current->left;
while(pre->right != NULL && pre->right != current)
pre = pre->right;
/* UTILITY FUNCTIONS */
/* Helper function that allocates a new tNode with the
given data and NULL left and right pointers. */
struct tNode* newtNode(int data)
{
struct tNode* tNode = (struct tNode*)
malloc(sizeof(struct tNode));
tNode->data = data;
tNode->left = NULL;
tNode->right = NULL;
return(tNode);
}
MorrisTraversal(root);
getchar();
return 0;
}
References:
www.liacs.nl/~deutz/DS/september28.pdf
http://comsci.liu.edu/~murali/algo/Morris.htm
www.scss.tcd.ie/disciplines/software_systems//HughGibbonsSlides.pdf
Please write comments if you find any bug in above code/algorithm, or want to share more
information about stack Morris Inorder Tree Traversal.
Source
http://www.geeksforgeeks.org/inorder-tree-traversal-without-recursion-and-without-
stack/
Category: Trees Tags: Tree Traveral
For example, in the above tree root to leaf paths exist with following sums.
21 > 10 8 3
23 > 10 8 5
14 > 10 2 2
So the returned value should be true only for numbers 21, 23 and 14. For any other
number, returned value should be false.
Algorithm:
Recursively check if left or right child has path sum equal to ( number value at current
node)
Implementation:
#include<stdio.h>
#include<stdlib.h>
#define bool int
/*
Given a tree and a sum, return true if there is a path from the root
down to a leaf, such that adding up all the values along the path
equals the given sum.
Strategy: subtract the node value from the sum when recurring down,
and check to see if the sum is 0 when you run out of tree.
*/
bool hasPathSum(struct node* node, int sum)
{
/* return true if we run out of tree and sum==0 */
if (node == NULL)
{
return (sum == 0);
}
else
{
bool ans = 0;
if(node->left)
ans = ans || hasPathSum(node->left, subSum);
if(node->right)
ans = ans || hasPathSum(node->right, subSum);
return ans;
}
}
/* UTILITY FUNCTIONS */
/* Helper function that allocates a new node with the
given data and NULL left and right pointers. */
struct node* newnode(int data)
{
struct node* node = (struct node*)
malloc(sizeof(struct node));
node->data = data;
node->left = NULL;
node->right = NULL;
return(node);
}
if(hasPathSum(root, sum))
printf("There is a root-to-leaf path with sum %d", sum);
else
printf("There is no root-to-leaf path with sum %d", sum);
getchar();
return 0;
}
Please write comments if you find any bug in above code/algorithm, or find other ways to
solve the same problem
Source
http://www.geeksforgeeks.org/root-to-leaf-path-sum-equal-to-a-given-number/
Category: Trees
A
/ \
/ \
D B E F C
A
/ \
/ \
B C
/ \ /
/ \ /
D E F
Algorithm: buildTree()
1) Pick an element from Preorder. Increment a Preorder Index Variable (preIndex in below
code) to pick next element in next recursive call.
2) Create a new tree node tNode with the data as picked element.
3) Find the picked elements index in Inorder. Let the index be inIndex.
4) Call buildTree for elements before inIndex and make the built tree as left subtree of
tNode.
5) Call buildTree for elements after inIndex and make the built tree as right subtree of
tNode.
6) return tNode.
Thanks to Rohini and Tushar for suggesting the code.
return tNode;
}
/* UTILITY FUNCTIONS */
/* Function to find index of value in arr[start...end]
The function assumes that value is present in in[] */
int search(char arr[], int strt, int end, char value)
{
int i;
for(i = strt; i <= end; i++)
{
if(arr[i] == value)
return i;
}
}
return(node);
}
Time Complexity: O(n^2). Worst case occurs when tree is left skewed. Example Preorder
and Inorder traversals for worst case are {A, B, C, D} and {D, C, B, A}.
Please write comments if you find any bug in above codes/algorithms, or find other ways to
solve the same problem.
Source
http://www.geeksforgeeks.org/construct-tree-from-given-inorder-and-preorder-
traversal/
Category: Trees Tags: Inorder Traversal, Preorder Traversal, Tree Traveral
Post navigation
Do not use sizeof for array parameters Given a binary tree, print all root-to-leaf paths
Writing code in comment? Please use code.geeksforgeeks.org, generate link and share the
link here.
#include<stdio.h>
#include<stdlib.h>
/* UTILITY FUNCTIONS */
/* Utility that prints out an array on a line. */
void printArray(int ints[], int len)
{
int i;
for (i=0; i<len; i++)
{
printf("%d ", ints[i]);
}
printf("\n");
}
return(node);
}
getchar();
return 0;
}
Source
http://www.geeksforgeeks.org/given-a-binary-tree-print-all-root-to-leaf-paths/
Category: Trees
Double Tree
Write a program that converts a given tree to its Double tree. To create Double tree of the
given tree, create a new duplicate for each node, and insert the duplicate as the left child of
the original node.
So the tree
2
/ \
1 3
is changed to
2
/ \
2 3
/ /
1 3
/
1
is changed to
1
/ \
1 3
/ /
2 3
/ \
2 5
/ /
4 5
/
4
Algorithm:
Recursively convert the tree to double tree in postorder fashion. For each node, first
convert the left subtree of the node, then right subtree, finally create a duplicate node of the
node and fix the left child of the node and left child of left child.
Implementation:
#include <stdio.h>
#include <stdlib.h>
if (node==NULL) return;
/* do the subtrees */
doubleTree(node->left);
doubleTree(node->right);
return(node);
}
doubleTree(root);
getchar();
return 0;
}
Source
http://www.geeksforgeeks.org/double-tree/
Category: Trees
1
/ \
2 3
/ \ \
4 5 8
/ \
6 7
#include <stdio.h>
#include <stdlib.h>
/*Function protoypes*/
int getWidth(struct node* root, int level);
int height(struct node* node);
struct node* newNode(int data);
return maxWidth;
}
if(root == NULL)
return 0;
if(level == 1)
return 1;
/* UTILITY FUNCTIONS */
/* Compute the "height" of a tree -- the number of
nodes along the longest path from the root node
down to the farthest leaf node.*/
int height(struct node* node)
{
if (node==NULL)
return 0;
else
{
/* compute the height of each subtree */
int lHeight = height(node->left);
int rHeight = height(node->right);
/* use the larger one */
/*
Constructed bunary tree is:
1
/ \
2 3
/ \ \
4 5 8
/ \
6 7
*/
printf("Maximum width is %d \n", getMaxWidth(root));
getchar();
return 0;
}
#include <stdio.h>
#include <stdlib.h>
int level = 0;
/* UTILITY FUNCTIONS */
/* Compute the "height" of a tree -- the number of
nodes along the longest path from the root node
down to the farthest leaf node.*/
int height(struct node* node)
{
if (node==NULL)
return 0;
else
{
/* compute the height of each subtree */
int lHeight = height(node->left);
int rHeight = height(node->right);
/* use the larger one */
/*
Constructed bunary tree is:
1
/ \
2 3
/ \ \
4 5 8
/ \
6 7
*/
printf("Maximum width is %d \n", getMaxWidth(root));
getchar();
return 0;
}
Source
http://www.geeksforgeeks.org/maximum-width-of-a-binary-tree/
Category: Trees
Post navigation
Run Length Encoding Intersection of two Sorted Linked Lists
Writing code in comment? Please use code.geeksforgeeks.org, generate link and share the
link here.
Source
http://www.geeksforgeeks.org/g-fact-18/
Category: Trees Tags: GFacts
(a)
10
/ \
7 15
\ /
9 11
(b)
10
/ \
7 15
/ \
9 11
(c)
10
/ \
7 15
/ /
5 11
(d)
10
/ \
7 15
/ \ /
9 10 12
Method 1 (Change Left subtree to its Mirror and compare it with Right subtree)
Algorithm: isFoldable(root)
1) If tree is empty, then return true.
2) Convert the left subtree to its mirror image
mirror(root->left); /* See this post */
3) Check if the structure of left subtree and right subtree is same
and store the result.
res = isStructSame(root->left, root->right); /*isStructSame()
recursively compares structures of two subtrees and returns
true if structures are same */
4) Revert the changes made in step (2) to get the original tree.
mirror(root->left);
5) Return result res stored in step 2.
#include<stdio.h>
#include<stdlib.h>
/* base case */
if(root == NULL)
return true;
return false;
}
/* UTILITY FUNCTIONS */
/* Change a tree so that the roles of the left and
right pointers are swapped at every node.
See http://geeksforgeeks.org/?p=662 for details */
void mirror(struct node* node)
{
if (node==NULL)
return;
else
{
struct node* temp;
/* do the subtrees */
mirror(node->left);
mirror(node->right);
return(node);
}
if(isFoldable(root) == 1)
{ printf("\n tree is foldable"); }
else
{ printf("\n tree is not foldable"); }
getchar();
return 0;
}
IsFoldable(root)
1) If tree is empty then return true
2) Else check if left and right subtrees are structure wise mirrors of
each other. Use utility function IsFoldableUtil(root->left,
root->right) for this.
#include<stdio.h>
#include<stdlib.h>
/*UTILITY FUNCTIONS */
/* Helper function that allocates a new node with the
given data and NULL left and right pointers. */
struct node* newNode(int data)
{
struct node* node = (struct node*)
malloc(sizeof(struct node));
node->data = data;
node->left = NULL;
node->right = NULL;
return(node);
}
if(IsFoldable(root) == true)
{ printf("\n tree is foldable"); }
else
{ printf("\n tree is not foldable"); }
getchar();
return 0;
}
Source
http://www.geeksforgeeks.org/foldable-binary-trees/
Category: Trees
1
/ \
2 3
/ \ /
4 5 8
The problem can be solved using recursion. Thanks to eldho for suggesting the solution.
#include <stdio.h>
#include <stdlib.h>
return(node);
}
printKDistant(root, 2);
getchar();
return 0;
}
The above program prints 4, 5 and 8.
Time Complexity: O(n) where n is number of nodes in the given binary tree.
Please write comments if you find the above code/algorithm incorrect, or find better ways
to solve the same problem.
Source
http://www.geeksforgeeks.org/print-nodes-at-k-distance-from-root/
Category: Trees
Solution:
Inorder traversal of BST prints it in ascending order. The only trick is to modify recursion
termination condition in standard Inorder Tree Traversal.
Implementation:
#include<stdio.h>
// print root
printf("%d ", arr[start]);
int main()
{
int arr[] = {4, 2, 5, 1, 3};
int arr_size = sizeof(arr)/sizeof(int);
printSorted(arr, 0, arr_size-1);
getchar();
return 0;
}
Source
http://www.geeksforgeeks.org/sorted-order-printing-of-an-array-that-represents-a-bst/
Category: Trees
5. Router algorithms
References:
http://www.cs.bu.edu/teaching/c/tree/binary/
http://en.wikipedia.org/wiki/Tree_%28data_structure%29#Common_uses
Please write comments if you find anything incorrect, or you want to share
more information about the topic discussed above.
Source
http://www.geeksforgeeks.org/applications-of-tree-data-structure/
Category: Trees
#include <stdio.h>
#include <stdlib.h>
/* Helper function that allocates a new node with the given data and
NULL left and right pointers. */
struct node* newNode(int data)
{
struct node* node = (struct node*)
malloc(sizeof(struct node));
node->data = data;
node->left = NULL;
node->right = NULL;
node->parent = NULL;
return(node);
}
/* Give a binary search tree and a number, inserts a new node with
the given number in the correct place in the tree. Returns the new
root pointer which the caller should then use (the standard trick to
avoid using reference parameters). */
struct node* insert(struct node* node, int data)
{
/* 1. If the tree is empty, return a new,
single node */
if (node == NULL)
return(newNode(data));
else
{
struct node *temp;
getchar();
return 0;
}
// Start from root and search for successor down the tree
while (root != NULL)
{
if (n->data < root->data)
{
succ = root;
root = root->left;
}
else if (n->data > root->data)
root = root->right;
else
break;
}
return succ;
}
http://net.pku.edu.cn/~course/cs101/2007/resource/Intro2Algorithm/book6/chap13.ht
m
Please write comments if you find anything incorrect, or you want to share more
information about the topic discussed above.
Source
http://www.geeksforgeeks.org/inorder-successor-in-binary-search-tree/
Implementation:
#include <stdio.h>
#include <stdlib.h>
#define ARRAY_SIZE(arr) sizeof(arr)/sizeof(arr[0])
/* same alias */
typedef struct node_t node_t;
node_t* left;
node_t* right;
};
return ret;
}
/* Iterative insertion
Recursion is least preferred unless we gain something
*/
node_t *insert_node(node_t *root, node_t* node)
{
/* A crawling pointer */
node_t *pTraverse = root;
node_t *currentParent = root;
return root;
}
/* Elements are in an array. The function builds binary tree */
node_t* binary_search_tree(node_t *root, int keys[], int const size)
{
int iterator;
node_t *new_node = NULL;
/* initialize */
new_node->data = keys[iterator];
new_node->left = NULL;
new_node->right = NULL;
return root;
}
int k = 5;
if( kNode )
{
printf("kth smallest elment for k = %d is %d", k, kNode->data);
}
else
{
printf("There is no such element");
}
getchar();
return 0;
}
stop:
Implementation:
#include <stdio.h>
#include <stdlib.h>
node_t* left;
node_t* right;
};
/* Iterative insertion
Recursion is least preferred unless we gain something
*/
node_t *insert_node(node_t *root, node_t* node)
{
/* A crawling pointer */
node_t *pTraverse = root;
node_t *currentParent = root;
return root;
}
/* initialize */
new_node->data = keys[iterator];
new_node->lCount = 0;
new_node->left = NULL;
new_node->right = NULL;
return root;
}
if( root )
{
/* A crawling pointer */
node_t *pTraverse = root;
/* Go to k-th smallest */
while(pTraverse)
{
if( (pTraverse->lCount + 1) == k )
{
ret = pTraverse->data;
break;
}
else if( k > pTraverse->lCount )
{
/* There are less nodes on left subtree
Go to right subtree */
k = k - (pTraverse->lCount + 1);
pTraverse = pTraverse->right;
}
else
{
/* The node is on left subtree */
pTraverse = pTraverse->left;
}
}
}
return ret;
}
getchar();
return 0;
}
Thanks to Venki for providing post. Please write comments if you find anything incorrect,
or you want to share more information about the topic discussed above.
Source
http://www.geeksforgeeks.org/find-k-th-smallest-element-in-bst-order-statistics-in-bst/
Category: Trees
Post navigation
Data Structures and Algorithms | Set 26 C Language | Set 8
Writing code in comment? Please use code.geeksforgeeks.org, generate link and share the
link here.
Get Level of a node in a Binary Tree
Given a Binary Tree and a key, write a function that returns level of the key.
For example, consider the following tree. If the input key is 3, then your function should
return 1. If the input key is 4, then your function should return 3. And for key which is not
present in key, then your function should return 0.
if (node->data == data)
return level;
return temp;
}
getchar();
return 0;
}
Output:
Level of 1 is 3
Level of 2 is 2
Level of 3 is 1
Level of 4 is 3
Level of 5 is 2
Time Complexity: O(n) where n is the number of nodes in the given Binary Tree.
Please write comments if you find anything incorrect, or you want to share more
information about the topic discussed above.
Source
http://www.geeksforgeeks.org/get-level-of-a-node-in-a-binary-tree/
Category: Trees
1
/ \
2 3
/ \
4 5
/
7
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
if (root->data == target)
return true;
return(node);
}
printAncestors(root, 7);
getchar();
return 0;
}
Output:
421
Time Complexity: O(n) where n is the number of nodes in the given Binary Tree.
Please write comments if you find anything incorrect, or you want to share more
information about the topic discussed above.
Source
http://www.geeksforgeeks.org/print-ancestors-of-a-given-node-in-binary-tree/
Category: Trees
/* The functions prints all the keys which in the given range [k1..k2].
The function assumes than k1 < k2 */
void Print(struct node *root, int k1, int k2)
{
/* base case */
if ( NULL == root )
return;
/* Since the desired o/p is sorted, recurse for left subtree first
If root->data is greater than k1, then only we can get o/p keys
in left subtree */
if ( k1 < root->data )
Print(root->left, k1, k2);
return temp;
}
getchar();
return 0;
}
Output:
12 20 22
Time Complexity: O(n) where n is the total number of keys in tree.
Please write comments if you find anything incorrect, or you want to share more
information about the topic discussed above.
Source
http://www.geeksforgeeks.org/print-bst-keys-in-the-given-range/
Category: Trees
The above tree contains 4 leaf nodes that represent players and have 3 levels 0, 1 and 2.
Initially 2 games are conducted at level 2, one between 5 and 3 and another one between 7
and 8. In the next move, one more game is conducted between 5 and 8 to conclude the final
winner. Overall we need 3 comparisons. For second best player we need to trace the
candidates participated with final winner, that leads to 7 as second best.
Median of Sorted Arrays
Tournament tree can effectively be used to find median of sorted arrays. Assume, given M
sorted arrays of equal size L (for simplicity). We can attach all these sorted arrays to the
tournament tree, one array per leaf. We need a tree of height CEIL (log2M) to have atleast
M external nodes.
Consider an example. Given 3 (M = 3) sorted integer arrays of maximum size 5 elements.
{ 2, 5, 7, 11, 15 } ---- Array1
{1, 3, 4} ---- Array2
{6, 8, 12, 13, 14} ---- Array3
What should be the height of tournament tree? We need to construct a tournament tree of
height log23 .= 1.585 = 2 rounded to next integer. A binary tree of height 2 will have 4
leaves to which we can attach the arrays as shown in the below figure.
The next winner is from Array1, so next element of Array1 array which is 5 will dive-in to
the next round, and next tournament played along the path of 2.
The tournaments can be continued till we get median element which is (5+3+5)/2 = 7th
element. Note that there are even better algorithms for finding median of union of sorted
arrays, for details see the related links given below.
In general with M sorted lists of size L1, L2 Lm requires time complexity of O((L1 + L2 +
+ Lm) * logM) to merge all the arrays, and O(m*logM) time to find median, where m is
median position.
Select smallest one million elements from one billion unsorted elements:
As a simple solution, we can sort the billion numbers and select first one million.
On a limited memory system sorting billion elements and picking the first one million
seems to be impractical. We can use tournament tree approach. At any time only elements
of tree to be in memory.
Split the large array (perhaps stored on disk) into smaller size arrays of size one million
each (or even smaller that can be sorted by the machine). Sort these 1000 small size arrays
and store them on disk as individual files. Construct a tournament tree which can have
atleast 1000 leaf nodes (tree to be of height 10 since 29 < 1000 < 210, if the individual file
size is even smaller we will need more leaf nodes). Every leaf node will have an engine that
picks next element from the sorted file stored on disk. We can play the tournament tree
game to extract first one million elements.
Total cost = sorting 1000 lists of one million each + tree construction + tournaments
Implementation
We need to build the tree (heap) in bottom-up manner. All the leaf nodes filled first. Start at
the left extreme of tree and fill along the breadth (i.e. from 2k-1 to 2k 1 where k is depth of
tree) and play the game. After practicing with few examples it will be easy to write code.
We will have code in an upcoming article.
Related Posts
Link 1, Link 2, Link 3, Link 4, Link 5, Link 6, Link 7.
by Venki. Please write comments if you find anything incorrect, or you want to share
more information about the topic discussed above.
Source
http://www.geeksforgeeks.org/tournament-tree-and-binary-heap/
26
/ \
10 3
/ \ \
4 6 3
Method 1 ( Simple )
Get the sum of nodes in left subtree and right subtree. Check if the sum calculated is equal
to roots data. Also, recursively check if the left and right subtrees are SumTrees.
#include <stdio.h>
#include <stdlib.h>
/* A binary tree node has data, left child and right child */
struct node
{
int data;
struct node* left;
struct node* right;
};
return 0;
}
/*
Helper function that allocates a new node
with the given data and NULL left and right
pointers.
*/
struct node* newNode(int data)
{
struct node* node =
(struct node*)malloc(sizeof(struct node));
node->data = data;
node->left = NULL;
node->right = NULL;
return(node);
}
getchar();
return 0;
}
Time Complexity: O(n^2) in worst case. Worst case occurs for a skewed tree.
Method 2 ( Tricky )
The Method 1 uses sum() to get the sum of nodes in left and right subtrees. The method 2
uses following rules to get the sum directly.
1) If the node is a leaf node then sum of subtree rooted with this node is equal to value of
this node.
2) If the node is not a leaf node then sum of subtree rooted with this node is twice the
value of this node (Assuming that the tree rooted with this node is SumTree).
#include <stdio.h>
#include <stdlib.h>
/* A binary tree node has data, left child and right child */
struct node
{
int data;
struct node* left;
struct node* right;
};
return 0;
}
getchar();
return 0;
}
Source
http://www.geeksforgeeks.org/check-if-a-given-binary-tree-is-sumtree/
Category: Trees
The outcome can be (12) < (34) i.e. we go on to left subtree or (12) > (34) i.e. we go on to
right subtree.
The left subtree is possible in two ways,
A) Either 1 or 2 can be lighter OR
B) Either 3 or 4 can be heavier.
Further on the left subtree, as second trial, we weigh (1, 2) or (3, 4). Let us consider (3, 4)
as the analogy for (1, 2) is similar. The outcome of second trail can be three ways
A) (3) < (4) yielding 4 as defective heavier coin, OR
B) (3) > (4) yielding 3 as defective heavier coin OR
C) (3) = (4), yielding ambiguity. Here we need one more weighing to check a genuine
coin against 1 or 2. In the figure I took (3, 2) where 3 is confirmed as genuine. We can
get (3) > (2) in which 2 is lighter, or (3) = (2) in which 1 is lighter. Note that it
impossible to get (3) < (2), it contradicts our assumption leaned to left side.
Similarly we can analyze the right subtree. We need two more weighings on right subtree
as well.
Overall we need 3 weighings to trace the odd coin. Note that we are unable to utilize two
outcomes of 3-ary trees. Also, the tree is not full tree, middle branch terminated after first
weighing. Infact, we can get 27 leaves of 3 level full 3-ary tree, but only we got 11 leaves
including impossible cases.
Analysis: Given N coins, all may be genuine or only one coin is defective. We need a
decision tree with atleast (2N + 1) leaves correspond to the outputs. Because there can be
N leaves to be lighter, or N leaves to be heavier or one genuine case, on total (2N + 1)
leaves.
As explained earlier ternary tree at level k, can have utmost 3k leaves and we need a tree
with leaves of 3k > (2N + 1).
In other words, we need atleast k > log3(2N + 1) weighing to find the defective one.
Observe the above figure that not all the branches are generating leaves, i.e. we are missing
valid outputs under some branches that leading to more number of trials. When possible,
we should group the coins in such a way that every branch is going to yield valid output (in
simple terms generate full 3-ary tree). Problem 4 describes this approach of 12 coins.
Problem 3: (Special case of two pan balance)
We are given 5 coins, a group of 4 coins out of which one coin is defective (we dont know
whether it is heavier or lighter), and one coin is genuine. How many weighing are required in
worst case to figure out the odd coin whether it is heavier or lighter?
Label the coins as 1, 2, 3, 4 and G (genuine). We now have some information on coin purity.
We need to make use that in the groupings.
We can best group them as [(G1, 23) and (4)]. Any other group cant generate full 3-ary
tree, try yourself. The following diagram explains the procedure.
The middle case (G1) = (23) is self explanatory, i.e. 1, 2, 3 are genuine and 4th coin can be
figured out lighter or heavier in one more trial.
The left side of tree corresponds to the case (G1) < (23). This is possible in two ways, either
1 should be lighter or either of (2, 3) should be heavier. The former instance is obvious
when next weighing (2, 3) is balanced, yielding 1 as lighter. The later instance could be (2)
< (3) yielding 3 as heavier or (2) > (3) yielding 2 as heavier. The leaf nodes on left branch
are named to reflect these outcomes.
The right side of tree corresponds to the case (G1) > (23). This is possible in two ways,
either 1 is heavier or either of (2, 3) should be lighter. The former instance is obvious when
the next weighing (2, 3) is balanced, yielding 1 as heavier. The later case could be (2) < (3)
yielding 2 as lighter coin, or (2) > (3) yielding 3 as lighter.
In the above problem, under any possibility we need only two weighing. We are able to use
all outcomes of two level full 3-ary tree. We started with (N + 1) = 5 coins where N = 4, we
end up with (2N + 1) = 9 leaves. Infact we should have 11 outcomes since we stared with
5 coins, where are other 2 outcomes? These two outcomes can be declared at the root
of tree itself (prior to first weighing), can you figure these two out comes?
If we observe the figure, after the first weighing the problem reduced to we know three
coins, either one can be lighter (heavier) or one among other two can be heavier (lighter).
This can be solved in one weighing (read Problem 1).
Analysis: Given (N + 1) coins, one is genuine and the rest N can be genuine or only one coin
is defective. The required decision tree should result in minimum of (2N + 1) leaves. Since
the total possible outcomes are (2(N + 1) + 1), number of weighing (trials) are given by the
height of ternary tree, k >= log3[2(N + 1) + 1]. Note the equality sign.
Rearranging k and N, we can weigh maximum of N <= (3k 3)/2 coins in k trials.
Problem 4: (The classic 12 coin puzzle)
You are given two pan fair balance. You have 12 identically looking coins out of which one
coin may be lighter or heavier. How can you find odd coin, if any, in minimum trials, also
determine whether defective coin is lighter or heavier, in the worst case?
How do you want to group them? Bi-set or tri-set? Clearly we can discard the option of
dividing into two equal groups. It cant lead to best tree. From the above two examples, we
can ensure that the decision tree can be used in optimal way if we can reveal atleaset one
genuine coin. Remember to group coins such that the first weighing reveals atleast one
genuine coin.
Let us name the coins as 1, 2, 8, A, B, C and D. We can combine the coins into 3 groups,
namely (1234), (5678) and (ABCD). Weigh (1234) and (5678). You are encouraged to draw
decision tree while reading the procedure. The outcome can be three ways,
1. (1234) = (5678), both groups are equal. Defective coin may be in (ABCD) group.
2. (1234) < (5678), i.e. first group is less in weight than second group.
3. (1234) > (5678), i.e. first group is more in weight than second group.
The output (1) can be solved in two more weighing as special case of two pan balance given
in Problem 3. We know that groups (1234) and (5678) are genuine and defective coin may
be in (ABCD). Pick one genuine coin from any of weighed groups, and proceed with (ABCD)
as explained in Problem 3.
Outcomes (2) and (3) are special. In both the cases, we know that (ABCD) is genuine. And
also, we know a set of coins being lighter and a set of coins being heavier. We need
to shuffle the weighed two groups in such a way that we end up with smaller height
decision tree.
Consider the second outcome where (1234) < (5678). It is possible when any coin among
(1, 2, 3, 4) is lighter or any coin among (5, 6, 7, 8 ) is heavier. We revealed lighter or heavier
possibility after first weighing. If we proceed as in Problem 1, we will not generate best
decision tree. Let us shuffle coins as (1235) and (4BCD) as new groups (there are different
shuffles possible, they also lead to minimum weighing, can you try?). If we weigh these two
groups again the outcome can be three ways, i) (1235) < (4BCD) yielding one among 1, 2, 3
is lighter which is similar to Problem 1 explained above, we need one more weighing, ii)
(1235) = (4BCD) yielding one among 6, 7, 8 is heavier which is similar to Problem 1
explained above, we need one more weighing iii) (1235) > (4BCD) yielding either 5 as
heavier coin or 4 as lighter coin, at the expense of one more weighing.
Similar way we can also solve the right subtree (third outcome where (1234) > (5678)) in
two more weighing.
We are able to solve the 12 coin puzzle in 3 weighing in the worst case.
Few Interesting Puzzles:
1. Solve Problem 4 with N = 8 and N = 13, How many minimum trials are required in
each case?
2. Given a function int weigh(A[], B[]) where A and B are arrays (need not be equal size).
The function returns -1, 0 or 1. It returns 0 if sum of all elements in A and B are equal, -
1 if A < B and 1 if A > B. Given an array of 12 elements, all elements are equal except
one. The odd element can be as that of others, smaller or greater than others. Write a
program to find the odd element (if any) using weigh() minimum number of times.
3. You might have seen 3-pan balance in science labs during school days. Given a 3-pan
balance (4 outcomes) and N coins, how many minimum trials are needed to figure out
odd coin?
References:
Similar problem was provided in one of the exercises of the book Introduction to
Algorithms by Levitin. Specifically read section 5.5 and section 11.2 including exercises.
by Venki. Please write comments if you find anything incorrect, or you want to share
more information about the topic discussed above.
Source
http://www.geeksforgeeks.org/decision-trees-fake-coin-puzzle/
Tree S
10
/ \
4 6
\
30
Tree T
26
/ \
10 3
/ \ \
4 6 3
\
30
Solution: Traverse the tree T in preorder fashion. For every visited node in the traversal,
see if the subtree rooted with this node is identical to S.
Following is C implementation for this.
#include <stdio.h>
#include <stdlib.h>
/* A binary tree node has data, left child and right child */
struct node
{
int data;
struct node* left;
struct node* right;
};
/* Check if the data of both roots is same and data of left and right
subtrees are also same */
return (root1->data == root2->data &&
areIdentical(root1->left, root2->left) &&
areIdentical(root1->right, root2->right) );
}
if (T == NULL)
return false;
/* Helper function that allocates a new node with the given data
and NULL left and right pointers. */
struct node* newNode(int data)
{
struct node* node =
(struct node*)malloc(sizeof(struct node));
node->data = data;
node->left = NULL;
node->right = NULL;
return(node);
}
if (isSubtree(T, S))
printf("Tree S is subtree of tree T");
else
printf("Tree S is not a subtree of tree T");
getchar();
return 0;
}
Output:
Time Complexity: Time worst case complexity of above solution is O(mn) where m and n
are number of nodes in given two trees.
We can solve the above problem in O(n) time. Please refer Check if a binary tree is subtree
of another binary tree | Set 2 for O(n) solution.
Please write comments if you find anything incorrect, or you want to share more
information about the topic discussed above.
Source
http://www.geeksforgeeks.org/check-if-a-binary-tree-is-subtree-of-another-binary-tree/
Category: Trees
Inserting a key into trie is simple approach. Every character of input key is inserted as an
individual trie node. Note that the children is an array of pointers to next level trie nodes.
The key character acts as an index into the array children. If the input key is new or an
extension of existing key, we need to construct non-existing nodes of the key, and mark leaf
node. If the input key is prefix of existing key in trie, we simply mark the last node of key as
leaf. The key length determines trie depth.
Searching for a key is similar to insert operation, however we only compare the characters
and move down. The search can terminate due to end of string or lack of key in trie. In
the former case, if the value field of last node is non-zero then the key exists in trie. In the
second case, the search terminates without examining all the characters of key, since the
key is not present in trie.
The following picture explains construction of trie using keys given in the example below,
root
/ \ \
t a b
| | |
h n y
| | \ |
e s y e
/ | |
i r w
| | |
r e e
|
r
In the picture, every character is of type trie_node_t. For example, the root is of
type trie_node_t, and its children a, b and t are filled, all other nodes of root will be NULL.
Similarly, a at the next level is having only one child (n), all other children are NULL.
The leaf nodes are in blue.
Insert and search costs O(key_length), however the memory requirements of trie is
O(ALPHABET_SIZE * key_length * N) where N is number of keys in trie. There are
efficient representation of trie nodes (e.g. compressed trie, ternary search tree, etc.)
to minimize memory requirements of trie.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// trie node
typedef struct trie_node trie_node_t;
struct trie_node
{
int value;
trie_node_t *children[ALPHABET_SIZE];
};
// trie ADT
typedef struct trie trie_t;
struct trie
{
trie_node_t *root;
int count;
};
if( pNode )
{
int i;
pNode->value = 0;
return pNode;
}
// Initializes trie (root is dummy node)
void initialize(trie_t *pTrie)
{
pTrie->root = getNode();
pTrie->count = 0;
}
pTrie->count++;
pCrawl = pTrie->root;
pCrawl = pCrawl->children[index];
}
pCrawl = pTrie->root;
if( !pCrawl->children[index] )
{
return 0;
}
pCrawl = pCrawl->children[index];
}
// Driver
int main()
{
// Input keys (use only 'a' through 'z' and lower case)
char keys[][8] = {"the", "a", "there", "answer", "any", "by", "bye",
"their"};
trie_t trie;
initialize(&trie);
// Construct trie
for(int i = 0; i < ARRAY_SIZE(keys); i++)
{
insert(&trie, keys[i]);
}
return 0;
}
Venki. Please write comments if you find anything incorrect, or you want to share more
information about the topic discussed above.
Source
http://www.geeksforgeeks.org/trie-insert-and-search/
Trie | (Delete)
In the previous post on trie we have described how to insert and search a node in trie. Here
is an algorithm how to delete a node from trie.
During delete operation we delete the key in bottom up manner using recursion. The
following are possible conditions when deleting key from trie,
1. Key may not be there in trie. Delete operation should not modify trie.
2. Key present as unique key (no part of key contains another key (prefix), nor the key
itself is prefix of another key in trie). Delete all the nodes.
3. Key is prefix key of another long key in trie. Unmark the leaf node.
4. Key present in trie, having atleast one other key as prefix key. Delete nodes from end
of key until first leaf node of longest prefix key.
The highlighted code presents algorithm to implement above conditions. (One may be in
dilemma how a pointer passed to delete helper is reflecting changes from deleteHelper to
deleteKey. Note that we are holding trie as an ADT in trie_t node, which is passed by
reference or pointer).
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define FREE(p) \
free(p); \
p = NULL;
// forward declration
typedef struct trie_node trie_node_t;
// trie node
struct trie_node
{
int value; // non zero if leaf
trie_node_t *children[ALPHABET_SIZE];
};
// trie ADT
typedef struct trie trie_t;
struct trie
{
trie_node_t *root;
int count;
};
trie_node_t *getNode(void)
{
trie_node_t *pNode = NULL;
if( pNode )
{
int i;
pNode->value = 0;
return pNode;
}
pTrie->count++;
pCrawl = pTrie->root;
if( pCrawl->children[index] )
{
// Skip current node
pCrawl = pCrawl->children[index];
}
else
{
// Add new node
pCrawl->children[index] = getNode();
pCrawl = pCrawl->children[index];
}
}
pCrawl = pTrie->root;
if( !pCrawl->children[index] )
{
return 0;
}
pCrawl = pCrawl->children[index];
}
return 1;
}
return false;
}
}
else // Recursive case
{
int index = INDEX(key[level]);
return false;
}
int main()
{
char keys[][8] = {"she", "sells", "sea", "shore", "the", "by", "sheer"};
trie_t trie;
initialize(&trie);
deleteKey(&trie, keys[0]);
return 0;
}
Venki. Please write comments if you find anything incorrect, or you want to share more
information about the topic discussed above.
Source
http://www.geeksforgeeks.org/trie-delete/
Category: Trees Tags: Advance Data Structures
Post navigation
Understanding volatile qualifier in C Find a Fixed Point in a given array
Writing code in comment? Please use code.geeksforgeeks.org, generate link and share the
link here.
Connect nodes at same level
Write a function to connect all the adjacent nodes at the same level in a binary tree.
Structure of the given Binary Tree node is like following.
struct node{
int data;
struct node* left;
struct node* right;
struct node* nextRight;
}
Initially, all the nextRight pointers point to garbage values. Your function should set these
pointers to point next right for each node.
Example
Input Tree
A
/ \
B C
/ \ \
D E F
Output Tree
A--->NULL
/ \
B-->C-->NULL
/ \ \
D-->E-->F-->NULL
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
struct node *left;
struct node *right;
struct node *nextRight;
};
// Sets the nextRight of root and calls connectRecur() for other nodes
void connect (struct node *p)
{
// Set the nextRight for root
p->nextRight = NULL;
// Set the next right for rest of the nodes (other than root)
connectRecur(p);
}
/* UTILITY FUNCTIONS */
/* Helper function that allocates a new node with the
given data and NULL left and right pointers. */
struct node* newnode(int data)
{
struct node* node = (struct node*)
malloc(sizeof(struct node));
node->data = data;
node->left = NULL;
node->right = NULL;
node->nextRight = NULL;
return(node);
}
getchar();
return 0;
}
1
/ \
2 3
/ \ / \
4 5 6 7
/ \ / \
8 9 10 11
Source
http://www.geeksforgeeks.org/connect-nodes-at-same-level/
struct node {
int data;
struct node* left;
struct node* right;
struct node* nextRight;
}
Initially, all the nextRight pointers point to garbage values. Your function should set these
pointers to point next right for each node. You can use only constant extra space.
Example
Input Tree
A
/ \
B C
/ \ \
D E F
Output Tree
A--->NULL
/ \
B-->C-->NULL
/ \ \
D-->E-->F-->NULL
We discussed two different approaches to do it in the previous post. The auxiliary space
required in both of those approaches is not constant. Also, the method 2 discussed there
only works for complete Binary Tree.
In this post, we will first modify the method 2 to make it work for all kind of trees. After
that, we will remove recursion from this method so that the extra space becomes constant.
A Recursive Solution
In the method 2 of previous post, we traversed the nodes in pre order fashion. Instead of
traversing in Pre Order fashion (root, left, right), if we traverse the nextRight node before
the left and right children (root, nextRight, left), then we can make sure that all nodes at
level i have the nextRight set, before the level i+1 nodes. Let us consider the following
example (same example as previous post). The method 2 fails for right child of node 4. In
this method, we make sure that all nodes at the 4s level (level 2) have nextRight set, before
we try to set the nextRight of 9. So when we set the nextRight of 9, we search for a nonleaf
node on right side of node 4 (getNextRight() does this for us).
1 -------------- Level 0
/ \
2 3 -------------- Level 1
/ \ / \
4 5 6 7 -------------- Level 2
/ \ / \
8 9 10 11 -------------- Level 3
// Sets the nextRight of root and calls connectRecur() for other nodes
void connect (struct node *p)
{
// Set the nextRight for root
p->nextRight = NULL;
// Set the next right for rest of the nodes (other than root)
connectRecur(p);
}
/* Set next right of all descendents of p. This function makes sure that
nextRight of nodes ar level i is set before level i+1 nodes. */
void connectRecur(struct node* p)
{
// Base case
if (!p)
return;
/* Recursively call for next level nodes. Note that we call only
for left child. The call for left child will call for right child */
connectRecur(p->left);
}
/* If left child is NULL then first node of next level will either be
p->right or getNextRight(p) */
else if (p->right)
{
p->right->nextRight = getNextRight(p);
connectRecur(p->right);
}
else
connectRecur(getNextRight(p));
}
/* This function returns the leftmost child of nodes at the same level as p.
This function is used to getNExt right of p's right child
If right child of p is NULL then this can also be used for the left child
*/
struct node *getNextRight(struct node *p)
{
struct node *temp = p->nextRight;
// If all the nodes at p's level are leaf nodes then return NULL
return NULL;
}
An Iterative Solution
The recursive approach discussed above can be easily converted to iterative. In the
iterative version, we use nested loop. The outer loop, goes through all the levels and the
inner loop goes through all the nodes at every level. This solution uses constant space.
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
struct node *left;
struct node *right;
struct node *nextRight;
};
/* This function returns the leftmost child of nodes at the same level as p.
This function is used to getNExt right of p's right child
If right child of is NULL then this can also be sued for the left child */
struct node *getNextRight(struct node *p)
{
struct node *temp = p->nextRight;
// If all the nodes at p's level are leaf nodes then return NULL
return NULL;
}
if (!p)
return;
if (q->right)
q->right->nextRight = getNextRight(q);
/* UTILITY FUNCTIONS */
/* Helper function that allocates a new node with the
given data and NULL left and right pointers. */
struct node* newnode(int data)
{
struct node* node = (struct node*)
malloc(sizeof(struct node));
node->data = data;
node->left = NULL;
node->right = NULL;
node->nextRight = NULL;
return(node);
}
getchar();
return 0;
}
Output:
Please write comments if you find anything incorrect, or you want to share more
information about the topic discussed above.
Source
http://www.geeksforgeeks.org/connect-nodes-at-same-level-with-o1-extra-space/
Algorithm
In the previous post, we discussed construction of BST from sorted Linked List.
Constructing from sorted array in O(n) time is simpler as we can get the middle element in
O(1) time. Following is a simple algorithm where we first find the middle node of list and
make it root of the tree to be constructed.
Following is C implementation of the above algorithm. The main code which creates
Balanced BST is highlighted.
#include<stdio.h>
#include<stdlib.h>
/* A function that constructs Balanced Binary Search Tree from a sorted array
*/
struct TNode* sortedArrayToBST(int arr[], int start, int end)
{
/* Base Case */
if (start > end)
return NULL;
return root;
}
return node;
}
/* A utility function to print preorder traversal of BST */
void preOrder(struct TNode* node)
{
if (node == NULL)
return;
printf("%d ", node->data);
preOrder(node->left);
preOrder(node->right);
}
return 0;
}
T(n) = 2T(n/2) + C
T(n) --> Time taken for an array of size n
C --> Constant (Finding middle of array and linking root to left
and right subtrees take constant time)
The above recurrence can be solved using Master Theorem as it falls in case 2.
Please write comments if you find anything incorrect, or you want to share more
information about the topic discussed above.
Source
http://www.geeksforgeeks.org/sorted-array-to-balanced-bst/
Category: Trees
Populate Inorder Successor for all nodes
Given a Binary Tree where each node has following structure, write a function to populate
next pointer for all nodes. The next pointer for every node should be set to point to inorder
successor.
struct node
{
int data;
struct node* left;
struct node* right;
struct node* next;
}
Initially, all next pointers have NULL values. Your function should fill these next pointers so
that they point to inorder successor.
Solution (Use Reverse Inorder Traversal)
Traverse the given tree in reverse inorder traversal and keep track of previously visited
node. When a node is being visited, assign previously visited node as next.
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
struct node *left;
struct node *right;
struct node *next;
};
if (p)
{
// First set the next pointer in right subtree
populateNext(p->right);
/* UTILITY FUNCTIONS */
/* Helper function that allocates a new node with the
given data and NULL left and right pointers. */
struct node* newnode(int data)
{
struct node* node = (struct node*)
malloc(sizeof(struct node));
node->data = data;
node->left = NULL;
node->right = NULL;
node->next = NULL;
return(node);
}
return 0;
}
We can avoid the use of static variable by passing reference to next as paramater.
populateNextRecur(root, &next);
}
10
/ \
-2 6
/ \ / \
8 -4 7 5
should be changed to
20(4-2+12+6)
/ \
4(8-4) 12(7+5)
/ \ / \
0 0 0 0
Solution:
Do a traversal of the given tree. In the traversal, store the old value of the current node,
recursively call for left and right subtrees and change the value of current node as sum of
the values returned by the recursive calls. Finally return the sum of new value and value
(which is sum of values in the subtree rooted with this node).
#include<stdio.h>
// Convert a given tree to a tree where every node contains sum of values of
// nodes in left and right subtrees in the original tree
int toSumTree(struct node *node)
{
// Base case
if(node == NULL)
return 0;
// Recursively call for left and right subtrees and store the sum as
// new value of this node
node->data = toSumTree(node->left) + toSumTree(node->right);
// Return the sum of values of nodes in left and right subtrees and
// old_value of this node
return node->data + old_val;
}
return temp;
}
toSumTree(root);
getchar();
return 0;
}
Output:
Time Complexity: The solution involves a simple traversal of the given tree. So the time
complexity is O(n) where n is the number of nodes in the given Binary Tree.
See thisforum thread for the original question. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above.
Source
http://www.geeksforgeeks.org/convert-a-given-tree-to-sum-tree/
Category: Trees
Input:
5
/ \
2 4
/ \
1 3
Output: 3
The following subtree is the maximum size BST subtree
2
/ \
1 3
Input:
50
/ \
30 60
/ \ / \
5 20 45 70
/ \
65 80
Output: 5
The following subtree is the maximum size BST subtree
60
/ \
45 70
/ \
65 80
/*
See http://www.geeksforgeeks.org/archives/632 for implementation of size()
Time Complexity: The worst case time complexity of this method will be O(n^2). Consider a
skewed tree for worst case analysis.
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
return(node);
}
return max_size;
}
/* Base Case */
if (node == NULL)
{
*is_bst_ref = 1; // An empty tree is BST
return 0; // Size of the BST is 0
}
/* Before updating *min_ref, store the min value in left subtree. So that
we
have the correct minimum value for this subtree */
min = *min_ref;
// Update min and max values for the parent recursive calls
if (min < *min_ref)
*min_ref = min;
if (node->data < *min_ref) // For leaf nodes
*min_ref = node->data;
if (node->data > *max_ref)
*max_ref = node->data;
/* If both left and right subtrees are BST. And left and right
subtree properties hold for this node, then this tree is BST.
So return the size of this tree */
if(left_flag && right_flag)
{
if (ls + rs + 1 > *max_size_ref)
*max_size_ref = ls + rs + 1;
return ls + rs + 1;
}
else
{
//Since this subtree is not BST, set is_bst flag for parent calls
*is_bst_ref = 0;
return 0;
}
}
getchar();
return 0;
}
Time Complexity: O(n) where n is the number of nodes in the given Binary Tree.
Please write comments if you find anything incorrect, or you want to share more
information about the topic discussed above.
Source
http://www.geeksforgeeks.org/find-the-largest-subtree-in-a-tree-that-is-also-a-bst/
Category: Trees
Post navigation
Complicated declarations in C Analysis of Algorithms | Set 2 (Worst, Average and Best
Cases)
Writing code in comment? Please use code.geeksforgeeks.org, generate link and share the
link here.
z z x
/ \ / \ / \
y T4 Left Rotate (y) x T4 Right Rotate(z) y z
/ \ - - - - - - - - -> / \ - - - - - - - -> / \ / \
T1 x y T3 T1 T2 T3 T4
/ \ / \
T2 T3 T1 T2
z y
/ \ / \
T1 y Left Rotate(z) z x
/ \ - - - - - - - -> / \ / \
T2 x T1 T2 T3 T4
/ \
T3 T4
z z x
/ \ / \ / \
T1 y Right Rotate (y) T1 x Left Rotate(z) z y
/ \ - - - - - - - - -> / \ - - - - - - - -> / \ / \
x T4 T2 y T1 T2 T3 T4
/ \ / \
T2 T3 T3 T4
C implementation
Following is the C implementation for AVL Tree Insertion. The following C implementation
uses the recursive BST insert to insert a new node. In the recursive BST insert, after
insertion, we get pointers to all ancestors one by one in bottom up manner. So we dont
need parent pointer to travel up. The recursive code itself travels up and visits all the
ancestors of the newly inserted node.
1) Perform the normal BST insertion.
2) The current node must be one of the ancestors of the newly inserted node. Update the
height of the current node.
3) Get the balance factor (left subtree height right subtree height) of the current node.
4) If balance factor is greater than 1, then the current node is unbalanced and we are either
in Left Left case or left Right case. To check whether it is left left case or not, compare the
newly inserted key with the key in left subtree root.
5) If balance factor is less than -1, then the current node is unbalanced and we are either in
Right Right case or Right Left case. To check whether it is Right Right case or not, compare
the newly inserted key with the key in right subtree root.
#include<stdio.h>
#include<stdlib.h>
/* Helper function that allocates a new node with the given key and
NULL left and right pointers. */
struct node* newNode(int key)
{
struct node* node = (struct node*)
malloc(sizeof(struct node));
node->key = key;
node->left = NULL;
node->right = NULL;
node->height = 1; // new node is initially added at leaf
return(node);
}
// Perform rotation
x->right = y;
y->left = T2;
// Update heights
y->height = max(height(y->left), height(y->right))+1;
x->height = max(height(x->left), height(x->right))+1;
// Perform rotation
y->left = x;
x->right = T2;
// Update heights
x->height = max(height(x->left), height(x->right))+1;
y->height = max(height(y->left), height(y->right))+1;
Output:
Time Complexity: The rotation operations (left and right rotate) take constant time as only
few pointers are being changed there. Updating the height and getting the balance factor
also take constant time. So the time complexity of AVL insert remains same as BST insert
which is O(h) where h is height of the tree. Since AVL tree is balanced, the height is
O(Logn). So time complexity of AVL insert is O(Logn).
The AVL tree and other self balancing search trees like Red Black are useful to get all basic
operations done in O(Logn) time. The AVL trees are more balanced compared to Red Black
Trees, but they may cause more rotations during insertion and deletion. So if your
application involves many frequent insertions and deletions, then Red Black trees should
be preferred. And if the insertions and deletions are less frequent and search is more
frequent operation, then AVL tree should be preferred over Red Black Tree.
Following is the post for delete.
AVL Tree | Set 2 (Deletion)
Following are some previous posts that have used self-balancing search trees.
Median in a stream of integers (running integers)
Maximum of all subarrays of size k
Count smaller elements on right side
References:
IITD Video Lecture on AVL Tree Introduction
IITD Video Lecture on AVL Tree Insertion and Deletion
Please write comments if you find anything incorrect, or you want to share more
information about the topic discussed above.
Source
http://www.geeksforgeeks.org/avl-tree-set-1-insertion/
Vertical Sum in a given Binary Tree
Given a Binary Tree, find vertical sum of the nodes that are in same vertical line. Print all
sums through different vertical lines.
Examples:
1
/ \
2 3
/ \ / \
4 5 6 7
import java.util.HashMap;
// data members
private int key;
private TreeNode left;
private TreeNode right;
// Accessor methods
public int key() { return key; }
public TreeNode left() { return left; }
public TreeNode right() { return right; }
// Constructor
public TreeNode(int key) { this.key = key; left = null; right = null; }
// Constructors
public Tree() { root = null; }
public Tree(TreeNode n) { root = n; }
// base case
if (root == null) { return; }
*/
TreeNode root = new TreeNode(1);
root.setLeft(new TreeNode(2));
root.setRight(new TreeNode(3));
root.left().setLeft(new TreeNode(4));
root.left().setRight(new TreeNode(5));
root.right().setLeft(new TreeNode(6));
root.right().setRight(new TreeNode(7));
Tree t = new Tree(root);
z z x
/ \ / \ / \
y T4 Left Rotate (y) x T4 Right Rotate(z) y z
/ \ - - - - - - - - -> / \ - - - - - - - -> / \ / \
T1 x y T3 T1 T2 T3 T4
/ \ / \
T2 T3 T1 T2
z y
/ \ / \
T1 y Left Rotate(z) z x
/ \ - - - - - - - -> / \ / \
T2 x T1 T2 T3 T4
/ \
T3 T4
z z x
/ \ / \ / \
T1 y Right Rotate (y) T1 x Left Rotate(z) z x
/ \ - - - - - - - - -> / \ - - - - - - - -> / \ / \
x T4 T2 y T1 T2 T3 T4
/ \ / \
T2 T3 T3 T4
#include<stdio.h>
#include<stdlib.h>
/* Helper function that allocates a new node with the given key and
NULL left and right pointers. */
struct node* newNode(int key)
{
struct node* node = (struct node*)
malloc(sizeof(struct node));
node->key = key;
node->left = NULL;
node->right = NULL;
node->height = 1; // new node is initially added at leaf
return(node);
}
// Perform rotation
x->right = y;
y->left = T2;
// Update heights
y->height = max(height(y->left), height(y->right))+1;
x->height = max(height(x->left), height(x->right))+1;
// Perform rotation
y->left = x;
x->right = T2;
// Update heights
x->height = max(height(x->left), height(x->right))+1;
y->height = max(height(y->left), height(y->right))+1;
/* Given a non-empty binary search tree, return the node with minimum
key value found in that tree. Note that the entire tree does not
need to be searched. */
struct node * minValueNode(struct node* node)
{
struct node* current = node;
return current;
}
if (root == NULL)
return root;
// No child case
if(temp == NULL)
{
temp = root;
root = NULL;
}
else // One child case
*root = *temp; // Copy the contents of the non-empty child
free(temp);
}
else
{
// node with two children: Get the inorder successor (smallest
// in the right subtree)
struct node* temp = minValueNode(root->right);
// STEP 3: GET THE BALANCE FACTOR OF THIS NODE (to check whether
// this node became unbalanced)
int balance = getBalance(root);
return root;
}
// A utility function to print preorder traversal of the tree.
// The function also prints height of every node
void preOrder(struct node *root)
{
if(root != NULL)
{
printf("%d ", root->key);
preOrder(root->left);
preOrder(root->right);
}
}
return 0;
}
Output:
Time Complexity: The rotation operations (left and right rotate) take constant time as only
few pointers are being changed there. Updating the height and getting the balance factor
also take constant time. So the time complexity of AVL delete remains same as BST delete
which is O(h) where h is height of the tree. Since AVL tree is balanced, the height is
O(Logn). So time complexity of AVL delete is O(Logn).
References:
IITD Video Lecture on AVL Tree Insertion and Deletion
Please write comments if you find anything incorrect, or you want to share more
information about the topic discussed above.
Source
http://www.geeksforgeeks.org/avl-tree-set-2-deletion/
Category: Trees Tags: Advance Data Structures
Post navigation
Vertical Sum in a given Binary Tree Operating Systems | Set 5
Writing code in comment? Please use code.geeksforgeeks.org, generate link and share the
link here.
Merge Two Balanced Binary Search Trees
You are given two balanced binary search trees e.g., AVL or Red Black Tree. Write a
function that merges the two given balanced BSTs into a balanced binary search tree. Let
there be m elements in first tree and n elements in the other tree. Your merge function
should take O(m+n) time.
In the following solutions, it is assumed that sizes of trees are also given as input. If the size
is not given, then we can get the size by traversing the tree (See this).
Method 1 (Insert elements of first tree to second)
Take all elements of first BST one by one, and insert them into the second BST. Inserting an
element to a self balancing BST takes Logn time (See this) where n is size of the BST. So
time complexity of this method is Log(n) + Log(n+1) Log(m+n-1). The value of this
expression will be between mLogn and mLog(m+n-1). As an optimization, we can pick the
smaller tree as first tree.
Method 2 (Merge Inorder Traversals)
1) Do inorder traversal of first tree and store the traversal in one temp array arr1[]. This
step takes O(m) time.
2) Do inorder traversal of second tree and store the traversal in another temp array arr2[].
This step takes O(n) time.
3) The arrays created in step 1 and 2 are sorted arrays. Merge the two sorted arrays into
one array of size m + n. This step takes O(m+n) time.
4) Construct a balanced tree from the merged array using the technique discussed in this
post. This step takes O(m+n) time.
Time complexity of this method is O(m+n) which is better than method 1. This method
takes O(m+n) time even if the input BSTs are not balanced.
Following is C++ implementation of this method.
#include <stdio.h>
#include <stdlib.h>
/* This function merges two balanced BSTs with roots as root1 and root2.
m and n are the sizes of the trees respectively */
struct node* mergeTrees(struct node *root1, struct node *root2, int m, int n)
{
// Store inorder traversal of first tree in an array arr1[]
int *arr1 = new int[m];
int i = 0;
storeInorder(root1, arr1, &i);
// Construct a tree from the merged array and return root of the tree
return sortedArrayToBST (mergedArr, 0, m+n-1);
}
return(node);
}
return mergedArr;
}
// A helper function that stores inorder traversal of a tree rooted with node
void storeInorder(struct node* node, int inorder[], int *index_ptr)
{
if (node == NULL)
return;
inorder[*index_ptr] = node->data;
(*index_ptr)++; // increase index for next entry
/* A function that constructs Balanced Binary Search Tree from a sorted array
See http://www.geeksforgeeks.org/archives/17138 */
struct node* sortedArrayToBST(int arr[], int start, int end)
{
/* Base Case */
if (start > end)
return NULL;
return root;
}
getchar();
return 0;
}
Output:
Post navigation
Greedy Algorithms | Set 1 (Activity Selection Problem) Union and Intersection of two
Linked Lists
Writing code in comment? Please use code.geeksforgeeks.org, generate link and share the
link here.
10
/ \
-2 7
/ \
8 -4
Solution
1) First find the leaf node that is on the maximum sum path. In the following code
getTargetLeaf() does this by assigning the result to *target_leaf_ref.
2) Once we have the target leaf node, we can print the maximum sum path by traversing
the tree. In the following code, printPath() does this.
The main function is maxSumPath() that uses above two functions to get the complete
solution.
#include<stdio.h>
#include<limits.h>
// A utility function that prints all nodes on the path from root to
target_leaf
bool printPath (struct node *root, struct node *target_leaf)
{
// base case
if (root == NULL)
return false;
return false;
}
// This function Sets the target_leaf_ref to refer the leaf node of the
maximum
// path sum. Also, returns the max_sum using max_sum_ref
void getTargetLeaf (struct node *node, int *max_sum_ref, int curr_sum,
struct node **target_leaf_ref)
{
if (node == NULL)
return;
// Update current sum to hold sum of nodes on path from root to this node
curr_sum = curr_sum + node->data;
// If this is a leaf node and path to this node has maximum sum so far,
// then make this node target_leaf
if (node->left == NULL && node->right == NULL)
{
if (curr_sum > *max_sum_ref)
{
*max_sum_ref = curr_sum;
*target_leaf_ref = node;
}
}
// If this is not a leaf node, then recur down to find the target_leaf
getTargetLeaf (node->left, max_sum_ref, curr_sum, target_leaf_ref);
getTargetLeaf (node->right, max_sum_ref, curr_sum, target_leaf_ref);
}
// Returns the maximum sum and prints the nodes on max sum path
int maxSumPath (struct node *node)
{
// base case
if (node == NULL)
return 0;
printf ("Following are the nodes on the maximum sum path \n");
int sum = maxSumPath(root);
printf ("\nSum of the nodes is %d ", sum);
getchar();
return 0;
}
Output:
Time Complexity: Time complexity of the above solution is O(n) as it involves tree traversal
two times.
Please write comments if you find anything incorrect, or you want to share more
information about the topic discussed above.
Source
http://www.geeksforgeeks.org/find-the-maximum-sum-path-in-a-binary-tree/
Category: Trees
First BST
3
/ \
1 5
Second BST
4
/ \
2 6
Output: 1 2 3 4 5 6
First BST
8
/ \
2 10
/
1
Second BST
5
/
3
/
0
Output: 0 1 2 3 5 8 10
#include<stdio.h>
#include<stdlib.h>
return 0;
}
//.................... END OF STACK RELATED STUFF....................
// Run the loop while there are nodes not yet printed.
// The nodes may be in stack(explored, but not printed)
// or may be not yet explored
while (current1 != NULL || !isEmpty(s1) ||
current2 != NULL || !isEmpty(s2))
{
// Following steps follow iterative Inorder Traversal
if (current1 != NULL || current2 != NULL )
{
// Reach the leftmost node of both BSTs and push ancestors of
// leftmost nodes to stack s1 and s2 respectively
if (current1 != NULL)
{
push(&s1, current1);
current1 = current1->left;
}
if (current2 != NULL)
{
push(&s2, current2);
current2 = current2->left;
}
}
else
{
// If we reach a NULL node and either of the stacks is empty,
// then one tree is exhausted, ptint the other tree
if (isEmpty(s1))
{
while (!isEmpty(s2))
{
current2 = pop (&s2);
current2->left = NULL;
inorder(current2);
}
return ;
}
if (isEmpty(s2))
{
while (!isEmpty(s1))
{
current1 = pop (&s1);
current1->left = NULL;
inorder(current1);
}
return ;
}
return 0;
}
Example 1
Input:
10
/ \
2 7
/ \
8 4
Output:
8
/ \
4 10
/ \
2 7
Example 2
Input:
10
/ \
30 15
/ \
20 5
Output:
15
/ \
10 20
/ \
5 30
Solution
Following is a 3 step solution for converting Binary tree to Binary Search Tree.
1) Create a temp array arr[] that stores inorder traversal of the tree. This step takes O(n)
time.
2) Sort the temp array arr[]. Time complexity of this step depends upon the sorting
algorithm. In the following implementation, Quick Sort is used which takes (n^2) time. This
can be done in O(nLogn) time using Heap Sort or Merge Sort.
3) Again do inorder traversal of tree and copy array elements to tree nodes one by one.
This step takes O(n) time.
Following is C implementation of the above approach. The main function to convert is
highlighted in the following code.
// Create a temp array arr[] and store inorder traversal of tree in arr[]
int *arr = new int[n];
int i = 0;
storeInorder (root, arr, &i);
return 0;
}
Output:
We will be covering another method for this problem which converts the tree using
O(height of tree) extra space.
Please write comments if you find anything incorrect, or you want to share more
information about the topic discussed above
Source
http://www.geeksforgeeks.org/binary-tree-to-binary-search-tree-conversion/
Category: Trees
The idea used in Construction of Tree from given Inorder and Preorder traversals can be
used here. Let the given array is {1, 5, 10, 40, 30, 15, 28, 20}. The maximum element in
given array must be root. The elements on left side of the maximum element are in left
subtree and elements on right side are in right subtree.
40
/ \
{1,5,10} {30,15,28,20}
We recursively follow above step for left and right subtrees, and finally get the following
tree.
40
/ \
10 30
/ \
5 28
/ / \
1 15 20
Algorithm: buildTree()
1) Find index of the maximum element in array. The maximum element must be root of
Binary Tree.
2) Create a new tree node root with the data as the maximum value found in step 1.
3) Call buildTree for elements before the maximum element and make the built tree as left
subtree of root.
5) Call buildTree for elements after the maximum element and make the built tree as right
subtree of root.
6) return root.
Implementation: Following is C/C++ implementation of the above algorithm.
return root;
}
/* UTILITY FUNCTIONS */
/* Function to find index of the maximum value in arr[start...end] */
int max (int arr[], int strt, int end)
{
int i, max = arr[strt], maxind = strt;
for(i = strt+1; i <= end; i++)
{
if(arr[i] > max)
{
max = arr[i];
maxind = i;
}
}
return maxind;
}
return node;
}
Output:
Inorder traversal of the constructed tree is
5 10 40 30 28
Source
http://www.geeksforgeeks.org/construct-binary-tree-from-inorder-traversal/
Category: Trees
Post navigation
Database Management Systems | Set 11 Multiline macros in C
Writing code in comment? Please use code.geeksforgeeks.org, generate link and share the
link here.
Input: pre[] = {10, 30, 20, 5, 15}, preLN[] = {'N', 'N', 'L', 'L', 'L'}
Output: Root of following tree
10
/ \
30 15
/ \
20 5
The first element in pre[] will always be root. So we can easily figure out root. If left subtree
is empty, the right subtree must also be empty and preLN[] entry for root must be L. We
can simply create a node and return it. If left and right subtrees are not empty, then
recursively call for left and right subtrees and link the returned nodes to root.
return temp;
}
return 0;
}
Output:
Following is Inorder Traversal of the Constructed Binary Tree:
20 30 5 10 15
Source
http://www.geeksforgeeks.org/construct-a-special-tree-from-given-preorder-traversal/
Category: Trees
Post navigation
Sieve of Eratosthenes Playing with Destructors in C++
Writing code in comment? Please use code.geeksforgeeks.org, generate link and share the
link here.
In Preorder traversal, descendants (or Preorder successors) of every node appear after the
node. In the above example, 20 is the first node in preorder and all descendants of 20
appear after it. All descendants of 20 are smaller than it. For 10, all descendants are greater
than it. In general, we can say, if all internal nodes have only one child in a BST, then all the
descendants of every node are either smaller or larger than the node. The reason is simple,
since the tree is BST and every node has only one child, all descendants of a node will either
be on left side or right side, means all descendants will either be smaller or greater.
Approach 1 (Naive)
This approach simply follows the above idea that all values on right side are either smaller
or larger. Use two loops, the outer loop picks an element one by one, starting from the
leftmost element. The inner loop checks if all elements on the right side of the picked
element are either smaller or greater. The time complexity of this method will be O(n^2).
Approach 2
Since all the descendants of a node must either be larger or smaller than the node. We can
do following for every node in a loop.
1. Find the next preorder successor (or descendant) of the node.
2. Find the last preorder successor (last element in pre[]) of the node.
3. If both successors are less than the current node, or both successors are greater than the
current node, then continue. Else, return false.
#include <stdio.h>
Output:
Yes
Approach 3
1. Scan the last two nodes of preorder & mark them as min & max.
2. Scan every node down the preorder array. Each node must be either smaller than the
min node or larger than the max node. Update min & max accordingly.
#include <stdio.h>
Output:
Yes
Please write comments if you find anything incorrect, or you want to share more
information about the topic discussed above
Source
http://www.geeksforgeeks.org/check-if-each-internal-node-of-a-bst-has-exactly-one-
child/
1
/ \
2 3
/
4
1
/ \
2 3
/ \ /
4 5 6
1
/ \
2 3
\ / \
4 5 6
1
/ \
2 3
/ \
4 5
1
/ \
2 3
\
4
Thanks to Guddu Sharma for suggesting this simple and efficient approach.
/*UTILITY FUNCTIONS*/
struct node** createQueue(int *front, int *rear)
{
struct node **queue =
(struct node **)malloc(sizeof(struct node*)*MAX_Q_SIZE);
*front = *rear = 0;
return queue;
}
return(node);
}
if ( isCompleteBT(root) == true )
printf ("Complete Binary Tree");
else
printf ("NOT Complete Binary Tree");
return 0;
}
Output:
NOT Complete Binary Tree
Time Complexity: O(n) where n is the number of nodes in given Binary Tree
Auxiliary Space: O(n) for queue.
Please write comments if you find any of the above codes/algorithms incorrect, or find
other ways to solve the same problem.
Source
http://www.geeksforgeeks.org/check-if-a-given-binary-tree-is-complete-tree-or-not/
Category: Trees
Post navigation
Microsoft Interview | Set 3 Amazon Interview | Set 4
Writing code in comment? Please use code.geeksforgeeks.org, generate link and share the
link here.
temp->data = data;
temp->left = temp->right = NULL;
return temp;
}
printBoundary( root );
return 0;
}
Output:
20 8 4 10 14 25 22
Source
http://www.geeksforgeeks.org/boundary-traversal-of-binary-tree/
Category: Trees
Input Tree:
10
/ \
5 8
/ \
2 20
In the above tree, nodes 20 and 8 must be swapped to fix the tree.
Following is the output tree
10
/ \
5 20
/ \
2 8
The inorder traversal of a BST produces a sorted array. So a simple method is to store
inorder traversal of the input tree in an auxiliary array. Sort the auxiliary array. Finally,
insert the auxiilary array elements back to the BST, keeping the structure of the BST same.
Time complexity of this method is O(nLogn) and auxiliary space needed is O(n).
We can solve this in O(n) time and with a single traversal of the given BST. Since
inorder traversal of BST is always a sorted array, the problem can be reduced to a problem
where two elements of a sorted array are swapped. There are two cases that we need to
handle:
1. The swapped nodes are not adjacent in the inorder traversal of the BST.
If we observe carefully, during inorder traversal, we find node 7 is smaller than the
previous visited node 25. Here save the context of node 25 (previous node). Again, we find
that node 5 is smaller than the previous node 20. This time, we save the context of node 5 (
current node ). Finally swap the two nodes values.
2. The swapped nodes are adjacent in the inorder traversal of BST.
Unlike case #1, here only one point exists where a node value is smaller than previous node
value. e.g. node 7 is smaller than node 8.
How to Solve? We will maintain three pointers, first, middle and last. When we find the first
point where current node value is smaller than previous node value, we update the first with
the previous node & middle with the current node. When we find the second point where
current node value is smaller than previous node value, we update the last with the current
node. In case #2, we will never find the second point. So, last pointer will not be updated. After
processing, if the last node value is null, then two swapped nodes of BST are adjacent.
Following is C implementation of the given code.
// This function does inorder traversal to find out the two swapped nodes.
// It sets three pointers, first, middle and last. If the swapped nodes are
// adjacent to each other, then first and middle contain the resultant nodes
// Else, first and last contain the resultant nodes
void correctBSTUtil( struct node* root, struct node** first,
struct node** middle, struct node** last,
struct node** prev )
{
if( root )
{
// Recur for the left subtree
correctBSTUtil( root->left, first, middle, last, prev );
// A function to fix a given BST where two nodes are swapped. This
// function uses correctBSTUtil() to find out two nodes and swaps the
// nodes to fix the BST
void correctBST( struct node* root )
{
// Initialize pointers needed for correctBSTUtil()
struct node *first, *middle, *last, *prev;
first = middle = last = prev = NULL;
// else nodes have not been swapped, passed tree is really BST.
}
correctBST(root);
return 0;
}
Output:
Inorder Traversal of the original tree
1 10 3 6 7 2 12
Inorder Traversal of the fixed tree
1 2 3 6 7 10 12
Source
http://www.geeksforgeeks.org/fix-two-swapped-nodes-of-bst/
Category: Trees
Post navigation
Output of C++ Program | Set 15 Private Destructor
Writing code in comment? Please use code.geeksforgeeks.org, generate link and share the
link here.
Construct Full Binary Tree from given preorder and postorder
traversals
Given two arrays that represent preorder and postorder traversals of a full binary tree,
construct the binary tree.
A Full Binary Tree is a binary tree where every node has either 0 or 2 children
Following are examples of Full Trees.
1
/ \
2 3
/ \ / \
4 5 6 7
1
/ \
2 3
/ \
4 5
/ \
6 7
1
/ \
2 3
/ \ / \
4 5 6 7
/ \
8 9
It is not possible to construct a general Binary Tree from preorder and postorder traversals
(See this). But if know that the Binary Tree is Full, we can construct the tree without
ambiguity. Let us understand this with the help of following example.
Let us consider the two given arrays as pre[] = {1, 2, 4, 8, 9, 5, 3, 6, 7} and post[] = {8, 9, 4, 5,
2, 6, 7, 3, 1};
In pre[], the leftmost element is root of tree. Since the tree is full and array size is more
than 1. The value next to 1 in pre[], must be left child of root. So we know 1 is root and 2 is
left child. How to find the all nodes in left subtree? We know 2 is root of all nodes in left
subtree. All nodes before 2 in post[] must be in left subtree. Now we know 1 is root,
elements {8, 9, 4, 5, 2} are in left subtree, and the elements {6, 7, 3} are in right subtree.
1
/ \
/ \
{8, 9, 4, 5, 2} {6, 7, 3}
We recursively follow the above approach and get the following tree.
1
/ \
2 3
/ \ / \
4 5 6 7
/ \
8 9
temp->data = data;
temp->left = temp->right = NULL;
return temp;
}
return root;
}
// The main function to construct Full Binary Tree from given preorder and
// postorder traversals. This function mainly uses constructTreeUtil()
struct node *constructTree (int pre[], int post[], int size)
{
int preIndex = 0;
return constructTreeUtil (pre, post, &preIndex, 0, size - 1, size);
}
return 0;
}
Output:
Inorder traversal of the constructed tree:
8 4 9 2 5 1 6 3 7
Please write comments if you find anything incorrect, or you want to share more
information about the topic discussed above.
Source
http://www.geeksforgeeks.org/full-and-complete-binary-tree-from-given-preorder-and-
postorder-traversals/
Category: Trees
Post navigation
Adobe Interview | Set 2 Lexicographic rank of a string
Writing code in comment? Please use code.geeksforgeeks.org, generate link and share the
link here.
10
/ \
5 40
/ \ \
1 7 50
10
/ \
/ \
{5, 1, 7} {40, 50}
We recursively follow above steps for subarrays {5, 1, 7} and {40, 50}, and get the complete
tree.
temp->data = data;
temp->left = temp->right = NULL;
return temp;
}
return root;
}
return 0;
}
Output:
1 5 7 10 40 50
temp->data = data;
temp->left = temp->right = NULL;
return temp;
}
return root;
}
return 0;
}
Output:
1 5 7 10 40 50
Source
http://www.geeksforgeeks.org/construct-bst-from-given-preorder-traversa/
Category: Trees
Post navigation
Shuffle a given array Construct BST from given preorder traversal | Set 2
Writing code in comment? Please use code.geeksforgeeks.org, generate link and share the
link here.
10
/ \
5 40
/ \ \
1 7 50
We have discussed O(n^2) and O(n) recursive solutions in the previous post. Following is a
stack based iterative solution that works in O(n) time.
1. Create an empty stack.
2. Make the first value as root. Push it to the stack.
3. Keep on popping while the stack is not empty and the next value is greater than stacks
top value. Make this value as the right child of the last popped node. Push the new node to
the stack.
4. If the next value is less than the stacks top value, make this value as the left child of the
stacks top node. Push the new node to the stack.
5. Repeat steps 2 and 3 until there are items remaining in pre[].
// Push root
push( stack, root );
int i;
Node* temp;
// Make this greater value as the right child and push it to the
stack
if ( temp != NULL)
{
temp->right = newNode( pre[i] );
push( stack, temp->right );
}
// If the next value is less than the stack's top value, make this
value
// as the left child of the stack's top node. Push the new node to
stack
else
{
peek( stack )->left = newNode( pre[i] );
push( stack, peek( stack )->left );
}
}
return root;
}
return 0;
}
Output:
1 5 7 10 40 50
Time Complexity: O(n). The complexity looks more from first look. If we take a closer look,
we can observe that every item is pushed and popped only once. So at most 2n push/pop
operations are performed in the main loops of constructTree(). Therefore, time complexity
is O(n).
Please write comments if you find anything incorrect, or you want to share more
information about the topic discussed above.
Source
http://www.geeksforgeeks.org/construct-bst-from-given-preorder-traversal-set-2/
Category: Trees
/* A binary tree node has key, left child and right child */
struct node
{
int key;
struct node* left;
struct node* right;
};
/* Helper function that allocates a new node with the given key and
NULL left and right pointers.*/
struct node* newNode(int key)
{
struct node* node = (struct node*)malloc(sizeof(struct node));
node->key = key;
node->left = NULL;
node->right = NULL;
return(node);
}
root->left = newNode(4);
root->right = newNode(12);
root->left->left = newNode(2);
root->left->right = newNode(6);
root->right->left = newNode(10);
root->right->right = newNode(14);
return 0;
}
Output:
0 2
1 2
2 2
3 4
4 4
5 6
6 6
7 8
8 8
9 10
10 10
11 12
12 12
13 14
14 14
15 -1
Exercise:
1. Modify above code to find floor value of input key in a binary search tree.
2. Write neat algorithm to find floor and ceil values in a sorted array. Ensure to handle all
possible boundary conditions.
Venki. Please write comments if you find anything incorrect, or you want to share more
information about the topic discussed above.
Source
http://www.geeksforgeeks.org/floor-and-ceil-from-a-bst/
Category: Trees
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <stack>
/* A binary tree node has data, left child and right child */
struct node
{
int data;
struct node* left;
struct node* right;
};
/* Helper function that allocates a new node with the given data and
NULL left and right pointers.*/
struct node* newNode(int data)
{
struct node* node = new struct node;
node->data = data;
node->left = NULL;
node->right = NULL;
return(node);
}
/* Pop all items one by one. Do following for every popped item
a) print it
b) push its right child
c) push its left child
Note that right child is pushed first so that left is processed first */
while (nodeStack.empty() == false)
{
// Pop the top item from stack and print it
struct node *node = nodeStack.top();
printf ("%d ", node->data);
nodeStack.pop();
Output:
10 8 3 5 2 2
This article is compiled by Saurabh Sharma and reviewed by GeeksforGeeks team. Please
write comments if you find anything incorrect, or you want to share more information
about the topic discussed above
Source
http://www.geeksforgeeks.org/iterative-preorder-traversal/
Category: Trees
Convert a BST to a Binary Tree such that sum of all greater keys is
added to every ke
Given a Binary Search Tree (BST), convert it to a Binary Tree such that every key of the
original BST is changed to key plus sum of all greater keys in BST.
Examples:
// Program to change a BST to Binary Tree such that key of a node becomes
// original key plus sum of all greater keys in BST
#include <stdio.h>
#include <stdlib.h>
// A recursive function that traverses the given BST in reverse inorder and
// for every key, adds all greater keys to it
void addGreaterUtil(struct node *root, int *sum_ptr)
{
// Base Case
if (root == NULL)
return;
addGreater(root);
return 0;
}
Output:
Inorder traversal of the given tree
2 5 13
Inorder traversal of the modified tree
20 18 13
Time Complexity: O(n) where n is the number of nodes in given Binary Search Tree.
Please write comments if you find anything incorrect, or you want to share more
information about the topic discussed above
Source
http://www.geeksforgeeks.org/convert-bst-to-a-binary-tree/
Category: Trees Tags: Amazon, BST
Morris traversal for Preorder
Using Morris Traversal, we can traverse the tree without using stack and recursion. The
algorithm for Preorder is almost similar to Morris traversal for Inorder.
1...If left child is null, print the current node data. Move to right child.
.Else, Make the right child of the inorder predecessor point to the current node. Two
cases arise:
a) The right child of the inorder predecessor already points to the current node. Set
right child to NULL. Move to right child of current node.
b) The right child is NULL. Set it to current node. Print current nodes data and move
to left child of current node.
2...Iterate until current node is not NULL.
Following is C implementation of the above algorithm.
struct node
{
int data;
struct node *left, *right;
};
root = newNode(1);
root->left = newNode(2);
root->right = newNode(3);
root->left->left = newNode(4);
root->left->right = newNode(5);
root->right->left = newNode(6);
root->right->right = newNode(7);
root->left->left->left = newNode(8);
root->left->left->right = newNode(9);
root->left->right->left = newNode(10);
root->left->right->right = newNode(11);
morrisTraversalPreorder(root);
printf("\n");
preorder(root);
return 0;
}
Output:
1 2 4 8 9 5 10 11 3 6 7
1 2 4 8 9 5 10 11 3 6 7
Limitations:
Morris traversal modifies the tree during the process. It establishes the right links while
moving down the tree and resets the right links while moving up the tree. So the algorithm
cannot be applied if write operations are not allowed.
This article is compiled by Aashish Barnwal and reviewed by GeeksforGeeks team. Please
write comments if you find anything incorrect, or you want to share more information
about the topic discussed above.
Source
http://www.geeksforgeeks.org/morris-traversal-for-preorder/
Category: Trees
1
/ \
2 3
1
/ \
2 3
/ \ /
4 5 6
1
/ \
2 3
/ /
4 5
1
/ \
2 3
/ \ /
4 5 6
/
7
Complete binary trees are generally represented using arrays. The array representation is
better because it doesnt contain any empty slot. Given parent index i, its left child is given
by 2 * i + 1 and its right child is given by 2 * i + 2. So no extra space is wasted and space to
store left and right pointers is saved. However, it may be an interesting programming
question to created a Complete Binary Tree using linked representation. Here Linked mean
a non-array representation where left and right pointers(or references) are used to refer
left and right children respectively. How to write an insert function that always adds a new
node in the last level and at the leftmost available position?
To create a linked complete binary tree, we need to keep track of the nodes in a level order
fashion such that the next node to be inserted lies in the leftmost position. A queue data
structure can be used to keep track of the inserted nodes.
Following are steps to insert a new node in Complete Binary Tree.
1. If the tree is empty, initialize the root with new node.
2. Else, get the front node of the queue.
.If the left child of this front node doesnt exist, set the left child as the new node.
.else if the right child of this front node doesnt exist, set the right child as the new
node.
3. If the front node has both the left child and right child, Dequeue() it.
4. Enqueue() the new node.
Below is the implementation:
// A tree node
struct node
{
int data;
struct node *right,*left;
};
// A queue node
struct Queue
{
int front, rear;
int size;
struct node* *array;
};
int i;
for (i = 0; i < size; ++i)
queue->array[i] = NULL;
return queue;
}
queue->array[++queue->rear] = root;
if (isEmpty(queue))
++queue->front;
}
if (hasOnlyOneItem(queue))
queue->front = queue->rear = -1;
else
++queue->front;
return temp;
}
else
{
// get the front node of the queue.
struct node* front = getFront(queue);
// If the left child of this front node doesnt exist, set the
// left child as the new node
if (!front->left)
front->left = temp;
// If the right child of this front node doesnt exist, set the
// right child as the new node
else if (!front->right)
front->right = temp;
// If the front node has both the left child and right child,
// Dequeue() it.
if (hasBothChild(front))
Dequeue(queue);
}
Enqueue(root, queue);
while (!isEmpty(queue))
{
struct node* temp = Dequeue(queue);
if (temp->left)
Enqueue(temp->left, queue);
if (temp->right)
Enqueue(temp->right, queue);
}
}
levelOrder(root);
return 0;
}
Output:
1 2 3 4 5 6 7 8 9 10 11 12
This article is compiled by Aashish Barnwal and reviewed by GeeksforGeeks team. Please
write comments if you find anything incorrect, or you want to share more information
about the topic discussed above.
Source
http://www.geeksforgeeks.org/linked-complete-binary-tree-its-creation/
Ternary Search Tree
A ternary search tree is a special trie data structure where the child nodes of a standard
trie are ordered as a binary search tree.
Representation of ternary search trees:
Unlike trie(standard) data structure where each node contains 26 pointers for its children,
each node in a ternary search tree contains only 3 pointers:
1. The left pointer points to the node whose value is less than the value in the current node.
2. The equal pointer points to the node whose value is equal to the value in the current
node.
3. The right pointer points to the node whose value is greater than the value in the current
node.
Apart from above three pointers, each node has a field to indicate data(character in case of
dictionary) and another field to mark end of a string.
So, more or less it is similar to BST which stores data based on some order. However, data
in a ternary search tree is distributed over the nodes. e.g. It needs 4 nodes to store the word
Geek.
Below figure shows how exactly the words in a ternary search tree are stored?
One of the advantage of using ternary search trees over tries is that ternary search trees
are a more space efficient (involve only three pointers per node as compared to 26 in
standard tries). Further, ternary search trees can be used any time a hashtable would be
used to store strings.
Tries are suitable when there is a proper distribution of words over the alphabets so that
spaces are utilized most efficiently. Otherwise ternary search trees are better. Ternary
search trees are efficient to use(in terms of space) when the strings to be stored share a
common prefix.
Applications of ternary search trees:
1. Ternary search trees are efficient for queries like Given a word, find the next word in
dictionary(near-neighbor lookups) or Find all telephone numbers starting with 9342 or
typing few starting characters in a web browser displays all website names with this
prefix(Auto complete feature).
2. Used in spell checks: Ternary search trees can be used as a dictionary to store all the
words. Once the word is typed in an editor, the word can be parallely searched in the
ternary search tree to check for correct spelling.
Implementation:
Following is C implementation of ternary search tree. The operations implemented are,
search, insert and traversal.
else
{
if (*(word+1) == '\0')
return root->isEndOfString;
insert(&root, "cat");
insert(&root, "cats");
insert(&root, "up");
insert(&root, "bug");
return 0;
}
Output:
Following is traversal of ternary search tree
bug
cat
cats
up
Time Complexity: The time complexity of the ternary search tree operations is similar to
that of binary search tree. i.e. the insertion, deletion and search operations take time
proportional to the height of the ternary search tree. The space is proportional to the
length of the string to be stored.
Reference:
http://en.wikipedia.org/wiki/Ternary_search_tree
This article is compiled by Aashish Barnwaland reviewed by GeeksforGeeks team. Please
write comments if you find anything incorrect, or you want to share more information
about the topic discussed above.
Source
http://www.geeksforgeeks.org/ternary-search-tree/
Category: Trees Tags: Advance Data Structures, Advanced Data Structures
Post navigation
[TopTalent.in] Exclusive Interview with Ravi Kiran from BITS, Pilani who got placed in
Google, Microsoft and Facebook Amazon Interview | Set 17
Writing code in comment? Please use code.geeksforgeeks.org, generate link and share the
link here.
int getSum(node, l, r)
{
if range of node is within l and r
return value in node
else if range of node is completely outside l and r
return 0
else
return getSum(node's left child, l, r) +
getSum(node's right child, l, r)
}
Update a value
Like tree construction and query operations, update can also be done recursively. We are
given an index which needs to updated. Let diff be the value to be added. We start from root
of the segment tree, and add diff to all nodes which have given index in their range. If a
node doesnt have given index in its range, we dont make any changes to that node.
Implementation:
Following is implementation of segment tree. The program implements construction of
segment tree for any given array. It also implements query and update operations.
/* A recursive function to update the nodes which have the given index in
their range. The following are parameters
st, si, ss and se are same as getSumUtil()
i --> index of the element to be updated. This index is in input
array.
diff --> Value to be added to all nodes which have i in range */
void updateValueUtil(int *st, int ss, int se, int i, int diff, int si)
{
// Base Case: If the input index lies outside the range of this segment
if (i < ss || i > se)
return;
// If the input index is in range of this node, then update the value
// of the node and its children
st[si] = st[si] + diff;
if (se != ss)
{
int mid = getMid(ss, se);
updateValueUtil(st, ss, mid, i, diff, 2*si + 1);
updateValueUtil(st, mid+1, se, i, diff, 2*si + 2);
}
}
// The function to update a value in input array and segment tree.
// It uses updateValueUtil() to update the value in segment tree
void updateValue(int arr[], int *st, int n, int i, int new_val)
{
// Check for erroneous input index
if (i < 0 || i > n-1)
{
printf("Invalid Input");
return;
}
// If there are more than one elements, then recur for left and
// right subtrees and store the sum of values in this node
int mid = getMid(ss, se);
st[si] = constructSTUtil(arr, ss, mid, st, si*2+1) +
constructSTUtil(arr, mid+1, se, st, si*2+2);
return st[si];
}
return 0;
}
Output:
Sum of values in given range = 15
Updated sum of values in given range = 22
Time Complexity:
Time Complexity for tree construction is O(n). There are total 2n-1 nodes, and value of
every node is calculated only once in tree construction.
Time complexity to query is O(Logn). To query a sum, we process at most four nodes at
every level and number of levels is O(Logn).
The time complexity of update is also O(Logn). To update a leaf value, we process one node
at every level and number of levels is O(Logn).
Source
http://www.geeksforgeeks.org/segment-tree-set-1-sum-of-given-range/
Category: Trees Tags: Advance Data Structures, Advanced Data Structures, SegmentTree
Post navigation
Amazon Interview | Set 17 Works Applications Co., Ltd. Japan Interview | Set 1
Writing code in comment? Please use code.geeksforgeeks.org, generate link and share the
link here.
Implementation:
// If there are more than one elements, then recur for left and
// right subtrees and store the minimum of two values in this node
int mid = getMid(ss, se);
st[si] = minVal(constructSTUtil(arr, ss, mid, st, si*2+1),
constructSTUtil(arr, mid+1, se, st, si*2+2));
return st[si];
}
/* Function to construct segment tree from given array. This function
allocates memory for segment tree and calls constructSTUtil() to
fill the allocated memory */
int *constructST(int arr[], int n)
{
// Allocate memory for segment tree
int x = (int)(ceil(log2(n))); //Height of segment tree
int max_size = 2*(int)pow(2, x) - 1; //Maximum size of segment tree
int *st = new int[max_size];
return 0;
}
Output:
Time Complexity:
Time Complexity for tree construction is O(n). There are total 2n-1 nodes, and value of
every node is calculated only once in tree construction.
Time complexity to query is O(Logn). To query a range minimum, we process at most two
nodes at every level and number of levels is O(Logn).
Please refer following links for more solutions to range minimum query problem.
http://community.topcoder.com/tc?module=Static&d1=tutorials&d2=lowestCommonAnce
stor#Range_Minimum_Query_(RMQ)
http://wcipeg.com/wiki/Range_minimum_query
Please write comments if you find anything incorrect, or you want to share more
information about the topic discussed above.
Source
http://www.geeksforgeeks.org/segment-tree-set-1-range-minimum-query/
Category: Trees Tags: Advance Data Structures, Advanced Data Structures
Post navigation
[TopTalent.in] Interview with Sujeet Gholap, placed in Microsoft, Google, Samsung,
Goldman Sachs & Tower Research How to measure time taken by a function in C?
Writing code in comment? Please use code.geeksforgeeks.org, generate link and share the
link here.
The idea is simple, there are two possibilities for every node X, either X is a member of the
set or not a member. If X is a member, then the value of LISS(X) is 1 plus LISS of all
grandchildren. If X is not a member, then the value is sum of LISS of all children.
2) Overlapping Subproblems
Following is recursive implementation that simply follows the recursive structure
mentioned above.
/* A binary tree node has data, pointer to left child and a pointer to
right child */
struct node
{
int data;
struct node *left, *right;
};
return 0;
}
Output:
Size of the Largest Independent Set is 5
Time complexity of the above naive recursive approach is exponential. It should be noted
that the above function computes the same subproblems again and again. For example,
LISS of node with value 50 is evaluated for node with values 10 and 20 as 50 is grandchild
of 10 and child of 20.
Since same suproblems are called again, this problem has Overlapping Subprolems
property. So LISS problem has both properties (see thisand this) of a dynamic
programming problem. Like other typical Dynamic Programming(DP) problems,
recomputations of same subproblems can be avoided by storing the solutions to
subproblems and solving problems in bottom up manner.
Following is C implementation of Dynamic Programming based solution. In the following
solution, an additional field liss is added to tree nodes. The initial value of liss is set as 0
for all nodes. The recursive function LISS() calculates liss for a node only if it is not already
set.
/* A binary tree node has data, pointer to left child and a pointer to
right child */
struct node
{
int data;
int liss;
struct node *left, *right;
};
if (root->liss)
return root->liss;
return root->liss;
}
return 0;
}
Output
Size of the Largest Independent Set is 5
Time Complexity: O(n) where n is the number of nodes in given Binary tree.
Following extensions to above solution can be tried as an exercise.
1) Extend the above solution for n-ary tree.
2) The above solution modifies the given tree structure by adding an additional field liss
to tree nodes. Extend the solution so that it doesnt modify the tree structure.
3) The above solution only returns size of LIS, it doesnt print elements of LIS. Extend the
solution to print all nodes that are part of LIS.
Please write comments if you find anything incorrect, or you want to share more
information about the topic discussed above.
Source
http://www.geeksforgeeks.org/largest-independent-set-problem/
Following are the steps to print postorder traversal of the above tree using two stacks.
#include <stdio.h>
#include <stdlib.h>
// A tree node
struct Node
{
int data;
struct Node *left, *right;
};
// Stack type
struct Stack
{
int size;
int top;
struct Node* *array;
};
postOrderIterative(root);
return 0;
}
Output:
4 5 2 6 7 3 1
Source
http://www.geeksforgeeks.org/iterative-postorder-traversal/
Category: Trees Tags: stack
Post navigation
Flatten a multilevel linked list Iterative Postorder Traversal | Set 2 (Using One Stack)
Writing code in comment? Please use code.geeksforgeeks.org, generate link and share the
link here.
Following are the steps to print postorder traversal of the above tree using one stack.
7. Current node is NULL. Pop 5 from stack. Right child of 5 doesn't exist.
Print 5. Set current node to NULL.
Stack: 3, 1, 2
// A tree node
struct Node
{
int data;
struct Node *left, *right;
};
// Stack type
struct Stack
{
int size;
int top;
struct Node* *array;
};
// If the popped item has a right child and the right child is not
// processed yet, then make sure right child is processed before root
if (root->right && peek(stack) == root->right)
{
pop(stack); // remove right child from stack
push(stack, root); // push root back to stack
root = root->right; // change root so that the right
// child is processed next
}
else // Else print root's data and set root as NULL
{
printf("%d ", root->data);
root = NULL;
}
} while (!isEmpty(stack));
}
postOrderIterative(root);
return 0;
}
Output:
4 5 2 6 7 3 1
This article is compiled byAashish Barnwal. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above
Source
http://www.geeksforgeeks.org/iterative-postorder-traversal-using-stack/
Category: Trees Tags: stack
Post navigation
Iterative Postorder Traversal | Set 1 (Using Two Stacks) Generate n-bit Gray Codes
Writing code in comment? Please use code.geeksforgeeks.org, generate link and share the
link here.
// If tail is not NULL, then set right of tail as root, else current
// node is head
if (*tail)
(*tail)->right = root;
else
*head = root;
// Update tail
*tail = root;
// This function returns true if there is pair in DLL with sum equal
// to given sum. The algorithm is similar to hasArrayTwoCandidates()
// in method 1 of http://tinyurl.com/dy6palr
bool isPresentInDLL(node* head, node* tail, int sum)
{
while (head != tail)
{
int curr = head->key + tail->key;
if (curr == sum)
return true;
else if (curr > sum)
tail = tail->left;
else
head = head->right;
}
return false;
}
// Convert given BST to doubly linked list. head and tail store the
// pointers to first and last nodes in DLLL
node* head = NULL;
node* tail = NULL;
convertBSTtoDLL(root, &head, &tail);
// Now iterate through every node and find if there is a pair with sum
// equal to -1 * heaf->key where head is current node
while ((head->right != tail) && (head->key < 0))
{
// If there is a pair with sum equal to -1*head->key, then return
// true else move forward
if (isPresentInDLL(head->right, tail, -1*head->key))
return true;
else
head = head->right;
}
// A utility function to create a new BST node with key as given num
node* newNode(int num)
{
node* temp = new node;
temp->key = num;
temp->left = temp->right = NULL;
return temp;
}
Output:
Present
Source
http://www.geeksforgeeks.org/find-if-there-is-a-triplet-in-bst-that-adds-to-0/
Find a pair with given sum in a Balanced BST
Given a Balanced Binary Search Tree and a target sum, write a function that returns true if
there is a pair with sum equals to target sum, otherwise return false. Expected time
complexity is O(n) and only O(Logn) extra space can be used. Any modification to Binary
Search Tree is not allowed. Note that height of a Balanced BST is always O(Logn).
This problem is mainly extension of the previous post. Here we are not allowed to modify
the BST.
The Brute Force Solution is to consider each pair in BST and check whether the sum
equals to X. The time complexity of this solution will be O(n^2).
A Better Solution is to create an auxiliary array and store Inorder traversal of BST in the
array. The array will be sorted as Inorder traversal of BST always produces sorted data.
Once we have the Inorder traversal, we can pair in O(n) time (See this for details). This
solution works in O(n) time, but requires O(n) auxiliary space.
A space optimized solution is discussed in previous post. The idea was to first in-place
convert BST to Doubly Linked List (DLL), then find pair in sorted DLL in O(n) time. This
solution takes O(n) time and O(Logn) extra space, but it modifies the given BST.
The solution discussed below takes O(n) time, O(Logn) space and doesnt modify BST.
The idea is same as finding the pair in sorted array (See method 1 of this for details). We
traverse BST in Normal Inorder and Reverse Inorder simultaneously. In reverse inorder,
we start from the rightmost node which is the maximum value node. In normal inorder, we
start from the left most node which is minimum value node. We add sum of current nodes
in both traversals and compare this sum with given target sum. If the sum is same as target
sum, we return true. If the sum is more than target sum, we move to next node in reverse
inorder traversal, otherwise we move to next node in normal inorder traversal. If any of the
traversals is finished without finding a pair, we return false. Following is C++
implementation of this approach.
/* In a balanced binary search tree isPairPresent two element which sums to
a given value time O(n) space O(logn) */
#include <stdio.h>
#include <stdlib.h>
#define MAX_SIZE 100
// A BST node
struct node
{
int val;
struct node *left, *right;
};
// Stack type
struct Stack
{
int size;
int top;
struct node* *array;
};
// Returns true if a pair with target sum exists in BST, otherwise false
bool isPairPresent(struct node *root, int target)
{
// Create two stacks. s1 is used for normal inorder traversal
// and s2 is used for reverse inorder traversal
struct Stack* s1 = createStack(MAX_SIZE);
struct Stack* s2 = createStack(MAX_SIZE);
// Note the sizes of stacks is MAX_SIZE, we can find the tree size and
// fix stack size as O(Logn) for balanced trees like AVL and Red Black
// tree. We have used MAX_SIZE to keep the code simple
// done1, val1 and curr1 are used for normal inorder traversal using s1
// done2, val2 and curr2 are used for reverse inorder traversal using s2
bool done1 = false, done2 = false;
int val1 = 0, val2 = 0;
struct node *curr1 = root, *curr2 = root;
// The loop will break when we either find a pair or one of the two
// traversals is complete
while (1)
{
// Find next node in normal Inorder traversal. See following post
// http://www.geeksforgeeks.org/inorder-tree-traversal-without-
recursion/
while (done1 == false)
{
if (curr1 != NULL)
{
push(s1, curr1);
curr1 = curr1->left;
}
else
{
if (isEmpty(s1))
done1 = 1;
else
{
curr1 = pop(s1);
val1 = curr1->val;
curr1 = curr1->right;
done1 = 1;
}
}
}
// If we find a pair, then print the pair and return. The first
// condition makes sure that two same values are not added
if ((val1 != val2) && (val1 + val2) == target)
{
printf("\n Pair Found: %d + %d = %d\n", val1, val2, target);
return true;
}
getchar();
return 0;
}
Output:
Pair Found: 8 + 25 = 33
Post navigation
Find if there is a triplet in a Balanced BST that adds to zero Reverse Level Order
Traversal
Writing code in comment? Please use code.geeksforgeeks.org, generate link and share the
link here.
Example Tree
Reverse Level order traversal of the above tree is 4 5 2 3 1.
Both methods for normal level order traversal can be easily modified to do reverse level
order traversal.
METHOD 1 (Recursive function to print a given level)
We can easily modify the method 1 of the normal level order traversal. In method 1, we
have a method printGivenLevel() which prints a given level number. The only thing we
need to change is, instead of calling printGivenLevel() from first level to last level, we call it
from last level to first level.
// A recursive C program to print REVERSE level order traversal
#include <stdio.h>
#include <stdlib.h>
/* A binary tree node has data, pointer to left and right child */
struct node
{
int data;
struct node* left;
struct node* right;
};
/*Function protoypes*/
void printGivenLevel(struct node* root, int level);
int height(struct node* node);
struct node* newNode(int data);
return(node);
}
return 0;
}
Output:
Level Order traversal of binary tree is
4 5 2 3 1
Time Complexity: The worst case time complexity of this method is O(n^2). For a skewed
tree, printGivenLevel() takes O(n) time where n is the number of nodes in the skewed tree.
So time complexity of printLevelOrder() is O(n) + O(n-1) + O(n-2) + .. + O(1) which is
O(n^2).
METHOD 2 (Using Queue and Stack)
The method 2 of normal level order traversal can also be easily modified to print level
order traversal in reverse order. The idea is to use a stack to get the reverse level order. If
we do normal level order traversal and instead of printing a node, push the node to a stack
and then print contents of stack, we get 5 4 3 2 1 for above example tree, but output
should be 4 5 2 3 1. So to get the correct sequence (left to right at every level), we process
children of a node in reverse order, we first push the right subtree to stack, then left
subtree.
// A C++ program to print REVERSE level order traversal using stack and queue
// This approach is adopted from following link
// http://tech-queries.blogspot.in/2008/12/level-order-tree-traversal-in-
reverse.html
#include <iostream>
#include <stack>
#include <queue>
using namespace std;
/* A binary tree node has data, pointer to left and right children */
struct node
{
int data;
struct node* left;
struct node* right;
};
// Now pop all items from stack one by one and print them
while (S.empty() == false)
{
root = S.top();
cout << root->data << " ";
S.pop();
}
}
return (temp);
}
return 0;
}
Output:
Level Order traversal of binary tree is
4 5 6 7 2 3 1
Time Complexity: O(n) where n is number of nodes in the binary tree.
Please write comments if you find any bug in the above programs/algorithms or other
ways to solve the same problem.
Source
http://www.geeksforgeeks.org/reverse-level-order-traversal/
We are mainly given level order traversal in sequential access form. We know head of
linked list is always is root of the tree. We take the first node as root and we also know that
the next two nodes are left and right children of root. So we know partial Binary Tree. The
idea is to do Level order traversal of the partially built Binary Tree using queue and
traverse the linked list at the same time. At every step, we take the parent node from queue,
make next two nodes of linked list as children of the parent node, and enqueue the next
two nodes to queue.
1. Create an empty queue.
2. Make the first node of the list as root, and enqueue it to the queue.
3. Until we reach the end of the list, do the following.
a. Dequeue one node from the queue. This is the current parent.
b. Traverse two nodes in the list, add them as children of the current parent.
c. Enqueue the two nodes into the queue.
Below is the code which implements the same in C++.
// C++ program to create a Complete Binary tree from its Linked List
// Representation
#include <iostream>
#include <string>
#include <queue>
using namespace std;
// method to create a new binary tree node from the given data
BinaryTreeNode* newBinaryTreeNode(int data)
{
BinaryTreeNode *temp = new BinaryTreeNode;
temp->data = data;
temp->left = temp->right = NULL;
return temp;
}
// converts a given linked list representing a complete binary tree into the
// linked representation of binary tree.
void convertList2Binary(ListNode *head, BinaryTreeNode* &root)
{
// queue to store the parent nodes
queue<BinaryTreeNode *> q;
// Base Case
if (head == NULL)
{
root = NULL; // Note that root is passed by reference
return;
}
// 1.) The first node is always the root node, and add it to the queue
root = newBinaryTreeNode(head->data);
q.push(root);
// 2.c) take next two nodes from the linked list. We will add
// them as children of the current parent node in step 2.b. Push them
// into the queue so that they will be parents to the future nodes
BinaryTreeNode *leftChild = NULL, *rightChild = NULL;
leftChild = newBinaryTreeNode(head->data);
q.push(leftChild);
head = head->next;
if (head)
{
rightChild = newBinaryTreeNode(head->data);
q.push(rightChild);
head = head->next;
}
BinaryTreeNode *root;
convertList2Binary(head, root);
cout << "Inorder Traversal of the constructed Binary Tree is: \n";
inorderTraversal(root);
return 0;
}
Output:
Inorder Traversal of the constructed Binary Tree is:
25 12 30 10 36 15
Time Complexity: Time complexity of the above solution is O(n) where n is the number of
nodes.
This article is compiled by Ravi Chandra Enaganti. Please write comments if you find
anything incorrect, or you want to share more information about the topic discussed above.
Source
http://www.geeksforgeeks.org/given-linked-list-representation-of-complete-tree-convert-
it-to-linked-representation/
Category: Trees Tags: Queue
// Resmoves all nodes having value outside the given range and returns the
root
// of modified tree
node* removeOutsideRange(node *root, int min, int max)
{
// Base Case
if (root == NULL)
return NULL;
// Now fix the root. There are 2 possible cases for toot
// 1.a) Root's key is smaller than min value (root is not in range)
if (root->key < min)
{
node *rChild = root->right;
delete root;
return rChild;
}
// 1.b) Root's key is greater than max value (root is not in range)
if (root->key > max)
{
node *lChild = root->left;
delete root;
return lChild;
}
// 2. Root is in range
return root;
}
// A utility function to create a new BST node with key as given num
node* newNode(int num)
{
node* temp = new node;
temp->key = num;
temp->left = temp->right = NULL;
return temp;
}
return 0;
}
Output:
Inorder traversal of the given tree is: -13 -8 6 7 13 14 15
Inorder traversal of the modified tree is: -8 6 7 13
Source
http://www.geeksforgeeks.org/remove-bst-keys-outside-the-given-range/
Category: Trees
I came across this interview during one of my interviews. A similar problem is discussed in
this post. The problem here is simpler as we dont need to create circular DLL, but a simple
DLL. The idea behind its solution is quite simple and straight.
1. If left subtree exists, process the left subtree
..1.a) Recursively convert the left subtree to DLL.
..1.b) Then find inorder predecessor of root in left subtree (inorder predecessor is
rightmost node in left subtree).
..1.c) Make inorder predecessor as previous of root and root as next of inorder
predecessor.
2. If right subtree exists, process the right subtree (Below 3 steps are similar to left
subtree).
..2.a) Recursively convert the right subtree to DLL.
..2.b) Then find inorder successor of root in right subtree (inorder successor is leftmost
node in right subtree).
..2.c) Make inorder successor as next of root and root as previous of inorder successor.
3. Find the leftmost node and return it (the leftmost node is always head of converted
DLL).
Below is the source code for above algorithm.
/* A binary tree node has data, and left and right pointers */
struct node
{
int data;
node* left;
node* right;
};
/* This is the core function to convert Tree to list. This function follows
steps 1 and 2 of the above algorithm */
node* bintree2listUtil(node* root)
{
// Base case
if (root == NULL)
return root;
return root;
}
// The main function that first calls bintree2listUtil(), then follows step 3
// of the above algorithm
node* bintree2list(node *root)
{
// Base case
if (root == NULL)
return root;
return (root);
}
// Convert to DLL
node *head = bintree2list(root);
return 0;
}
Output:
25 12 30 10 36 15
This article is compiled by Ashish Mangla and reviewed by GeeksforGeeks team. Please
write comments if you find anything incorrect, or you want to share more information
about the topic discussed above.
You may also like to see Convert a given Binary Tree to Doubly Linked List | Set 2 for
another simple and efficient solution.
Source
http://www.geeksforgeeks.org/in-place-convert-a-given-binary-tree-to-doubly-linked-
list/
Category: Trees
Search
Search is similar to search in Binary Search Tree. Let the key to be searched be k. We start
from root and recursively traverse down. For every visited non-leaf node, if the node has
key, we simply return the node. Otherwise we recur down to the appropriate child (The
child which is just before the first greater key) of the node. If we reach a leaf node and dont
find k in the leaf node, we return NULL.
Traverse
Traversal is also similar to Inorder traversal of Binary Tree. We start from the leftmost
child, recursively print the leftmost child, then repeat the same process for remaining
children and keys. In the end, recursively print the rightmost child.
// A BTree node
class BTreeNode
{
int *keys; // An array of keys
int t; // Minimum degree (defines the range for number of keys)
BTreeNode **C; // An array of child pointers
int n; // Current number of keys
bool leaf; // Is true when node is leaf. Otherwise false
public:
BTreeNode(int _t, bool _leaf); // Constructor
// Make BTree friend of this so that we can access private members of this
// class in BTree functions
friend class BTree;
};
// A BTree
class BTree
{
BTreeNode *root; // Pointer to root node
int t; // Minimum degree
public:
// Constructor (Initializes tree as empty)
BTree(int _t)
{ root = NULL; t = _t; }
The above code doesnt contain driver program. We will be covering the complete program
in our next post on B-Tree Insertion.
There are two conventions to define a B-Tree, one is to define by minimum degree
(followed in Cormen book), second is define by order. We have followed the minimum
degree convention and will be following same in coming posts on B-Tree. The variable
names used in the above program are also kept same as Cormen book for better
readability.
Insertion and Deletion
B-Tree Insertion
B-Tree Deletion
References:
Introduction to Algorithms 3rd Edition by Clifford Stein, Thomas H. Cormen, Charles E.
Leiserson, Ronald L. Rivest
Please write comments if you find anything incorrect, or you want to share more
information about the topic discussed above.
Source
http://www.geeksforgeeks.org/b-tree-set-1-introduction-2/
As discussed above, to insert a new key, we go down from root to leaf. Before traversing
down to a node, we first check if the node is full. If the node is full, we split it to create
space. Following is complete algorithm.
Insertion
1) Initialize x as root.
2) While x is not leaf, do following
..a) Find the child of x that is going to to be traversed next. Let the child be y.
..b) If y is not full, change x to point to y.
..c) If y is full, split it and change x to point to one of the two parts of y. If k is smaller than
mid key in y, then set x as first part of y. Else second part of y. When we split y, we move a
key from y to its parent x.
3) The loop in step 2 stops when x is leaf. x must have space for 1 extra key as we have
been splitting all nodes in advance. So simply insert k to x.
Note that the algorithm follows the Cormen book. It is actually a proactive insertion
algorithm where before going down to a node, we split it if it is full. The advantage of
splitting before is, we never traverse a node twice. If we dont split a node before going
down to it and split it only if new key is inserted (reactive), we may end up traversing all
nodes again from leaf to root. This happens in cases when all nodes on the path from root
to leaf are full. So when we come to the leaf node, we split it and move a key up. Moving a
key up will cause a split in parent node (because parent was already full). This cascading
effect never happens in this proactive insertion algorithm. There is a disadvantage of this
proactive insertion though, we may do unnecessary splits.
Let us understand the algorithm with an example tree of minimum degree t as 3 and a
sequence of integers 10, 20, 30, 40, 50, 60, 70, 80 and 90 in an initially empty B-Tree.
Initially root is NULL. Let us first insert 10.
Let us now insert 20, 30, 40 and 50. They all will be inserted in root because maximum
number of keys a node can accommodate is 2*t 1 which is 5.
Let us now insert 60. Since root node is full, it will first split into two, then 60 will be
inserted into the appropriate child.
Let us now insert 70 and 80. These new keys will be inserted into the appropriate leaf
without any split.
Let us now insert 90. This insertion will cause a split. The middle key will go up to the
parent.
// A BTree node
class BTreeNode
{
int *keys; // An array of keys
int t; // Minimum degree (defines the range for number of keys)
BTreeNode **C; // An array of child pointers
int n; // Current number of keys
bool leaf; // Is true when node is leaf. Otherwise false
public:
BTreeNode(int _t, bool _leaf); // Constructor
// Make BTree friend of this so that we can access private members of this
// class in BTree functions
friend class BTree;
};
// A BTree
class BTree
{
BTreeNode *root; // Pointer to root node
int t; // Minimum degree
public:
// Constructor (Initializes tree as empty)
BTree(int _t)
{ root = NULL; t = _t; }
// Split the old root and move 1 key to the new root
s->splitChild(0, root);
// Change root
root = s;
}
else // If root is not full, call insertNonFull for root
root->insertNonFull(k);
}
}
int k = 6;
(t.search(k) != NULL)? cout << "\nPresent" : cout << "\nNot Present";
k = 15;
(t.search(k) != NULL)? cout << "\nPresent" : cout << "\nNot Present";
return 0;
}
Output:
Traversal of the constucted tree is 5 6 7 10 12 17 20 30
Present
Not Present
References:
Introduction to Algorithms 3rd Edition by Clifford Stein, Thomas H. Cormen, Charles E.
Leiserson, Ronald L. Rivest
http://www.cs.utexas.edu/users/djimenez/utsa/cs3343/lecture17.html
Please write comments if you find anything incorrect, or you want to share more
information about the topic discussed above.
Source
http://www.geeksforgeeks.org/b-tree-set-1-insert-2/
Solution
We build a Trie of all dictionary words. Once the Trie is built, traverse through it using
characters of input string. If prefix matches a dictionary word, store current length and
look for a longer match. Finally, return the longest match.
Following is Java implementation of the above solution based.
import java.util.HashMap;
// The main method that finds out the longest string 'input'
public String getMatchingPrefix(String input) {
String result = ""; // Initialize resultant string
int length = input.length(); // Find length of the input string
// Testing class
public class Test {
public static void main(String[] args) {
Trie dict = new Trie();
dict.insert("are");
dict.insert("area");
dict.insert("base");
dict.insert("cat");
dict.insert("cater");
dict.insert("basement");
input = "basement";
System.out.print(input + ": ");
System.out.println(dict.getMatchingPrefix(input));
input = "are";
System.out.print(input + ": ");
System.out.println(dict.getMatchingPrefix(input));
input = "arex";
System.out.print(input + ": ");
System.out.println(dict.getMatchingPrefix(input));
input = "basemexz";
System.out.print(input + ": ");
System.out.println(dict.getMatchingPrefix(input));
input = "xyz";
System.out.print(input + ": ");
System.out.println(dict.getMatchingPrefix(input));
}
}
Output:
caterer: cater
basement: basement
are: are
arex: are
basemexz: base
xyz:
Time Complexity: Time complexity of finding the longest prefix is O(n) where n is length of
the input string. Refer thisfor time complexity of building the Trie.
This article is compiled by Ravi Chandra Enaganti. Please write comments if you find
anything incorrect, or you want to share more information about the topic discussed above
Source
http://www.geeksforgeeks.org/longest-prefix-matching-a-trie-based-solution-in-java/
Category: Trees Tags: Advance Data Structures, Java
Tree Isomorphism Problem
Write a function to detect if two trees are isomorphic. Two trees are called isomorphic if
one of them can be obtained from other by a series of flips, i.e. by swapping left and right
children of a number of nodes. Any number of nodes at any level can have their children
swapped. Two empty trees are isomorphic.
For example, following two trees are isomorphic with following sub-trees flipped: 2 and 3,
NULL and 6, 7 and 8.
We simultaneously traverse both trees. Let the current internal nodes of two trees being
traversed be n1 and n2 respectively. There are following two conditions for subtrees
rooted with n1 and n2 to be isomorphic.
1) Data of n1 and n2 is same.
2) One of the following two is true for children of n1 and n2
a) Left child of n1 is isomorphic to left child of n2 and right child of n1 is isomorphic to
right child of n2.
b) Left child of n1 is isomorphic to right child of n2 and right child of n1 is isomorphic
to left child of n2.
/* A binary tree node has data, pointer to left and right children */
struct node
{
int data;
struct node* left;
struct node* right;
};
if (n1->data != n2->data)
return false;
return (temp);
}
return 0;
}
Output:
Yes
Time Complexity: The above solution does a traversal of both trees. So time complexity is
O(m + n) where m and n are number of nodes in given trees.
This article is contributed by Ciphe. Please write comments if you find anything incorrect,
or you want to share more information about the topic discussed above.
If you like GeeksforGeeks and would like to contribute, you can also write an article and
mail your article to contribute@geeksforgeeks.org. See your article appearing on the
GeeksforGeeks main page and help other Geeks.
Source
http://www.geeksforgeeks.org/tree-isomorphism-problem/
Category: Trees
Input: {1, 1}
Output: ("aa", 'k")
[2 interpretations: aa(1, 1), k(11)]
Input: {1, 2, 1}
Output: ("aba", "au", "la")
[3 interpretations: aba(1,2,1), au(1,21), la(12,1)]
Input: {9, 1, 8}
Output: {"iah", "ir"}
[2 interpretations: iah(9,1,8), ir(9,18)]
Please note we cannot change order of array. That means {1,2,1} cannot become {2,1,1}
On first look it looks like a problem of permutation/combination. But on closer look you
will figure out that this is an interesting tree problem.
The idea here is string can take at-most two paths:
1. Proces single digit
2. Process two digits
That means we can use binary tree here. Processing with single digit will be left child and
two digits will be right child. If value two digits is greater than 26 then our right child will
be null as we dont have alphabet for greater than 26.
Lets understand with an example .Array a = {1,2,1}. Below diagram shows that how our
tree grows.
Braces {} contain array still pending for processing. Note that with every level, our array
size decreases. If you will see carefully, it is not hard to find that tree height is always n
(array size)
How to print all strings (interpretations)? Output strings are leaf node of tree. i.e for
{1,2,1}, output is {aba au la}.
We can conclude that there are mainly two steps to print all interpretations of given
integer array.
Step 1: Create a binary tree with all possible interpretations in leaf nodes.
Step 2: Print all leaf nodes from the binary tree created in step 1.
Following is Java implementation of above algorithm.
String dataString;
Node left;
Node right;
Node(String dataString) {
this.dataString = dataString;
//Be default left and right child are null.
}
// left child
root.left = createTree(data, dataToStr, newArr);
printleaf(root.left);
printleaf(root.right);
}
// bf(2,6) z(26)
int[] arr3 = {2, 6};
printAllInterpretations(arr3);
// ab(1,2), l(12)
int[] arr4 = {1, 2};
printAllInterpretations(arr4);
// a(1,0} j(10)
int[] arr5 = {1, 0};
printAllInterpretations(arr5);
Output:
aacd amd kcd
aaa ak ka
bf z
ab l
a j
Exercise:
1. What is the time complexity of this solution? [Hint : size of tree + finding leaf nodes]
2. Can we store leaf nodes at the time of tree creation so that no need to run loop again for
leaf node fetching?
3. How can we reduce extra space?
This article is compiled by Varun Jain. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above
Source
http://www.geeksforgeeks.org/find-all-possible-interpretations/
Category: Trees Tags: Facebook
Post navigation
Expression Evaluation Microsoft Interview | Set 19
Writing code in comment? Please use code.geeksforgeeks.org, generate link and share the
link here.
Example Tree
Recursive method to find height of Binary Tree is discussed here. How to find height
without recursion? We can use level order traversal to find height without recursion. The
idea is to traverse level by level. Whenever move down to a level, increment height by 1
(height is initialized as 0). Count number of nodes at each level, stop traversing when count
of nodes at next level is 0.
Following is detailed algorithm to find level order traversal using queue.
Create a queue.
Push root into the queue.
height = 0
Loop
nodeCount = size of queue
height++;
Output:
Height of tree is 3
Source
http://www.geeksforgeeks.org/iterative-method-to-find-height-of-binary-tree/
Category: Trees
Print the tree that would form when each pair of these links that has the same character as
start and end point is joined together. You have to maintain fidelity w.r.t. the height of
nodes, i.e. nodes at height n from root should be printed at same row or column. For set of
links given above, tree printed should be
-->a
|-->b
| |-->c
| |-->d
|-->e
Note that these links need not form a single tree; they could form, ahem, a forest. Consider
the following links
a ---> b
a ---> g
b ---> c
c ---> d
d ---> e
c ---> f
z ---> y
y ---> x
x ---> w
-->z
|-->y
| |-->x
| | |-->w
You can assume that given links can form a tree or forest of trees only, and there are no
duplicates among links.
Solution: The idea is to maintain two arrays, one array for tree nodes and other for trees
themselves (we call this array forest). An element of the node array contains the TreeNode
object that corresponds to respective character. An element of the forest array contains
Tree object that corresponds to respective root of tree.
It should be obvious that the crucial part is creating the forest here, once it is created,
printing it out in required format is straightforward. To create the forest, following
procedure is used
It should be clear that this procedure runs in linear time in number of nodes as well as of
links it makes only one pass over the links. It also requires linear space in terms of
alphabet size.
Following is Java implementation of above algorithm. In the following implementation
characters are assumed to be only lower case characters from a to z.
// The main class that represents tree and has main method
public class Tree {
// Constructor
public Tree(TreeNode root) { this.root = root; }
String [] links2 = {"a b", "a g", "b c", "c d", "d e", "c f",
"z y", "y x", "x w"};
System.out.println("------------ Forest 2 ----------------");
printForest(links2);
}
}
// Constructor
public TreeNode(char c) { this.c = c; this.children = new TreeNode[26];}
Output:
-->z
|-->y
| |-->x
| | |-->w
Exercise:
In the above implementation, endpoints of input links are assumed to be from set of only
26 characters. Extend the implementation where endpoints are strings of any length.
This article is contributed by Ciphe. Please write comments if you find anything incorrect,
or you want to share more information about the topic discussed above
Source
http://www.geeksforgeeks.org/custom-tree-problem/
Check for Identical BSTs without building the trees
Given two arrays which represent a sequence of keys. Imagine we make a Binary Search
Tree (BST) from each array. We need to tell whether two BSTs will be identical or not
without actually constructing the tree.
Examples
For example, the input arrays are {2, 4, 3, 1} and {2, 1, 4, 3} will construct the same tree
Let the input arrays be a[] and b[]
Example 1:
a[] = {2, 4, 1, 3} will construct following tree.
2
/ \
1 4
/
3
b[] = {2, 4, 3, 1} will also also construct the same tree.
2
/ \
1 4
/
3
So the output is "True"
Example 2:
a[] = {8, 3, 6, 1, 4, 7, 10, 14, 13}
b[] = {8, 10, 14, 3, 6, 4, 1, 7, 13}
Solution:
According to BST property, elements of left subtree must be smaller and elements of right
subtree must be greater than root.
Two arrays represent sane BST if for every element x, the elements in left and right
subtrees of x appear after it in both arrays. And same is true for roots of left and right
subtrees.
The idea is to check of if next smaller and greater elements are same in both arrays. Same
properties are recursively checked for left and right subtrees. The idea looks simple, but
implementation requires checking all conditions for all elements. Following is an
interesting recursive implementation of the idea.
/* The main function that checks if two arrays a[] and b[] of size n
construct
same BST. The two values 'min' and 'max' decide whether the call is made
for
left subtree or right subtree of a parent element. The indexes i1 and i2
are
the indexes in (a[] and b[]) after which we search the left or right child.
Initially, the call is made for INT_MIN and INT_MAX as 'min' and 'max'
respectively, because root has no parent.
i1 and i2 are just after the indexes of the parent element in a[] and b[].
*/
bool isSameBSTUtil(int a[], int b[], int n, int i1, int i2, int min, int max)
{
int j, k;
/* Search for a value satisfying the constraints of min and max in a[] and
b[]. If the parent element is a leaf node then there must be some
elements in a[] and b[] satisfying constraint. */
for (j=i1; j<n; j++)
if (a[j]>min && a[j]<max)
break;
for (k=i2; k<n; k++)
if (b[k]>min && b[k]<max)
break;
/* Make the current child as parent and recursively check for left and
right
subtrees of it. Note that we can also pass a[k] in place of a[j] as
they
are both are same */
return isSameBSTUtil(a, b, n, j+1, k+1, a[j], max) && // Right Subtree
isSameBSTUtil(a, b, n, j+1, k+1, min, a[j]); // Left Subtree
}
Output:
BSTs are same
This article is compiled byAmit Jain. Please write comments if you find anything incorrect,
or you want to share more information about the topic discussed above
Source
http://www.geeksforgeeks.org/check-for-identical-bsts-without-building-the-trees/
Category: Trees
Post navigation
Dynamic Programming | Set 33 (Find if a string is interleaved of two other strings) Can
we Overload or Override static methods in java ?
Writing code in comment? Please use code.geeksforgeeks.org, generate link and share the
link here.
Convert a given Binary Tree to Doubly Linked List | Set 2
Given a Binary Tree (BT), convert it to a Doubly Linked List(DLL). 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.
// A tree node
struct node
{
int data;
struct node *left, *right;
};
if (root != NULL)
{
fixPrevPtr(root->left);
root->left = pre;
pre = root;
fixPrevPtr(root->right);
}
}
// Start from the rightmost node, traverse back using left pointers.
// While traversing, change right pointer of nodes.
while (root && root->left != NULL)
{
prev = root;
root = root->left;
root->right = prev;
}
// The main function that converts BST to DLL and returns head of DLL
struct node *BTToDLL(struct node *root)
{
// Set the previous pointer
fixPrevPtr(root);
printf("\n\n\t\tDLL Traversal\n\n");
printList(head);
return 0;
}
Output:
25 12 30 10 36 15
DLL Traversal
25 12 30 10 36 15
Time Complexity: O(n) where n is the number of nodes in given Binary Tree. The solution
simply does two traversals of all Binary Tree nodes.
This article is contributed by Bala. Please write comments if you find anything incorrect, or
you want to share more information about the topic discussed above
Source
http://www.geeksforgeeks.org/convert-a-given-binary-tree-to-doubly-linked-list-set-2/
Category: Trees
1
/ \
2 3
/ \ / \
4 5 6 7
/ \ /
8 9 10
Following are different input keys and their ancestors in the above tree
// Traverse the complete tree in postorder way till we find the key
while (1)
{
// Traverse the left side. While traversing, push the nodes into
// the stack so that their right subtrees can be traversed later
while (root && root->data != key)
{
push(stack, root); // push current node
root = root->left; // move to next node
}
// If the popped node is right child of top, then remove the top
// as well. Left child of the top must have processed before.
// Consider the following tree for example and key = 3. If we
// remove the following loop, the program will go in an
// infinite loop after reaching 5.
// 1
// / \
// 2 3
// \
// 4
// \
// 5
while (!isEmpty(stack) && peek(stack)->right == root)
root = pop(stack);
}
// if stack is not empty then simply set the root as right child
// of top and start traversing right sub-tree.
root = isEmpty(stack)? NULL: peek(stack)->right;
}
getchar();
return 0;
}
Output:
Following are all keys and their ancestors
1:
2: 1
3: 1
4: 2 1
5: 2 1
6: 3 1
7: 3 1
8: 4 2 1
9: 5 2 1
10: 7 3 1
Exercise
Note that the above solution assumes that the given key is present in the given Binary
Tree. It may go in infinite loop if key is not present. Extend the above solution to work even
when the key is not present in tree.
This article is contrubuted byChandra Prakash. Please write comments if you find
anything incorrect, or you want to share more information about the topic discussed above.
Source
http://www.geeksforgeeks.org/print-ancestors-of-a-given-binary-tree-node-without-
recursion/
Category: Trees Tags: stack, StackAndQueue
5
/ \
2 6
/ \ \
1 4 8
/ / \
3 7 9
A straightforward method is to use level order traversal. In the traversal, check level of
current node, if it is odd, increment odd sum by data of current node, otherwise increment
even sum. Finally return difference between odd sum and even sum. See following for
implementation of this approach.
C implementation of level order traversal based approach to find the difference.
The problem can also be solved using simple recursive traversal. We can recursively
calculate the required difference as, value of roots data subtracted by the difference for
subtree under left child and the difference for subtree under right child. Following is C
implementation of this approach.
// The main function that return difference between odd and even level
// nodes
int getLevelDiff(struct node *root)
{
// Base case
if (root == NULL)
return 0;
Output:
-9 is the required difference
Time complexity of both methods is O(n), but the second method is simple and easy to
implement.
This article is contributed by Chandra Prakash. Please write comments if you find
anything incorrect, or you want to share more information about the topic discussed above.
Source
http://www.geeksforgeeks.org/difference-between-sums-of-odd-and-even-levels/
Category: Trees
Input:
Inorder traversal in[] = {4, 2, 5, 1, 3, 6}
Preorder traversal pre[] = {1, 2, 4, 5, 3, 6}
Output:
Postorder traversal is {4, 5, 2, 6, 3, 1}
1
/ \
2 3
/ \ \
4 5 6
A naive method is to first construct the tree, then use simple recursive method to print
postorder traversal of the constructed tree.
We can print postorder traversal without constructing the tree. The idea is, root is
always the first item in preorder traversal and it must be the last item in postorder
traversal. We first recursively print left subtree, then recursively print right subtree.
Finally, print root. To find boundaries of left and right subtrees in pre[] and in[], we search
root in in[], all elements before root in in[] are elements of left subtree and all elements
after root are elements of right subtree. In pre[], all elements after index of root in in[] are
elements of right subtree. And elements before index (including the element at index and
excluding the first element) are elements of left subtree.
// Print root
cout << pre[0] << " ";
}
// Driver program to test above functions
int main()
{
int in[] = {4, 2, 5, 1, 3, 6};
int pre[] = {1, 2, 4, 5, 3, 6};
int n = sizeof(in)/sizeof(in[0]);
cout << "Postorder traversal " << endl;
printPostOrder(in, pre, n);
return 0;
}
Output
Postorder traversal
4 5 2 6 3 1
Time Complexity: The above function visits every node in array. For every visit, it calls
search which takes O(n) time. Therefore, overall time complexity of the function is O(n2)
Please write comments if you find anything incorrect, or you want to share more
information about the topic discussed above
Source
http://www.geeksforgeeks.org/print-postorder-from-given-inorder-and-preorder-
traversals/
Category: Trees
Post navigation
NP-Completeness | Set 1 (Introduction) Morgan Stanley Interview | Set 3
Writing code in comment? Please use code.geeksforgeeks.org, generate link and share the
link here.
1
/ \
2 3
/ / \
4 5 6
\ \
7 8
/ \
9 10
/
11
We strongly recommend you to minimize the browser and try this yourself first.
The idea is to recursively traverse the given binary tree and while traversing, maintain a
variable level which will store the current nodes level in the tree. If current node is leaf
then check level is odd or not. If level is odd then return it. If current node is not leaf, then
recursively find maximum depth in left and right subtrees, and return maximum of the two
depths.
// If this node is a leaf and its level is odd, return its level
if (root->left==NULL && root->right==NULL && level&1)
return level;
// If not leaf, return the maximum value from left and right subtrees
return max(depthOfOddLeafUtil(root->left, level+1),
depthOfOddLeafUtil(root->right, level+1));
}
/* Main function which calculates the depth of deepest odd level leaf.
This function mainly uses depthOfOddLeafUtil() */
int depthOfOddLeaf(struct Node *root)
{
int level = 1, depth = 0;
return depthOfOddLeafUtil(root, level);
}
Output:
5 is the required depth
Time Complexity: The function does a simple traversal of the tree, so the complexity is
O(n).
This article is contributed by Chandra Prakash. Please write comments if you find
anything incorrect, or you want to share more information about the topic discussed above.
Source
http://www.geeksforgeeks.org/find-depth-of-the-deepest-odd-level-node/
Category: Trees
12
/ \
5 7
/ \
3 1
Leaves are at same level
12
/ \
5 7
/
3
Leaves are Not at same level
12
/
5
/ \
3 9
/ /
1 2
Leaves are at same level
We strongly recommend you to minimize the browser and try this yourself first.
The idea is to first find level of the leftmost leaf and store it in a variable leafLevel. Then
compare level of all other leaves with leafLevel, if same, return true, else return false. We
traverse the given Binary Tree in Preorder fashion. An argument leaflevel is passed to all
calls. The value of leafLevel is initialized as 0 to indicate that the first leaf is not yet seen
yet. The value is updated when we find first leaf. Level of subsequent leaves (in preorder) is
compared with leafLevel.
/* Recursive function which checks whether all leaves are at same level */
bool checkUtil(struct Node *root, int level, int *leafLevel)
{
// Base case
if (root == NULL) return true;
// If this node is not leaf, recursively check left and right subtrees
return checkUtil(root->left, level+1, leafLevel) &&
checkUtil(root->right, level+1, leafLevel);
}
/* The main function to check if all leafs are at same level.
It mainly uses checkUtil() */
bool check(struct Node *root)
{
int level = 0, leafLevel = 0;
return checkUtil(root, level, &leafLevel);
}
Output:
Leaves are at same level
Time Complexity: The function does a simple traversal of the tree, so the complexity is
O(n).
This article is contributed by Chandra Prakash. Please write comments if you find
anything incorrect, or you want to share more information about the topic discussed above.
Source
http://www.geeksforgeeks.org/check-leaves-level/
Category: Trees
Print Left View of a Binary Tree
Given a Binary Tree, print left view of it. Left view of a Binary Tree is set of nodes visible
when tree is visited from left side. Left view of following tree is 12, 10, 25.
12
/ \
10 30
/ \
25 40
The left view contains all nodes that are first nodes in their levels. A simple solution is to do
level order traversal and print the first node in every level.
The problem can also be solved using simple recursive traversal. We can keep track of
level of a node by passing a parameter to all recursive calls. The idea is to keep track of
maximum level also. Whenever we see a node whose level is more than maximum level so
far, we print the node because this is the first node in its level (Note that we traverse the
left subtree before right subtree). Following is C implementation of this approach.
struct node
{
int data;
struct node *left, *right;
};
leftView(root);
return 0;
}
Output:
12 10 25
Time Complexity: The function does a simple traversal of the tree, so the complexity is
O(n).
This article is contributed by Ramsai Chinthamani. Please write comments if you find
anything incorrect, or you want to share more information about the topic discussed above
Source
http://www.geeksforgeeks.org/print-left-view-binary-tree/
Category: Trees
B-Tree | Set 3 (Delete)
It is recommended to refer following posts as prerequisite of this post.
B-Tree | Set 1 (Introduction)
B-Tree | Set 2 (Insert)
B-Tree is a type of a multi-way search tree. So, if you are not familiar with multi-way search
trees in general, it is better to take a look at this video lecture from IIT-Delhi, before
proceeding further. Once you get the basics of a multi-way search tree clear, B-Tree
operations will be easier to understand.
Source of the following explanation and algorithm is Introduction to Algorithms 3rd
Edition by Clifford Stein, Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest
Deletion process:
Deletion from a B-tree is more complicated than insertion, because we can delete a key
from any node-not just a leafand when we delete a key from an internal node, we will
have to rearrange the nodes children.
As in insertion, we must make sure the deletion doesnt violate the B-tree properties. Just
as we had to ensure that a node didnt get too big due to insertion, we must ensure that a
node doesnt get too small during deletion (except that the root is allowed to have fewer
than the minimum number t-1 of keys). Just as a simple insertion algorithm might have to
back up if a node on the path to where the key was to be inserted was full, a simple
approach to deletion might have to back up if a node (other than the root) along the path to
where the key is to be deleted has the minimum number of keys.
The deletion procedure deletes the key k from the subtree rooted at x. This procedure
guarantees that whenever it calls itself recursively on a node x, the number of keys in x is at
least the minimum degree t . Note that this condition requires one more key than the
minimum required by the usual B-tree conditions, so that sometimes a key may have to be
moved into a child node before recursion descends to that child. This strengthened
condition allows us to delete a key from the tree in one downward pass without having to
back up (with one exception, which well explain). You should interpret the following
specification for deletion from a B-tree with the understanding that if the root node x ever
becomes an internal node having no keys (this situation can occur in cases 2c and 3b then
we delete x, and xs only child x.c1 becomes the new root of the tree, decreasing the height
of the tree by one and preserving the property that the root of the tree contains at least one
key (unless the tree is empty).
We sketch how deletion works with various cases of deleting keys from a B-tree.
1. If the key k is in node x and x is a leaf, delete the key k from x.
2. If the key k is in node x and x is an internal node, do the following.
a) If the child y that precedes k in node x has at least t keys, then find the predecessor k0
of k in the sub-tree rooted at y. Recursively delete k0, and replace k by k0 in x. (We can find
k0 and delete it in a single downward pass.)
b) If y has fewer than t keys, then, symmetrically, examine the child z that follows k in
node x. If z has at least t keys, then find the successor k0 of k in the subtree rooted at z.
Recursively delete k0, and replace k by k0 in x. (We can find k0 and delete it in a single
downward pass.)
c) Otherwise, if both y and z have only t-1 keys, merge k and all of z into y, so that x loses
both k and the pointer to z, and y now contains 2t-1 keys. Then free z and recursively delete
k from y.
3. If the key k is not present in internal node x, determine the root x.c(i) of the appropriate
subtree that must contain k, if k is in the tree at all. If x.c(i) has only t-1 keys, execute step
3a or 3b as necessary to guarantee that we descend to a node containing at least t keys.
Then finish by recursing on the appropriate child of x.
a) If x.c(i) has only t-1 keys but has an immediate sibling with at least t keys, give x.c(i) an
extra key by moving a key from x down into x.c(i), moving a key from x.c(i) s immediate
left or right sibling up into x, and moving the appropriate child pointer from the sibling into
x.c(i).
b) If x.c(i) and both of x.c(i)s immediate siblings have t-1 keys, merge x.c(i) with one
sibling, which involves moving a key from x down into the new merged node to become the
median key for that node.
Since most of the keys in a B-tree are in the leaves, deletion operations are most often used
to delete keys from leaves. The recursive delete procedure then acts in one downward pass
through the tree, without having to back up. When deleting a key in an internal node,
however, the procedure makes a downward pass through the tree but may have to return
to the node from which the key was deleted to replace the key with its predecessor or
successor (cases 2a and 2b).
The following figures from CLRS book explain the deletion porcess.
Implementation:
Following is C++ implementation of deletion process.
The deletion function has been compartmentalized into 8 functions for ease
of understanding and clarity
In class BTree:
1) remove
Testing: The code has been tested using the B-Tree provided in the CLRS
book( included
in the main function ) along with other cases.
#include<iostream>
using namespace std;
// A BTree node
class BTreeNode
{
int *keys; // An array of keys
int t; // Minimum degree (defines the range for number of keys)
BTreeNode **C; // An array of child pointers
int n; // Current number of keys
bool leaf; // Is true when node is leaf. Otherwise false
public:
BTreeNode(int _t, bool _leaf); // Constructor
// A function that returns the index of the first key that is greater
// or equal to k
int findKey(int k);
class BTree
{
BTreeNode *root; // Pointer to root node
int t; // Minimum degree
public:
void traverse()
{
if (root != NULL) root->traverse();
}
};
// A utility function that returns the index of the first key that is
// greater than or equal to k
int BTreeNode::findKey(int k)
{
int idx=0;
while (idx<n && keys[idx] < k)
++idx;
return idx;
}
// A function to remove the key k from the sub-tree rooted with this node
void BTreeNode::remove(int k)
{
int idx = findKey(k);
// If this node is a leaf node, then the key is not present in tree
if (leaf)
{
cout << "The key "<< k <<" is does not exist in the tree\n";
return;
}
// If the child where the key is supposed to exist has less that t
keys,
// we fill that child
if (C[idx]->n < t)
fill(idx);
// If the last child has been merged, it must have merged with the
previous
// child and so we recurse on the (idx-1)th child. Else, we recurse
on the
// (idx)th child which now has atleast t keys
if (flag && idx > n)
C[idx-1]->remove(k);
else
C[idx]->remove(k);
}
return;
}
// A function to remove the idx-th key from this node - which is a leaf node
void BTreeNode::removeFromLeaf (int idx)
{
// Move all the keys after the idx-th pos one place backward
for (int i=idx+1; i<n; ++i)
keys[i-1] = keys[i];
return;
}
// A function to remove the idx-th key from this node - which is a non-leaf
node
void BTreeNode::removeFromNonLeaf(int idx)
{
int k = keys[idx];
// If both C[idx] and C[idx+1] has less that t keys,merge k and all of
C[idx+1]
// into C[idx]
// Now C[idx] contains 2t-1 keys
// Free C[idx+1] and recursively delete k from C[idx]
else
{
merge(idx);
C[idx]->remove(k);
}
return;
}
// Keep moving the left most node starting from C[idx+1] until we reach a
leaf
BTreeNode *cur = C[idx+1];
while (!cur->leaf)
cur = cur->C[0];
// A function to fill child C[idx] which has less than t-1 keys
void BTreeNode::fill(int idx)
{
// If the previous child(C[idx-1]) has more than t-1 keys, borrow a key
// from that child
if (idx!=0 && C[idx-1]->n>=t)
borrowFromPrev(idx);
// If the next child(C[idx+1]) has more than t-1 keys, borrow a key
// from that child
else if (idx!=n && C[idx+1]->n>=t)
borrowFromNext(idx);
BTreeNode *child=C[idx];
BTreeNode *sibling=C[idx-1];
// The last key from C[idx-1] goes up to the parent and key[idx-1]
// from parent is inserted as the first key in C[idx]. Thus, the loses
// sibling one key and child gains one key
// If C[idx] is not a leaf, move all its child pointers one step ahead
if (!child->leaf)
{
for(int i=child->n; i>=0; --i)
child->C[i+1] = child->C[i];
}
// Setting child's first key equal to keys[idx-1] from the current node
child->keys[0] = keys[idx-1];
child->n += 1;
sibling->n -= 1;
return;
}
BTreeNode *child=C[idx];
BTreeNode *sibling=C[idx+1];
return;
}
// Pulling a key from the current node and inserting it into (t-1)th
// position of C[idx]
child->keys[t-1] = keys[idx];
// Moving all keys after idx in the current node one step before -
// to fill the gap created by moving keys[idx] to C[idx]
for (int i=idx+1; i<n; ++i)
keys[i-1] = keys[i];
// Moving the child pointers after (idx+1) in the current node one
// step before
for (int i=idx+2; i<=n; ++i)
C[i-1] = C[i];
// Split the old root and move 1 key to the new root
s->splitChild(0, root);
// Change root
root = s;
}
else // If root is not full, call insertNonFull for root
root->insertNonFull(k);
}
}
void BTree::remove(int k)
{
if (!root)
{
cout << "The tree is empty\n";
return;
}
// If the root node has 0 keys, make its first child as the new root
// if it has a child, otherwise set root as NULL
if (root->n==0)
{
BTreeNode *tmp = root;
if (root->leaf)
root = NULL;
else
root = root->C[0];
t.insert(1);
t.insert(3);
t.insert(7);
t.insert(10);
t.insert(11);
t.insert(13);
t.insert(14);
t.insert(15);
t.insert(18);
t.insert(16);
t.insert(19);
t.insert(24);
t.insert(25);
t.insert(26);
t.insert(21);
t.insert(4);
t.insert(5);
t.insert(20);
t.insert(22);
t.insert(2);
t.insert(17);
t.insert(12);
t.insert(6);
t.remove(6);
cout << "Traversal of tree after removing 6\n";
t.traverse();
cout << endl;
t.remove(13);
cout << "Traversal of tree after removing 13\n";
t.traverse();
cout << endl;
t.remove(7);
cout << "Traversal of tree after removing 7\n";
t.traverse();
cout << endl;
t.remove(4);
cout << "Traversal of tree after removing 4\n";
t.traverse();
cout << endl;
t.remove(2);
cout << "Traversal of tree after removing 2\n";
t.traverse();
cout << endl;
t.remove(16);
cout << "Traversal of tree after removing 16\n";
t.traverse();
cout << endl;
return 0;
}
Output:
Traversal of tree constructed is
1 2 3 4 5 6 7 10 11 12 13 14 15 16 17 18 19 20 21 22 24 25 26
Traversal of tree after removing 6
1 2 3 4 5 7 10 11 12 13 14 15 16 17 18 19 20 21 22 24 25 26
Traversal of tree after removing 13
1 2 3 4 5 7 10 11 12 14 15 16 17 18 19 20 21 22 24 25 26
Traversal of tree after removing 7
1 2 3 4 5 10 11 12 14 15 16 17 18 19 20 21 22 24 25 26
Traversal of tree after removing 4
1 2 3 5 10 11 12 14 15 16 17 18 19 20 21 22 24 25 26
Traversal of tree after removing 2
1 3 5 10 11 12 14 15 16 17 18 19 20 21 22 24 25 26
Traversal of tree after removing 16
1 3 5 10 11 12 14 15 17 18 19 20 21 22 24 25 26
Post navigation
Radix Sort Dynamic Programming | Set 36 (Maximum Product Cutting)
Writing code in comment? Please use code.geeksforgeeks.org, generate link and share the
link here.
50
/ \
30 70
/ \ / \
20 40 60 80
260
/ \
330 150
/ \ / \
350 300 210 80
We strongly recommend you to minimize the browser and try this yourself first.
A simple method for solving this is to find sum of all greater values for every node. This
method would take O(n^2) time.
We can do it using a single traversal. The idea is to use following BST property. If we do
reverse Inorder traversal of BST, we get all nodes in decreasing order. We do reverse
Inorder traversal and keep track of the sum of all nodes visited so far, we add this sum to
every node.
modifyBST(root);
return 0;
}
Output
350 330 300 260 210 150 80
Source
http://www.geeksforgeeks.org/add-greater-values-every-node-given-bst/
Category: Trees
Remove all nodes which don't lie in any path with sum>= k
Given a binary tree, a complete path is defined as a path from root to a leaf. The sum of all
nodes on that path is defined as the sum of that path. Given a number K, you have to
remove (prune the tree) all nodes which dont lie in any path with sum>=k.
Note: A node can be part of multiple paths. So we have to delete it only in case when all
paths from it have sum less than K.
We strongly recommend you to minimize the browser and try this yourself first.
The idea is to traverse the tree and delete nodes in bottom up manner. While traversing the
tree, recursively calculate the sum of nodes from root to leaf node of each path. For each
visited node, checks the total calculated sum against given sum k. If sum is less than k,
then free(delete) that node (leaf node) and return the sum back to the previous node. Since
the path is from root to leaf and nodes are deleted in bottom up manner, a node is deleted
only when all of its descendants are deleted. Therefore, when a node is deleted, it must be a
leaf in the current Binary Tree.
Following is C implementation of the above approach.
#include <stdio.h>
#include <stdlib.h>
// A utility function to create a new Binary Tree node with given data
struct Node* newNode(int data)
{
struct Node* node = (struct Node*) malloc(sizeof(struct Node));
node->data = data;
node->left = node->right = NULL;
return node;
}
return root;
}
return 0;
}
Output:
Tree before truncation
8 4 13 9 15 14 2 12 5 1 6 3 10 11 7
Time Complexity: O(n), the solution does a single traversal of given Binary Tree.
A Simpler Solution:
The above code can be simplified using the fact that nodes are deleted in bottom up
manner. The idea is to keep reducing the sum when traversing down. When we reach a leaf
and sum is greater than the leafs data, then we delete the leaf. Note that deleting nodes
may convert a non-leaf node to a leaf node and if the data for the converted leaf node is less
than the current sum, then the converted leaf should also be deleted.
Thanks to vicky for suggesting this solution in below comments.
#include <stdio.h>
#include <stdlib.h>
return root;
}
return 0;
}
Output:
Tree before truncation
8 4 13 9 15 14 2 12 5 1 6 3 10 11 7
This article is contributed by Chandra Prakash. Please write comments if you find
anything incorrect, or you want to share more information about the topic discussed above.
Source
http://www.geeksforgeeks.org/remove-all-nodes-which-lie-on-a-path-having-sum-less-
than-k/
Category: Trees
Post navigation
How to make a C++ class whose objects can only be dynamically allocated? How to
change the output of printf() in main() ?
Writing code in comment? Please use code.geeksforgeeks.org, generate link and share the
link here.
Output:
Doubly Linked List
785910
Modified Tree:
1
/ \
2 3
/ \
4 6
We strongly recommend you to minimize the browser and try this yourself first.
We need to traverse all leaves and connect them by changing their left and right pointers.
We also need to remove them from Binary Tree by changing left or right pointers in parent
nodes. There can be many ways to solve this. In the following implementation, we add
leaves at the beginning of current linked list and update head of the list using pointer to
head pointer. Since we insert at the beginning, we need to process leaves in reverse order.
For reverse order, we first traverse the right subtree then the left subtree. We use return
values to update left or right pointers in parent nodes.
// Main function which extracts all leaves from given Binary Tree.
// The function returns new root of Binary Tree (Note that root may change
// if Binary Tree has only one node). The function also sets *head_ref as
// head of doubly linked list. left pointer of tree is used as prev in DLL
// and right pointer is used as next
struct Node* extractLeafList(struct Node *root, struct Node **head_ref)
{
// Base cases
if (root == NULL) return NULL;
return root;
}
Output:
Inorder Trvaersal of given Tree is:
7 4 8 2 5 1 3 9 6 10
Extracted Double Linked list is:
7 8 5 9 10
Inorder traversal of modified tree is:
4 2 1 3 6
Time Complexity: O(n), the solution does a single traversal of given Binary Tree.
This article is contributed by Chandra Prakash. Please write comments if you find
anything incorrect, or you want to share more information about the topic discussed above.
Source
http://www.geeksforgeeks.org/connect-leaves-doubly-linked-list/
Category: Trees
Deepest left leaf node in a binary tree
Given a Binary Tree, find the deepest leaf node that is left child of its parent. For example,
consider the following tree. The deepest left leaf node is the node with value 9.
1
/ \
2 3
/ / \
4 5 6
\ \
7 8
/ \
9 10
We strongly recommend you to minimize the browser and try this yourself first.
The idea is to recursively traverse the given binary tree and while traversing, maintain
level which will store the current nodes level in the tree. If current node is left leaf, then
check if its level is more than the level of deepest left leaf seen so far. If level is more then
update the result. If current node is not leaf, then recursively find maximum depth in left
and right subtrees, and return maximum of the two depths. Thanks to Coder011for
suggesting this approach.
// A C++ program to find the deepest left leaf in a given binary tree
#include <stdio.h>
#include <iostream>
using namespace std;
struct Node
{
int val;
struct Node *left, *right;
};
// Update result if this node is left leaf and its level is more
// than the maxl level of the current result
if (isLeft && !root->left && !root->right && lvl > *maxlvl)
{
*resPtr = root;
*maxlvl = lvl;
return;
}
Output:
The deepest left child is 9
Time Complexity: The function does a simple traversal of the tree, so the complexity is
O(n).
This article is contributed by Abhay Rathi. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above
Source
http://www.geeksforgeeks.org/deepest-left-leaf-node-in-a-binary-tree/
Category: Trees
10
/ \
2 6
/ \ \
8 4 5
We strongly recommend you to minimize the browser and try this yourself first.
Solution: The idea is to do level order traversal of given Binary Tree. When we find the
given key, we just check if the next node in level order traversal is of same level, if yes, we
return the next node, otherwise return NULL.
test(root, 10);
test(root, 2);
test(root, 6);
test(root, 5);
test(root, 8);
test(root, 4);
return 0;
}
Output:
No next right node found for 10
Next Right of 2 is 6
No next right node found for 6
No next right node found for 5
Next Right of 8 is 4
Next Right of 4 is 5
Time Complexity: The above code is a simple BFS traversal code which visits every
enqueue and dequeues a node at most once. Therefore, the time complexity is O(n) where n
is the number of nodes in the given binary tree.
Exercise: Write a function to find left node of a given node. If there is no node on the left
side, then return NULL.
Please write comments if you find anything incorrect, or you want to share more
information about the topic discussed above
Source
http://www.geeksforgeeks.org/find-next-right-node-of-a-given-key/
Category: Trees
y x
/ \ Zig (Right Rotation) / \
x T3 - - - - - -> T1 y
/ \
3) Node has both parent and grandparent. There can be following subcases.
........3.a) Zig-Zig and Zag-Zag Node is left child of parent and parent is
also left child of grand parent (Two right rotations) OR node is right child
of its parent and parent is also right child of grand parent (Two Left
Rotations).
Example:
The important thing to note is, the search or splay operation not only brings the searched
key to root, but also balances the BST. For example in above case, height of BST is reduced
by 1.
Implementation:
/* Helper function that allocates a new node with the given key and
NULL left and right pointers. */
struct node* newNode(int key)
{
struct node* node = (struct node*)malloc(sizeof(struct node));
node->key = key;
node->left = node->right = NULL;
return (node);
}
Output:
Preorder traversal of the modified Splay tree is
20 50 30 40 100 200
Summary
1) Splay trees have excellent locality properties. Frequently accessed items are easy to
find. Infrequent items are out of way.
2) All splay tree operations take O(Logn) time on average. Splay trees can be rigorously
shown to run in O(log n) average time per operation, over any sequence of operations
(assuming we start from an empty tree)
3) Splay trees are simpler compared to AVLand Red-Black Trees as no extra field is
required in every tree node.
4) Unlike AVL tree, a splay tree can change even with read-only operations like search.
Applications of Splay Trees
Splay trees have become the most widely used basic data structure invented in the last 30
years, because they're the fastest type of balanced search tree for many applications.
Splay trees are used in Windows NT (in the virtual memory, networking, and file system
code), the gcc compiler and GNU C++ library, the sed string editor, Fore Systems network
routers, the most popular implementation of Unix malloc, Linux loadable kernel modules,
and in much other software (Source: http://www.cs.berkeley.edu/~jrs/61b/lec/36)
We will soon be discussing insert and delete operations on splay trees.
References:
http://www.cs.berkeley.edu/~jrs/61b/lec/36
http://www.cs.cornell.edu/courses/cs3110/2009fa/recitations/rec-splay.html
http://courses.cs.washington.edu/courses/cse326/01au/lectures/SplayTrees.ppt
Please write comments if you find anything incorrect, or you want to share more
information about the topic discussed above
Source
http://www.geeksforgeeks.org/splay-tree-set-1-insert/
100 [20] 25
/ \ \ / \
50 200 50 20 50
/ insert(25) / \ insert(25) / \
40 ======> 30 100 ========> 30 100
/ 1. Splay(25) \ \ 2. insert 25 \ \
30 40 200 40 200
/
[20]
/* Helper function that allocates a new node with the given key and
NULL left and right pointers. */
struct node* newNode(int key)
{
struct node* node = (struct node*)malloc(sizeof(struct node));
node->key = key;
node->left = node->right = NULL;
return (node);
}
Output:
Preorder traversal of the modified Splay tree is
25 20 50 30 40 100 200
This article is compiled by Abhay Rathi. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above
Source
http://www.geeksforgeeks.org/splay-tree-set-2-insert-delete/
Category: Trees Tags: Advance Data Structures, Advanced Data Structures
Sum of all the numbers that are formed from root to leaf paths
Given a binary tree, where every node value is a Digit from 1-9 .Find the sum of all the
numbers which are formed from root to leaf paths.
For example consider the following Binary Tree.
6
/ \
3 5
/ \ \
2 5 4
\ /
7 4
There are 4 leaves, hence 4 root to leaf paths:
Path Number
6->3->2 632
6->3->5->7 6357
6->3->5->4 6354
6->5>4 654
Answer = 632 + 6357 + 6354 + 654 = 13997
We strongly recommend you to minimize the browser and try this yourself first.
The idea is to do a preorder traversal of the tree. In the preorder traversal, keep track of
the value calculated till the current node, let this value be val. For every node, we update
the val as val*10 plus nodes data.
struct node
{
int data;
struct node *left, *right;
};
// Returns sum of all root to leaf paths. The first parameter is root
// of current subtree, the second parameter is value of the number formed
// by nodes from root to this node
int treePathsSumUtil(struct node *root, int val)
{
// Base case
if (root == NULL) return 0;
// Update val
val = (val*10 + root->data);
Output:
Sum of all paths is 13997
Time Complexity: The above code is a simple preorder traversal code which visits every
exactly once. Therefore, the time complexity is O(n) where n is the number of nodes in the
given binary tree.
This article is contributed by Ramchand R. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above
Source
http://www.geeksforgeeks.org/sum-numbers-formed-root-leaf-paths/
Category: Trees
From the above examples, we get some idea how Red-Black trees ensure balance.
Following is an important fact about balancing in Red-Black Trees.
Every Red Black Tree with n nodes has height <= 2Log2(n+1)
This can be proved using following facts:
1) For a general Binary Tree, let k be the minimum number of nodes on all root to NULL
paths, then n >= 2k 1 (Ex. If k is 3, then n is atleast 7). This expression can also be written
as k <= 2Log2(n+1)
2) From property 4 of Red-Black trees and above claim, we can say in a Red-Black Tree
with n nodes, there is a root to leaf path with at-most Log2(n+1) black nodes.
3) From property 3 of Red-Black trees, we can claim that the number black nodes in a Red-
Black tree is at least n/2 where n is total number of nodes.
From above 2 points, we can conclude the fact that Red Black Tree with n nodes has height
<= 2Log2(n+1)
In this post, we introduced Red-Black trees and discussed how balance is ensured. The
hard part is to maintain balance when keys are added and removed. We will soon be
discussing insertion and deletion operations in coming posts on Red-Black tree.
Exercise:
1) Is it possible to have all black nodes in a Red-Black tree?
2) Draw a Red-Black Tree that is not an AVL tree structure wise?
Insertion and Deletion
Red Black Tree Insertion
Red-Black Tree Deletion
References:
Introduction to Algorithms 3rd Edition by Clifford Stein, Thomas H. Cormen, Charles E.
Leiserson, Ronald L. Rivest
http://en.wikipedia.org/wiki/Red%E2%80%93black_tree
Video Lecture on Red-Black Tree by Tim Roughgarden
MIT Video Lecture on Red-Black Tree
MIT Lecture Notes on Red Black Tree
Please write comments if you find anything incorrect, or you want to share more
information about the topic discussed above.
Source
http://www.geeksforgeeks.org/red-black-tree-set-1-introduction-2/
In the previous post, we discussed introduction to Red-Black Trees. In this post, insertion is
discussed.
InAVL tree insertion, we used rotation as a tool to do balancing after insertion caused
imbalance. In Red-Black tree, we use two tools to do balancing.
1) Recoloring
2) Rotation
We try recoloring first, if recoloring doesnt work, then we go for rotation. Following is
detailed algorithm. The algorithms has mainly two cases depending upon the color of uncle.
If uncle is red, we do recoloring. If uncle is black, we do rotations and/or recoloring.
Color of a NULL node is considered as BLACK.
Let x be the newly inserted node.
1) Perform standard BST insertion and make the color of newly inserted nodes as RED.
2) If x is root, change color of x as BLACK (Black height of complete tree increases by 1).
3) Do following if color of xs parent is not BLACK or x is not root.
.a) If xs uncle is RED (Grand parent must have been black from property 4)
..(i) Change color of parent and uncle as BLACK.
..(ii) color of grand parent as RED.
..(iii) Change x = xs grandparent, repeat steps 2 and 3 for new x.
.b) If xs uncle is BLACK, then there can be four configurations for x, xs parent (p) and
xs grandparent (g) (This is similar toAVL Tree)
..i) Left Left Case (p is left child of g and x is left child of p)
..ii) Left Right Case (p is left child of g and x is right child of p)
..iii) Right Right Case (Mirror of case a)
..iv) Right Left Case (Mirror of case c)
Following are operations to be performed in four subcases when uncle is BLACK.
All four cases when Uncle is BLACK
Left Left Case (See g, p and x)
Examples of Insertion
Exercise:
Insert 2, 7 and 13 in below tree. Insertion of 13 is going to be really interesting, try it to
check if you have understood insertion well for exams.
Please refer C Program for Red Black Tree Insertion for complete implementation of above
algorithm.
Please write comments if you find anything incorrect, or you want to share more
information about the topic discussed above.
Source
http://www.geeksforgeeks.org/red-black-tree-set-2-insert/
/* A binary tree node has data, and left and right pointers */
struct node
{
int data;
node* left;
node* right;
};
// Convert to DLL
node *head = NULL;
BinaryTree2DoubleLinkedList(root, &head);
return 0;
}
Output:
25 12 30 10 36 15
Note that use of static variables like above is not a recommended practice (we have used
static for simplicity). Imagine a situation where same function is called for two or more
trees, the old value of prev would be used in next call for a different tree. To avoid such
problems, we can use double pointer or reference to a pointer.
Time Complexity: The above program does a simple inorder traversal, so time complexity
is O(n) where n is the number of nodes in given binary tree.
Please write comments if you find anything incorrect, or you want to share more
information about the topic discussed above
Source
http://www.geeksforgeeks.org/convert-given-binary-tree-doubly-linked-list-set-3/
We strongly recommend to minimize the browser and try this yourself first.
This is a typical tree traversal question. We start from root and check if the node has one
child, if yes then print the only child of that node. If node has both children, then recur for
both the children.
Output:
4 5 6
Time Complexity of above code is O(n) as the code does a simple tree traversal.
This article is compiled by Aman Gupta. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above
Source
http://www.geeksforgeeks.org/print-nodes-dont-sibling-binary-tree/
Category: Trees
Given a binary tree (not a binary search tree) and two values say n1 and n2, write a
program to find the least common ancestor.
Following is definition of LCA from Wikipedia:
Let T be a rooted tree. The lowest common ancestor between two nodes n1 and n2 is
defined as the lowest node in T that has both n1 and n2 as descendants (where we allow a
node to be a descendant of itself).
The LCA of n1 and n2 in T is the shared ancestor of n1 and n2 that is located farthest from
the root. Computation of lowest common ancestors may be useful, for instance, as part of a
procedure for determining the distance between pairs of nodes in a tree: the distance from
n1 to n2 can be computed as the distance from the root to n1, plus the distance from the
root to n2, minus twice the distance from the root to their lowest common ancestor.
(Source Wiki)
We have discussed an efficient solution to find LCA in Binary Search Tree. In Binary Search
Tree, using BST properties, we can find LCA in O(h) time where h is height of tree. Such an
implementation is not possible in Binary Tree as keys Binary Tree nodes dont follow any
order. Following are different approaches to find LCA in Binary Tree.
Method 1 (By Storing root to n1 and root to n2 paths):
Following is simple O(n) algorithm to find LCA of n1 and n2.
1) Find path from root to n1 and store it in a vector or array.
2) Find path from root to n2 and store it in another vector or array.
3) Traverse both paths till the values in arrays are same. Return the common element just
before the mismatch.
Following is C++ implementation of above algorithm.
// Utility function creates a new binary tree node with given key
Node * newNode(int k)
{
Node *temp = new Node;
temp->key = k;
temp->left = temp->right = NULL;
return temp;
}
// Finds the path from root node to given root of the tree, Stores the
// path in a vector path[], returns true if path exists otherwise false
bool findPath(Node *root, vector<int> &path, int k)
{
// base case
if (root == NULL) return false;
// Returns LCA if node n1, n2 are present in the given binary tree,
// otherwise return -1
int findLCA(Node *root, int n1, int n2)
{
// to store paths to n1 and n2 from the root
vector<int> path1, path2;
Output:
LCA(4, 5) = 2
LCA(4, 6) = 1
LCA(3, 4) = 1
LCA(2, 4) = 2
Time Complexity: Time complexity of the above solution is O(n). The tree is traversed
twice, and then path arrays are compared.
Thanks to Ravi Chandra Enaganti for suggesting the initial solution based on this method.
// This function returns pointer to LCA of two given values n1 and n2.
// This function assumes that n1 and n2 are present in Binary Tree
struct Node *findLCA(struct Node* root, int n1, int n2)
{
// Base case
if (root == NULL) return NULL;
Output:
LCA(4, 5) = 2
LCA(4, 6) = 1
LCA(3, 4) = 1
LCA(2, 4) = 2
// This function returns pointer to LCA of two given values n1 and n2.
// v1 is set as true by this function if n1 is found
// v2 is set as true by this function if n2 is found
struct Node *findLCAUtil(struct Node* root, int n1, int n2, bool &v1, bool
&v2)
{
// Base case
if (root == NULL) return NULL;
// This function returns LCA of n1 and n2 only if both n1 and n2 are present
// in tree, otherwise returns NULL;
Node *findLCA(Node *root, int n1, int n2)
{
// Initialize n1 and n2 as not visited
bool v1 = false, v2 = false;
return 0;
}
Output:
LCA(4, 5) = 2
Keys are not present
Source
http://www.geeksforgeeks.org/lowest-common-ancestor-binary-tree-set-1/
Category: Trees
Post navigation
Interesting Facts about Bitwise Operators in C Find distance between two given keys of a
Binary Tree
Writing code in comment? Please use code.geeksforgeeks.org, generate link and share the
link here.
// This function returns pointer to LCA of two given values n1 and n2.
// It also sets d1, d2 and dist if one key is not ancestor of other
// d1 --> To store distance of n1 from root
// d2 --> To store distance of n2 from root
// lvl --> Level (or distance from root) of current node
// dist --> To store distance between n1 and n2
Node *findDistUtil(Node* root, int n1, int n2, int &d1, int &d2,
int &dist, int lvl)
{
// Base case
if (root == NULL) return NULL;
return -1;
}
Time Complexity: Time complexity of the above solution is O(n) as the method does a
single tree traversal.
Thanks to Atul Singh for providing the initial solution for this post.
Please write comments if you find anything incorrect, or you want to share more
information about the topic discussed above
Source
http://www.geeksforgeeks.org/find-distance-two-given-nodes/
Category: Trees
Post navigation
Lowest Common Ancestor in a Binary Tree | Set 1 Print a long int in C using putchar()
only
Writing code in comment? Please use code.geeksforgeeks.org, generate link and share the
link here.
struct Node
{
int key;
Node *left, *right;
};
/* This function prints all nodes that are distance k from a leaf node
path[] --> Store ancestors of a node
visited[] --> Stores true if a node is printed as output. A node may be k
distance away from many leaves, we want to print it once */
void kDistantFromLeafUtil(Node* node, int path[], bool visited[],
int pathLen, int k)
{
// Base case
if (node==NULL) return;
/* Given a binary tree and a nuber k, print all nodes that are k
distant from a leaf*/
void printKDistantfromLeaf(Node* node, int k)
{
int path[MAX_HEIGHT];
bool visited[MAX_HEIGHT] = {false};
kDistantFromLeafUtil(node, path, visited, 0, k);
}
return 0;
}
Output:
Nodes at distance 2 are: 3 1
Time Complexity: Time Complexity of above code is O(n) as the code does a simple tree
traversal.
Please write comments if you find anything incorrect, or you want to share more
information about the topic discussed above
Source
http://www.geeksforgeeks.org/print-nodes-distance-k-leaf-node/
Category: Trees
12 40
\ / \
14 10 100
\ / \
16 60 150
Cannot be a Red-Black Tree It can be Red-Black Tree
with any color assignment
Max height of 12 is 1
Min height of 12 is 3
10
/ \
5 100
/ \
50 150
/
40
It can also be Red-Black Tree
Expected time complexity is O(n). The tree should be traversed at-most once in the
solution.
We strongly recommend to minimize the browser and try this yourself first.
For every node, we need to get the maximum and minimum heights and compare them.
The idea is to traverse the tree and for every node check if its balanced. We need to write a
recursive function that returns three things, a boolean value to indicate the tree is balanced
or not, minimum height and maximum height. To return multiple values, we can either use
a structure or pass variables by reference. We have passed maxh and minh by reference so
that the values can be used in parent calls.
struct Node
{
int key;
Node *left, *right;
};
int lmxh, lmnh; // To store max and min heights of left subtree
int rmxh, rmnh; // To store max and min heights of right subtree
// Check if left subtree is balanced, also set lmxh and lmnh
if (isBalancedUtil(root->left, lmxh, lmnh) == false)
return false;
// Set the max and min heights of this node for the parent call
maxh = max(lmxh, rmxh) + 1;
minh = min(lmnh, rmnh) + 1;
return false;
}
return 0;
}
Output:
Balanced
Time Complexity: Time Complexity of above code is O(n) as the code does a simple tree
traversal.
Please write comments if you find anything incorrect, or you want to share more
information about the topic discussed above
Source
http://www.geeksforgeeks.org/check-given-binary-tree-follows-height-property-red-
black-tree/
Category: Trees
Interval Tree
Consider a situation where we have a set of intervals and we need following operations to
be implemented efficiently.
1) Add an interval
2) Remove an interval
3) Given an interval x, find if x overlaps with any of the existing intervals.
Interval Tree: The idea is to augment a self-balancing Binary Search Tree (BST) like Red
Black Tree, AVL Tree, etc to maintain set of intervals so that all operations can be done in
O(Logn) time.
Every node of Interval Tree stores following information.
a) i: An interval which is represented as a pair [low, high]
b) max: Maximum high value in subtree rooted with this node.
The low value of an interval is used as key to maintain order in BST. The insert and delete
operations are same as insert and delete in self-balancing BST used.
The main operation is to search for an overlapping interval. Following is algorithm for
searching an overlapping interval x in an Interval tree rooted with root.
Interval overlappingIntervalSearch(root, x)
1) If x overlaps with root's interval, return the root's interval.
2) If left child of root is not empty and the max in left child
is greater than x's low value, recur for left child
#include <iostream>
using namespace std;
return root;
}
inorder(root->left);
cout << "[" << root->i->low << ", " << root->i->high << "]"
<< " max = " << root->max << endl;
inorder(root->right);
}
cout << "\nSearching for interval [" << x.low << "," << x.high << "]";
Interval *res = overlapSearch(root, x);
if (res == NULL)
cout << "\nNo Overlapping Interval";
else
cout << "\nOverlaps with [" << res->low << ", " << res->high << "]";
return 0;
}
Output:
Inorder traversal of constructed Interval Tree is
[5, 20] max = 20
[10, 30] max = 30
[12, 15] max = 15
[15, 20] max = 40
[17, 19] max = 40
[30, 40] max = 40
Searching for interval [6,7]
Overlaps with [5, 20]
Source
http://www.geeksforgeeks.org/interval-tree/
1
/ \
2 3
/ \ / \
4 5 6 7
\ \
8 9
We strongly recommend to minimize the browser and try this yourself first.
The idea is to traverse the tree once and get the minimum and maximum horizontal
distance with respect to root. For the tree shown above, minimum distance is -2 (for node
with value 4) and maximum distance is 3 (For node with value 9).
Once we have maximum and minimum distances from root, we iterate for each vertical
line at distance minimum to maximum from root, and for each vertical line traverse the
tree and print the nodes which lie on that vertical line.
Algorithm:
Implementation:
Following is C++ implementation of above algorithm.
#include <iostream>
using namespace std;
return 0;
}
Output:
Vertical order traversal is
4
2
1 5 6
3 8
7
9
Source
http://www.geeksforgeeks.org/print-binary-tree-vertical-order/
Category: Trees
Post navigation
Interval Tree Integer Promotions in C
Writing code in comment? Please use code.geeksforgeeks.org, generate link and share the
link here.
We strongly recommend to minimize the browser and try this yourself first.
There are two types of nodes to be considered.
1) Nodes in the subtree rooted with target node. For example if the target node is 8 and k
is 2, then such nodes are 10 and 14.
2) Other nodes, may be an ancestor of target, or a node in some other subtree. For target
node 8 and k is 2, the node 22 comes in this category.
Finding the first type of nodes is easy to implement. Just traverse subtrees rooted with the
target node and decrement k in recursive call. When the k becomes 0, print the node
currently being traversed (See thisfor more details). Here we call the function as
printkdistanceNodeDown().
How to find nodes of second type? For the output nodes not lying in the subtree with the
target node as the root, we must go through all ancestors. For every ancestor, we find its
distance from target node, let the distance be d, now we go to other subtree (if target was
found in left subtree, then we go to right subtree and vice versa) of the ancestor and find all
nodes at k-d distance from the ancestor.
Following is C++ implementation of the above approach.
#include <iostream>
using namespace std;
Output:
4
20
Time Complexity: At first look the time complexity looks more than O(n), but if we take a
closer look, we can observe that no node is traversed more than twice. Therefore the time
complexity is O(n).
This article is contributed by Prasant Kumar. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above
Source
http://www.geeksforgeeks.org/print-nodes-distance-k-given-node-binary-tree/
We strongly recommend to minimize the browser and try this yourself first.
The following post can be considered as a prerequisite for this.
Construct Tree from given Inorder and Preorder traversals
Let us consider the above example.
in[] = {4, 8, 10, 12, 14, 20, 22};
level[] = {20, 8, 22, 4, 12, 10, 14};
In a Levelorder sequence, the first element is the root of the tree. So we know 20 is root
for given sequences. By searching 20 in Inorder sequence, we can find out all elements on
left side of 20 are in left subtree and elements on right are in right subtree. So we know
below structure now.
20
/ \
/ \
{4,8,10,12,14} {22}
Let us call {4,8,10,12,14} as left subarray in Inorder traversal and {22} as right subarray in
Inorder traversal.
In level order traversal, keys of left and right subtrees are not consecutive. So we extract
all nodes from level order traversal which are in left subarray of Inorder traversal. To
construct the left subtree of root, we recur for the extracted elements from level order
traversal and left subarray of inorder traversal. In the above example, we recur for
following two arrays.
Similarly, we recur for following two arrays and construct the right subtree.
return root;
}
return 0;
}
Output:
Inorder traversal of the constructed tree is
4 8 10 12 14 20 22
An upper bound on time complexity of above method is O(n3). In the main recursive
function, extractNodes() is called which takes O(n2) time.
The code can be optimized in many ways and there may be better solutions. Looking for
improvements and other optimized approaches to solve this problem.
This article is contributed by Abhay Rathi. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above
Source
http://www.geeksforgeeks.org/construct-tree-inorder-level-order-traversals/
Category: Trees
Post navigation
Amazon Interview | Set 75 (For SDE-1) Red-Black Tree | Set 3 (Delete)
Writing code in comment? Please use code.geeksforgeeks.org, generate link and share the
link here.
3.2) Do following while the current node u is double black or it is not root. Let sibling of
node be s.
.(a): If sibling s is black and at least one of siblings children is red, perform
rotation(s). Let the red child of s be r. This case can be divided in four subcases depending
upon positions of s and r.
..(i) Left Left Case (s is left child of its parent and r is left child of s or both children of
s are red). This is mirror of right right case shown in below diagram.
..(ii) Left Right Case (s is left child of its parent and r is right child). This is mirror of
right left case shown in below diagram.
..(iii) Right Right Case (s is right child of its parent and r is right child of s or both
children of s are red)
..(iv) Right Left Case (s is right child of its parent and r is left child of s)
..(b): If sibling is black and its both children are black, perform recoloring, and recur
for the parent if parent is black.
In this case, if parent was red, then we didnt need to recur for prent, we can simply make
it black (red + double black = single black)
..(c): If sibling is red, perform a rotation to move old sibling up, recolor the old sibling
and parent. The new sibling is always black (See the below diagram). This mainly converts
the tree to black sibling case (by rotation) and leads to case (a) or (b). This case can be
divided in two subcases.
..(i) Left Case (s is left child of its parent). This is mirror of right right case shown in
below diagram. We right rotate the parent p.
..(iii) Right Case (s is right child of its parent). We left rotate the parent p.
3.3) If u is root, make it single black and return (Black height of complete tree reduces by
1).
References:
https://www.cs.purdue.edu/homes/ayg/CS251/slides/chap13c.pdf
Introduction to Algorithms 3rd Edition by Clifford Stein, Thomas H. Cormen, Charles E.
Leiserson, Ronald L. Rivest
Please write comments if you find anything incorrect, or you want to share more
information about the topic discussed above
Source
http://www.geeksforgeeks.org/red-black-tree-set-3-delete-2/
1
/ \
2 3
/ \ / \
4 5 6 7
\
8
We strongly recommend to minimize the browser and try this yourself first.
The Right view contains all nodes that are last nodes in their levels. A simple solution is to
do level order traversal and print the last node in every level.
The problem can also be solved using simple recursive traversal. We can keep track of level
of a node by passing a parameter to all recursive calls. The idea is to keep track of
maximum level also. And traverse the tree in a manner that right subtree is visited before
left subtree. Whenever we see a node whose level is more than maximum level so far, we
print the node because this is the last node in its level (Note that we traverse the right
subtree before left subtree). Following is C implementation of this approach.
struct Node
{
int data;
struct Node *left, *right;
};
rightView(root);
return 0;
}
Output:
1 3 7 8
Time Complexity: The function does a simple traversal of the tree, so the complexity is
O(n).
This article is contributed by Shalki Agarwal. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above
Source
http://www.geeksforgeeks.org/print-right-view-binary-tree-2/
Category: Trees
1
/ \
2 3
/ \ / \
4 5 6 7
\ \
8 9
Output:
Vertical order traversal is
4
2
1 5 6
3 8
7
9
Time Complexity of hashing based solution can be considered as O(n) under the
assumption that we have good hashing function that allows insertion and retrieval
operations in O(1) time. In the above C++ implementation, map of STL is used. map in STL
is typically implemented using a Self-Balancing Binary Search Tree where all operations
take O(Logn) time. Therefore time complexity of above implementation is O(nLogn).
Please write comments if you find anything incorrect, or you want to share more
information about the topic discussed above
Source
http://www.geeksforgeeks.org/print-binary-tree-vertical-order-set-2/
Category: Trees
We strongly recommend to minimize the gbrowser and try this yourself first.
Method 1 (Naive):
This method doesnt require the tree to be a BST. Following are steps.
1. Traverse node by node(Inorder, preorder, etc.)
2. For each node find all the nodes greater than that of the current node, sum the values.
Store all these sums.
3. Replace each node value with their corresponding sum by traversing in the same order
as in Step 1.
This takes O(n^2) Time Complexity.
Method 2 (Using only one traversal)
By leveraging the fact that the tree is a BST, we can find an O(n) solution. The idea is to
traverse BST in reverse inorder. Reverse inorder traversal of a BST gives us keys in
decreasing order. Before visiting a node, we visit all greater nodes of that node. While
traversing we keep track of sum of keys which is the sum of all the keys greater than the
key of current node.
// A BST node
struct Node
{
int data;
struct Node *left, *right;
};
printInorder(root->left);
cout << root->data << " ";
printInorder(root->right);
}
transformTree(root);
return 0;
}
Output:
Inorder Traversal of given tree
1 2 7 11 15 29 35 40
Source
http://www.geeksforgeeks.org/transform-bst-sum-tree/
Category: Trees
Given tree:
a
/ \
b c
/ \ / \
d e f g
/ \ / \ / \ / \
h i j k l m n o
Modified tree:
a
/ \
c b
/ \ / \
d e f g
/ \ / \ / \ / \
o n m l k j i h
We strongly recommend to minimize the browser and try this yourself first.
A simple solution is to do following steps.
1) Access nodes level by level.
2) If current level is odd, then store nodes of this level in an array.
3) Reverse the array and store elements back in tree.
A tricky solution is to do two inorder traversals. Following are steps to be followed.
1) Traverse the given tree in inorder fashion and store all odd level nodes in an auxiliary
array. For the above example given tree, contents of array become {h, i, b, j, k, l, m, c, n, o}
2) Reverse the array. The array now becomes {o, n, c, m, l, k, j, b, i, h}
3) Traverse the tree again inorder fashion. While traversing the tree, one by one take
elements from array and store elements from array to every odd level traversed node.
For the above example, we traverse h first in above array and replace h with o. Then we
traverse i and replace it with n.
Following is C++ implementation of the above algorithm.
reverseAlternate(root);
return 0;
}
Output:
Inorder Traversal of given tree
h d i b j e k a l f m c n g o
Time complexity of the above solution is O(n) as it does two inorder traversals of binary
tree.
This article is contributed by Kripal Gaurav. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above.
Source
http://www.geeksforgeeks.org/reverse-alternate-levels-binary-tree/
Category: Trees
Post navigation
[TopTalent.in] Exclusive Interview with Prashanth from IIT Madras who landed a job at
Microsoft, Redmond Calculate the angle between hour hand and minute hand
Writing code in comment? Please use code.geeksforgeeks.org, generate link and share the
link here.
Find the maximum path sum between two leaves of a binary tree
Given a binary tree in which each node element contains a number. Find the maximum
possible sum from one leaf node to another.
The maximum sum path may or may not go through root. For example, in the following
binary tree, the maximum sum is 27(3 + 6 + 9 + 0 1 + 10). Expected time complexity is
O(n).
A simple solution is to traverse the tree and do following for every traversed node X.
1) Find maximum sum from leaf to root in left subtree of X (we can use this post for this
and next steps)
2) Find maximum sum from leaf to root in right subtree of X.
3) Add the above two calculated values and X->data and compare the sum with the
maximum value obtained so far and update the maximum value.
4) Return the maximum value.
The time complexity of above solution is O(n2)
We can find the maximum sum using single traversal of binary tree. The idea is to
maintain two values in recursive calls
1) Maximum root to leaf path sum for the subtree rooted under current node.
2) The maximum path sum between leaves (desired output).
For every visited node X, we find the maximum root to leaf sum in left and right subtrees of
X. We add the two values with X->data, and compare the sum with maximum path sum
found so far.
Following is C++ implementation of the above O(n) solution.
// A utility function to find the maximum sum between any two leaves.
// This function calculates two values:
// 1) Maximum path sum between two leaves which is stored in res.
// 2) The maximum root to leaf path sum which is returned.
int maxPathSumUtil(struct Node *root, int &res)
{
// Base cases
if (root==NULL) return 0;
if (!root->left && !root->right) return root->data;
Output:
Max pathSum of the given binary tree is 27.
This article is contributed by Kripal Gaurav. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above
Source
http://www.geeksforgeeks.org/find-maximum-path-sum-two-leaves-binary-tree/
Category: Trees
Inorder predecessor and successor for a given key in BST
I recently encountered with a question in an interview at e-commerce company. The
interviewer asked the following question:
There is BST given with root node with key part as integer only. The structure of each node
is as follows:
struct Node
{
int key;
struct Node *left, *right ;
};
You need to find the inorder successor and predecessor of a given key. In case the given key
is not found in BST, then return the two values within which this key will lie.
Following is the algorithm to reach the desired result. Its a recursive method:
1. If root is NULL
then return
2. if key is found then
a. If its left subtree is not null
Then predecessor will be the right most
child of left subtree or left child itself.
b. If its right subtree is not null
The successor will be the left most child
of right subtree or right child itself.
return
3. If key is smaller then root node
set the successor as root
search recursively into left subtree
else
set the predecessor as root
search recursively into right subtree
// BST Node
struct Node
{
int key;
struct Node *left, *right;
};
Output:
Predecessor is 60
Successor is 70
This article is contributed by algoLover. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above.
Source
http://www.geeksforgeeks.org/inorder-predecessor-successor-given-key-bst/
Category: Trees
Post navigation
An Interesting Method to Generate Binary Numbers from 1 to n Amazon Interview | Set
97 (On-Campus for SDE1)
Writing code in comment? Please use code.geeksforgeeks.org, generate link and share the
link here.
Tree1
x
/ \
a b
\
c
Tree2
z
/ \
x e
/ \ \
a b k
\
c
We have discussed a O(n2) solution for this problem. In this post a O(n) solution is
discussed. The idea is based on the fact that inorder and preorder/postorder uniquely
identify a binary tree. Tree S is a subtree of T if both inorder and preorder traversals of S
arew substrings of inorder and preorder traversals of T respectively.
Following are detailed steps.
1) Find inorder and preorder traversals of T, store them in two auxiliary arrays inT[] and
preT[].
2) Find inorder and preorder traversals of S, store them in two auxiliary arrays inS[] and
preS[].
3) If inS[] is a subarray of inT[] and preS[] is a subarray preT[], then S is a subtree of T. Else
not.
We can also use postorder traversal in place of preorder in the above algorithm.
Let us consider the above example
EDIT
The above algorithm doesn't work for cases where a tree is present
in another tree, but not as a subtree. Consider the following example.
Tree1
x
/ \
a b
/
c
Tree2
x
/ \
a b
/ \
c d
The Tree2 is not a subtree of Tree1, but inS[] and preS[] are
subarrays of inT[] and preT[] respectively.
The above algorithm can be extended to handle such cases by adding a special character
whenever we encounter NULL in inorder and preorder traversals. Thanks to Shivam Goel
for suggesting this extension.
Following is C++ implementation of above algorithm.
#include <iostream>
#include <cstring>
using namespace std;
#define MAX 100
Node *S = newNode('a');
S->left = newNode('b');
S->left->left = newNode('c');
S->right = newNode('d');
if (isSubtree(T, S))
cout << "Yes: S is a subtree of T";
else
cout << "No: S is NOT a subtree of T";
return 0;
}
Output:
No: S is NOT a subtree of T
Time Complexity: Inorder and Preorder traversals of Binary Tree take O(n) time. The
function strstr() can also be implemented in O(n) time using KMP string matching
algorithm.
Auxiliary Space: O(n)
Thanks to Ashwini Singh for suggesting this method. Please write comments if you find
anything incorrect, or you want to share more information about the topic discussed above
Source
http://www.geeksforgeeks.org/check-binary-tree-subtree-another-binary-tree-set-2/
Category: Trees
Post navigation
Amazon Interview | Set 97 (On-Campus for SDE1) Euler Circuit in a Directed Graph
Writing code in comment? Please use code.geeksforgeeks.org, generate link and share the
link here.
6
/ \
3 5
/ \ / \
7 8 1 3
Say two node be 7 and 1, result is TRUE.
Say two nodes are 3 and 5, result is FALSE.
Say two nodes are 7 and 5, result is FALSE.
We strongly recommend to minimize the browser and try this yourself first.
The idea is to find level of one of the nodes. Using the found level, check if a and b are at
this level. If a and b are at given level, then finally check if they are not children of same
parent.
Following is C implementation of the above approach.
return 0;
}
Ouput:
Yes
Time Complexity of the above solution is O(n) as it does at most three traversals of binary
tree.
This article is contributed by Ayush Srivastava. Please write comments if you find
anything incorrect, or you want to share more information about the topic discussed above
Source
http://www.geeksforgeeks.org/check-two-nodes-cousins-binary-tree/
Category: Trees
Clone a Binary Tree with Random Pointers
Given a Binary Tree where every node has following structure.
struct node {
int key;
struct node *left,*right,*random;
}
The random pointer points to any random node of the binary tree and can even point to
NULL, clone the given binary tree.
Method 1 (Use Hashing)
The idea is to store mapping from given tree nodes to clone tre node in hashtable.
Following are detailed steps.
1) Recursively traverse the given Binary and copy key value, left pointer and right pointer
to clone tree. While copying, store the mapping from given tree node to clone tree node in a
hashtable. In the following pseudo code, cloneNode is currently visited node of clone tree
and treeNode is currently visited node of given tree.
cloneNode->key = treeNode->key
cloneNode->left = treeNode->left
cloneNode->right = treeNode->right
map[treeNode] = cloneNode
2) Recursively traverse both trees and set random pointers using entries from hash table.
cloneNode->random = map[treeNode->random]
// A hashmap based C++ program to clone a binary tree with random pointers
#include<iostream>
#include<map>
using namespace std;
/* A binary tree node has data, pointer to left child, a pointer to right
child and a pointer to random node*/
struct Node
{
int key;
struct Node* left, *right, *random;
};
/* Helper function that allocates a new Node with the
given data and NULL left, right and random pointers. */
Node* newNode(int key)
{
Node* temp = new Node;
temp->key = key;
temp->random = temp->right = temp->left = NULL;
return (temp);
}
// This function creates clone by copying key and left and right pointers
// This function also stores mapping from given tree node to clone.
Node* copyLeftRightNode(Node* treeNode, map<Node *, Node *> *mymap)
{
if (treeNode == NULL)
return NULL;
Node* cloneNode = newNode(treeNode->key);
(*mymap)[treeNode] = cloneNode;
cloneNode->left = copyLeftRightNode(treeNode->left, mymap);
cloneNode->right = copyLeftRightNode(treeNode->right, mymap);
return cloneNode;
}
// Test No 2
// tree = NULL;
// Test No 3
// tree = newNode(1);
// Test No 4
/* tree = newNode(1);
tree->left = newNode(2);
tree->right = newNode(3);
tree->random = tree->right;
tree->left->random = tree;
*/
return 0;
}
Output:
Inorder traversal of original binary tree is:
[4 1], [2 NULL], [5 3], [1 5], [3 NULL],
#include <iostream>
using namespace std;
/* A binary tree node has data, pointer to left child, a pointer to right
child and a pointer to random node*/
struct Node
{
int key;
struct Node* left, *right, *random;
};
treeNode->left->right = copyLeftRightNode(treeNode->right);
return treeNode->left;
}
// This function sets random pointer in cloned tree as per original tree
// i.e. if node A's random pointer points to node B, then
// in cloned tree, cA wil point to cB (cA and cB are new node in cloned
// tree corresponding to node A and B in original tree)
void copyRandomNode(Node* treeNode, Node* cloneNode)
{
if (treeNode == NULL)
return;
if(treeNode->random != NULL)
cloneNode->random = treeNode->random->left;
else
cloneNode->random = NULL;
restoreTreeLeftNode(treeNode->left, cloneNode->left);
restoreTreeLeftNode(treeNode->right, cloneNode->right);
}
// Test No 2
// Node *tree = NULL;
/*
// Test No 3
Node *tree = newNode(1);
// Test No 4
Node *tree = newNode(1);
tree->left = newNode(2);
tree->right = newNode(3);
tree->random = tree->right;
tree->left->random = tree;
Test No 5
Node *tree = newNode(1);
tree->left = newNode(2);
tree->right = newNode(3);
tree->left->left = newNode(4);
tree->left->right = newNode(5);
tree->right->left = newNode(6);
tree->right->right = newNode(7);
tree->random = tree->left;
*/
// Test No 6
Node *tree = newNode(10);
Node *n2 = newNode(6);
Node *n3 = newNode(12);
Node *n4 = newNode(5);
Node *n5 = newNode(8);
Node *n6 = newNode(11);
Node *n7 = newNode(13);
Node *n8 = newNode(7);
Node *n9 = newNode(9);
tree->left = n2;
tree->right = n3;
tree->random = n2;
n2->left = n4;
n2->right = n5;
n2->random = n8;
n3->left = n6;
n3->right = n7;
n3->random = n5;
n4->random = n9;
n5->left = n8;
n5->right = n9;
n5->random = tree;
n6->random = n9;
n9->random = n8;
/* Test No 7
Node *tree = newNode(1);
tree->left = newNode(2);
tree->right = newNode(3);
tree->left->random = tree;
tree->right->random = tree->left;
*/
cout << "Inorder traversal of original binary tree is: \n";
printInorder(tree);
return 0;
}
Output:
Inorder traversal of original binary tree is:
[5 9], [6 7], [7 NULL], [8 10], [9 7], [10 6], [11 9], [12 8], [13 NULL],
This article is contributed by Anurag Singh. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above.
Source
http://www.geeksforgeeks.org/clone-binary-tree-random-pointers/
Category: Trees Tags: Hashing
Post navigation
MAQ Software Interview Experience | Set 2 Oracle Interview | Set 8
Writing code in comment? Please use code.geeksforgeeks.org, generate link and share the
link here.
We strongly recommend to minimize the browser and try this yourself first.
This can be done using Post Order Traversal. The idea is to consider height and children
count on each and every node.
If a child node i takes ci iterations to pass info below its subtree, then its parent will take
(ci + 1) iterations to pass info to subtree rooted at that child i.
If parent has more children, it will pass info to them in subsequent iterations. Lets say
children of a parent takes c1, c2, c3, c4, , cn iterations to pass info in their own subtree,
Now parent has to pass info to these n children one by one in n iterations. If parent picks
child i in ith iteration, then parent will take (i + ci) iterations to pass info to child i and all
its subtree.
In any iteration, when parent passes info a child i+1, children (1 to i) which got info from
parent already in previous iterations, will pass info to further down in subsequent
iterations, if any child (1 to i) has its own child further down.
To pass info to whole tree in minimum iterations, it needs to be made sure that bandwidth
is utilized as efficiently as possible (i.e. maximum passable no of nodes should pass info
further down in any iteration)
The best possible scenario would be that in nth iteration, n different nodes pass info to
their child.
Nodes with height = 0: (Trivial case) Leaf node has no children (no information passing
needed), so no of iterations would be ZERO.
Nodes with height = 1: Here node has to pass info to all the children one by one (all
children are leaf node, so no more information passing further down). Since all children are
leaf, node can pass info to any child in any order (pick any child who didnt receive the info
yet). One iteration needed for each child and so no of iterations would be no of children.So
node with height 1 with n children will take n iterations.
Take a counter initialized with ZERO, loop through all children and keep incrementing
counter.
Nodes with height > 1: Lets assume that there are n children (1 to n) of a node and
minimum no iterations for all n children are c1, c2, ., cn.
To make sure maximum no of nodes participate in info passing in any iteration, parent
should 1st pass info to that child who will take maximum iteration to pass info further
down in subsequent iterations. i.e. in any iteration, parent should choose the child who
takes maximum iteration later on. It can be thought of as a greedy approach where parent
choose that child 1st, who needs maximum no of iterations so that all subsequent iterations
can be utilized efficiently.
If parent goes in any other fashion, then in the end, there could be some nodes which are
done quite early, sitting idle and so bandwidth is not utilized efficiently in further
iterations.
If there are two children i and j with minimum iterations ci and cj where ci > cj, then If
parent picks child j 1st then no of iterations needed by parent to pass info to both children
and their subtree would be:max (1 + cj, 2 + ci) = 2 + ci
If parent picks child i 1st then no of iterations needed by parent to pass info to both
children and their subtree would be: max(1 + ci, 2 + cj) = 1 + ci (So picking ci gives better
result than picking cj)
This tells that parent should always choose child i with max ci value in any iteration.
SO here greedy approach is:
sort all ci values decreasing order,
lets say after sorting, values are c1 > c2 > c3 > . > cn
take a counter c, set c = 1 + c1 (for child with maximum no of iterations)
for all children i from 2 to n, c = c + 1 + ci
then total no of iterations needed by parent is max(n, c)
Let minItr(A) be the minimum iteration needed to pass info from node A to its all the sub-
tree. Let child(A) be the count of all children for node A. So recursive relation would be:
NAryTree::NAryTree(int N)
{
this->N = N;
adj = new list<int>[N];
}
// To add a child w to v
void NAryTree::addChild(int v, int w)
{
adj[v].push_back(w); // Add w to vs list.
}
tree1.addChild(1, 7);
tree1.addChild(1, 8);
tree1.addChild(1, 9);
tree1.addChild(4, 10);
tree1.addChild(4, 11);
tree1.addChild(6, 12);
tree1.addChild(7, 13);
tree1.addChild(7, 14);
tree1.addChild(10, 15);
tree1.addChild(11, 16);
// TestCase 2
NAryTree tree2(3);
tree2.addChild(0, 1);
tree2.addChild(0, 2);
cout << "TestCase 2 - Minimum Iteration: "
<< tree2.getMinIter() << endl;
// TestCase 3
NAryTree tree3(1);
cout << "TestCase 3 - Minimum Iteration: "
<< tree3.getMinIter() << endl;
// TestCase 4
NAryTree tree4(6);
tree4.addChild(0, 1);
tree4.addChild(1, 2);
tree4.addChild(2, 3);
tree4.addChild(3, 4);
tree4.addChild(4, 5);
cout << "TestCase 4 - Minimum Iteration: "
<< tree4.getMinIter() << endl;
// TestCase 5
NAryTree tree5(6);
tree5.addChild(0, 1);
tree5.addChild(0, 2);
tree5.addChild(2, 3);
tree5.addChild(2, 4);
tree5.addChild(2, 5);
cout << "TestCase 5 - Minimum Iteration: "
<< tree5.getMinIter() << endl;
// TestCase 6
NAryTree tree6(6);
tree6.addChild(0, 1);
tree6.addChild(0, 2);
tree6.addChild(2, 3);
tree6.addChild(2, 4);
tree6.addChild(3, 5);
cout << "TestCase 6 - Minimum Iteration: "
<< tree6.getMinIter() << endl;
// TestCase 7
NAryTree tree7(14);
tree7.addChild(0, 1);
tree7.addChild(0, 2);
tree7.addChild(0, 3);
tree7.addChild(1, 4);
tree7.addChild(2, 5);
tree7.addChild(2, 6);
tree7.addChild(4, 7);
tree7.addChild(5, 8);
tree7.addChild(5, 9);
tree7.addChild(7, 10);
tree7.addChild(8, 11);
tree7.addChild(8, 12);
tree7.addChild(10, 13);
cout << "TestCase 7 - Minimum Iteration: "
<< tree7.getMinIter() << endl;
// TestCase 8
NAryTree tree8(14);
tree8.addChild(0, 1);
tree8.addChild(0, 2);
tree8.addChild(0, 3);
tree8.addChild(0, 4);
tree8.addChild(0, 5);
tree8.addChild(1, 6);
tree8.addChild(2, 7);
tree8.addChild(3, 8);
tree8.addChild(4, 9);
tree8.addChild(6, 10);
tree8.addChild(7, 11);
tree8.addChild(8, 12);
tree8.addChild(9, 13);
cout << "TestCase 8 - Minimum Iteration: "
<< tree8.getMinIter() << endl;
// TestCase 9
NAryTree tree9(25);
tree9.addChild(0, 1);
tree9.addChild(0, 2);
tree9.addChild(0, 3);
tree9.addChild(0, 4);
tree9.addChild(0, 5);
tree9.addChild(0, 6);
tree9.addChild(1, 7);
tree9.addChild(2, 8);
tree9.addChild(3, 9);
tree9.addChild(4, 10);
tree9.addChild(5, 11);
tree9.addChild(6, 12);
tree9.addChild(7, 13);
tree9.addChild(8, 14);
tree9.addChild(9, 15);
tree9.addChild(10, 16);
tree9.addChild(11, 17);
tree9.addChild(12, 18);
tree9.addChild(13, 19);
tree9.addChild(14, 20);
tree9.addChild(15, 21);
tree9.addChild(16, 22);
tree9.addChild(17, 23);
tree9.addChild(19, 24);
return 0;
}
Output:
TestCase 1 - Minimum Iteration: 6
TestCase 2 - Minimum Iteration: 2
TestCase 3 - Minimum Iteration: 0
TestCase 4 - Minimum Iteration: 5
TestCase 5 - Minimum Iteration: 4
TestCase 6 - Minimum Iteration: 3
TestCase 7 - Minimum Iteration: 6
TestCase 8 - Minimum Iteration: 6
TestCase 9 - Minimum Iteration: 8
This article is contributed by Anurag Singh. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above.
Source
http://www.geeksforgeeks.org/minimum-iterations-pass-information-nodes-tree/
Category: Trees
Post navigation
[TopTalent.in] Exclusive Interview with Abhishek who got into DE Shaw Intuit Interview
| Set 3 (For SE-2)
Writing code in comment? Please use code.geeksforgeeks.org, generate link and share the
link here.
Input: parent[] = {1 5 5 2 2 -1 3}
Output: 4
The given array represents following Binary Tree
5
/ \
1 2
/ / \
0 3 4
/
6
int n = sizeof(parent)/sizeof(parent[0]);
cout << "Height is " << findHeight(parent, n);
return 0;
}
Output:
Height is 5
Note that the time complexity of this programs seems more than O(n). If we take a closer
look, we can observe that depth of every node is evaluated only once.
This article is contributed by Siddharth. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above
Source
http://www.geeksforgeeks.org/find-height-binary-tree-represented-parent-array/
Output:
8 22
4 12
10 14
A Simple Method is to first write a recursive function that prints nodes of a given level
number. Then call recursive function in a loop from low to high. Time complexity of this
method is O(n2)
We can print nodes in O(n) time using queue based iterative level order traversal. The
idea is to do simple queue based level order traversal. While doing inorder traversal, add a
marker node at the end. Whenever we see a marker node, we increase level number. If
level number is between low and high, then print nodes.
The following is C++ implementation of above idea.
// A C++ program to print Nodes level by level berween given two levels.
#include <iostream>
#include <queue>
using namespace std;
/* A binary tree Node has key, pointer to left and right children */
struct Node
{
int key;
struct Node* left, *right;
};
/* Given a binary tree, print nodes from level number 'low' to level
number 'high'*/
void printLevels(Node* root, int low, int high)
{
queue <Node *> Q;
cout << "Level Order traversal between given two levels is";
printLevels(root, 2, 3);
return 0;
}
Time complexity of above method is O(n) as it does a simple level order traversal.
This article is contributed by Frank. Please write comments if you find anything incorrect,
or you want to share more information about the topic discussed above
Source
http://www.geeksforgeeks.org/given-binary-tree-print-nodes-two-given-level-numbers/
Category: Trees
Input:
20
/ \
8 22
Output: 20 8 -1 -1 22 -1 -1
Input:
20
/
8
/ \
4 12
/ \
10 14
Output: 20 8 4 -1 -1 12 10 -1 -1 14 -1 -1 -1
Input:
20
/
8
/
10
/
5
Output: 20 8 10 5 -1 -1 -1 -1 -1
Input:
20
\
8
\
10
\
5
Output: 20 -1 8 -1 10 -1 5 -1 -1
Deserialization can be done by simply reading data from file one by one.
Following is C++ implementation of the above idea.
/* A binary tree Node has key, pointer to left and right children */
struct Node
{
int key;
struct Node* left, *right;
};
// Else create node with this item and recur for children
root = newNode(val);
deSerialize(root->left, fp);
deSerialize(root->right, fp);
}
return 0;
}
Output:
Inorder Traversal of the tree constructed from file:
4 8 10 12 14 20 22
References:
http://www.cs.usfca.edu/~brooks/S04classes/cs245/lectures/lecture11.pdf
This article is contributed by Shivam Gupta, Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above
Source
http://www.geeksforgeeks.org/serialize-deserialize-binary-tree/
// Else create node with this item and recur for children
root = newNode(val);
for (int i = 0; i < N; i++)
if (deSerialize(root->child[i], fp))
break;
// Let us open a file and serialize the tree into the file
FILE *fp = fopen("tree.txt", "w");
if (fp == NULL)
{
puts("Could not open file");
return 0;
}
serialize(root, fp);
fclose(fp);
// Let us deserialize the storeed tree into root1
Node *root1 = NULL;
fp = fopen("tree.txt", "r");
deSerialize(root1, fp);
return 0;
}
Output:
Constructed N-Ary Tree from file is
A B E F K C D G H I J
The above implementation can be optimized in many ways for example by using a vector in
place of array of pointers. We have kept it this way to keep it simple to read and
understand.
This article is contributed by varun. Please write comments if you find anything incorrect,
or you want to share more information about the topic discussed above.
Source
http://www.geeksforgeeks.org/serialize-deserialize-n-ary-tree/
Category: Trees
struct Node
{
int key;
Node *left, *right;
if (root->left)
createThreadedUtil(root->left, q);
q->pop();
if (root->right)
createThreadedUtil(root->right, q);
createThreaded(root);
Output:
Inorder traversal of creeated threaded tree is
4 2 5 1 6 3 7
This article is contributed by Minhaz. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above
Source
http://www.geeksforgeeks.org/convert-binary-tree-threaded-binary-tree/
Category: Trees
K Dimensional Tree
A K-D Tree(also called as K-Dimensional Tree) is a binary search tree where data in each
node is a K-Dimensional point in space. In short, it is a space partitioning(details below)
data structure for organizing points in a K-Dimensional space.
A non-leaf node in K-D tree divides the space into two parts, called as half-spaces.
Points to the left of this space are represented by the left subtree of that node and points to
the right of the space are represented by the right subtree. We will soon be explaining the
concept on how the space is divided and tree is formed.
For the sake of simplicity, let us understand a 2-D Tree with an example.
The root would have an x-aligned plane, the roots children would both have y-aligned
planes, the roots grandchildren would all have x-aligned planes, and the roots great-
grandchildren would all have y-aligned planes and so on.
Generalization:
Let us number the planes as 0, 1, 2, (K 1). From the above example, it is quite clear that
a point (node) at depth D will have A aligned plane where A is calculated as:
A = D mod K
How to determine if a point will lie in the left subtree or in right subtree?
If the root node is aligned in planeA, then the left subtree will contain all points whose
coordinates in that plane are smaller than that of root node. Similarly, the right subtree will
contain all points whose coordinates in that plane are greater-equal to that of root node.
Creation of a 2-D Tree:
Consider following points in a 2-D plane:
(3, 6), (17, 15), (13, 15), (6, 12), (9, 1), (2, 7), (10, 19)
1. Insert (3, 6): Since tree is empty, make it the root node.
2. Insert (17, 15): Compare it with root node point. Since root node is X-aligned, the X-
coordinate value will be compared to determine if it lies in the rightsubtree or in the
right subtree. This point will be Y-aligned.
3. Insert (13, 15): X-value of this point is greater than X-value of point in root node. So,
this will lie in the right subtree of (3, 6). Again Compare Y-value of this point with the
Y-value of point (17, 15) (Why?). Since, they are equal, this point will lie in the right
subtree of (17, 15). This point will be X-aligned.
4. Insert (6, 12): X-value of this point is greater than X-value of point in root node. So, this
will lie in the right subtree of (3, 6). Again Compare Y-value of this point with the Y-
value of point (17, 15) (Why?). Since, 12 < 15, this point will lie in the left subtree of
(17, 15). This point will be X-aligned.
5. Insert (9, 1):Similarly, this point will lie in the right of (6, 12).
6. Insert (2, 7):Similarly, this point will lie in the left of (3, 6).
7. Insert (10, 19): Similarly, this point will lie in the left of (13, 15).
How is space partitioned?
All 7 points will be plotted in the X-Y plane as follows:
1. Point (3, 6) will divide the space into two parts: Draw line X = 3.
2. Point (2, 7) will divide the space to the left of line X = 3 into two parts horizontally.
Draw line Y = 7 to the left of line X = 3.
3. Point (17, 15) will divide the space to the right of line X = 3 into two parts horizontally.
Draw line Y = 15 to the right of line X = 3.
Point (6, 12) will divide the space below line Y = 15 and to the right of line X = 3 into
two parts.
Draw line X = 6 to the right of line X = 3 and below line Y = 15.
Point (13, 15) will divide the space below line Y = 15 and to the right of line X = 6 into
two parts.
Draw line X = 13 to the right of line X = 6 and below line Y = 15.
Point (9, 1) will divide the space between lines X = 3, X = 6 and Y = 15 into two parts.
Draw line Y = 1 between lines X = 3 and X = 6.
Point (10, 19) will divide the space to the right of line X = 3 and above line Y = 15 into
two parts.
Draw line Y = 19 to the right of line X = 3 and above line Y = 15.
Following is C++ implementation of KD Tree basic operations like search, insert and delete.
point->k = k;
point->coord = new int[k];
return point;
}
// Creates and returns an Input structure
struct Input* CreateInput(unsigned k, unsigned n)
{
struct Input* input = new Input;
input->n = n;
input->pointArray = new Point*[n];
return input;
}
// Compare the new point with root and decide the left or
// right subtree
if ((newNode->point).coord[axisOfComparison] <
((*root)->point).coord[axisOfComparison])
InsertKDTreeUtil(&((*root)->left), newNode, depth + 1);
else
InsertKDTreeUtil(&((*root)->right), newNode, depth + 1);
}
return 1;
}
if (ArePointsSame(root->point, point))
return 1;
PrintArray(input->pointArray[itp]->coord, k);
}
return 0;
}
Output:
17
140
94
1818
24
55
17
Inorder traversal of K-D Tree created is:
17
140
24
17
55
94
1818
This article is compiled by Aashish Barnwal. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above.
Source
http://www.geeksforgeeks.org/k-dimensional-tree/
Category: Trees Tags: Advance Data Structures, Advanced Data Structures
Post navigation
Amazon interview Experience | Set 141 (For SDE1) Ukkonens Suffix Tree Construction
Part 4
Writing code in comment? Please use code.geeksforgeeks.org, generate link and share the
link here.
1
/ \
2 3
/ \ / \
4 5 6 7
Top view of the above binary tree is
4 2 1 3 7
1
/ \
2 3
\
4
\
5
\
6
Top view of the above binary tree is
2 1 3 6
We strongly recommend to minimize your browser and try this yourself first.
The idea is to do something similar to vertical Order Traversal. Like vertical Order
Traversal, we need to 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 given horizontal
distance is seen or not.
// Constructor
public TreeNode(int key)
{
this.key = key;
left = right = null;
}
}
// Constructors
public Tree() { root = null; }
public Tree(TreeNode n) { root = n; }
Output:
Following are nodes in top view of Binary Tree
1 2 3 6
Time Complexity of the above implementation is O(n) where n is number of nodes in given
binary tree. The assumption here is that add() and contains() methods of HashSet work in
O(1) time.
This article is contributed by Rohan. Please write comments if you find anything incorrect,
or you want to share more information about the topic discussed above.
Source
http://www.geeksforgeeks.org/print-nodes-top-view-binary-tree/
Category: Trees
// traversal loop
while (!q.empty())
{
// Pop two items from queue
first = q.front();
q.pop();
second = q.front();
q.pop();
root->left = newNode(2);
root->right = newNode(3);
root->left->left = newNode(4);
root->left->right = newNode(5);
root->right->left = newNode(6);
root->right->right = newNode(7);
root->left->left->left = newNode(8);
root->left->left->right = newNode(9);
root->left->right->left = newNode(10);
root->left->right->right = newNode(11);
root->right->left->left = newNode(12);
root->right->left->right = newNode(13);
root->right->right->left = newNode(14);
root->right->right->right = newNode(15);
root->left->left->left->left = newNode(16);
root->left->left->left->right = newNode(17);
root->left->left->right->left = newNode(18);
root->left->left->right->right = newNode(19);
root->left->right->left->left = newNode(20);
root->left->right->left->right = newNode(21);
root->left->right->right->left = newNode(22);
root->left->right->right->right = newNode(23);
root->right->left->left->left = newNode(24);
root->right->left->left->right = newNode(25);
root->right->left->right->left = newNode(26);
root->right->left->right->right = newNode(27);
root->right->right->left->left = newNode(28);
root->right->right->left->right = newNode(29);
root->right->right->right->left = newNode(30);
root->right->right->right->right = newNode(31);
return 0;
}
Output:
Specific Level Order traversal of binary tree is
1 2 3 4 7 5 6 8 15 9 14 10 13 11 12 16 31 17 30 18 29 19 28 20 27 21 26 22 25
23 24
Followup Questions:
1. The above code prints specific level order from TOP to BOTTOM. How will you do
specific level order traversal from BOTTOM to TOP (Amazon Interview | Set 120
Round 1 Last Problem)
2. What if tree is not perfect, but complete.
3. What if tree is neither perfect, nor complete. It can be any general binary tree.
This article is contributed by Anurag Singh. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above.
Source
http://www.geeksforgeeks.org/perfect-binary-tree-specific-level-order-traversal/
Input: appointments[] = { {1, 5} {3, 7}, {2, 6}, {10, 15}, {5, 6}, {4, 100}}
Output: Following are conflicting intervals
[3,7] Conflicts with [1,5]
[2,6] Conflicts with [1,5]
[5,6] Conflicts with [3,7]
[4,100] Conflicts with [1,5]
return root;
}
Output:
Following are conflicting intervals
[3,7] Conflicts with [1,5]
[2,6] Conflicts with [1,5]
[5,6] Conflicts with [3,7]
[4,100] Conflicts with [1,5]
Note that the above implementation uses simple Binary Search Tree insert operations.
Therefore, time complexity of the above implementation is more than O(nLogn). We can
use Red-Black Tree or AVL Tree balancing techniques to make the above implementation
O(nLogn).
This article is contributed by Anmol. Please write comments if you find anything incorrect,
or you want to share more information about the topic discussed above
Source
http://www.geeksforgeeks.org/given-n-appointments-find-conflicting-appointments/
Category: Trees
Post navigation
Amazon Interview Experience | Set 158 (Off-Campus) Given a linked list of line
segments, remove middle points
Writing code in comment? Please use code.geeksforgeeks.org, generate link and share the
link here.
// Trie Node.
struct trieNode
{
bool isLeaf;
char *URL;
struct trieNode *child[CHARS];
};
// If we find the last node for a given ip address, print the URL.
if (pCrawl!=NULL && pCrawl->isLeaf)
return pCrawl->URL;
return NULL;
}
//Driver function.
int main()
{
/* Change third ipAddress for validation */
char ipAdd[][MAX] = {"107.108.11.123", "107.109.123.255",
"74.125.200.106"};
char URL[][50] = {"www.samsung.com", "www.samsung.net",
"www.google.in"};
int n = sizeof(ipAdd)/sizeof(ipAdd[0]);
struct trieNode *root = newTrieNode();
// Inserts all the ip address and their corresponding
// domain name after ip address validation.
for (int i=0; i<n; i++)
insert(root,ipAdd[i],URL[i]);
Output:
Reverse DNS look up resolved in cache:
107.108.11.123 --> www.samsung.com
Note that the above implementation of Trie assumes that the given IP address does not
contain characters other than {0, 1,.. 9, .}. What if a user gives an invalid IP address
that contains some other characters? This problem can be resolved by validating the input
IP address before inserting it into Trie. We can use the approach discussed herefor IP
address validation.
This article is contributed by Kumar Gautam. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above
Source
http://www.geeksforgeeks.org/implement-reverse-dns-look-cache/
Category: Trees Tags: Advance Data Structures, Advanced Data Structures
return BITree;
}
return 0;
}
Output:
Sum of elements in arr[0..5] is 12
Sum of elements in arr[0..5] after update is 18
Can we extend the Binary Indexed Tree for range Sum in Logn time?
This is simple to answer. The rangeSum(l, r) can be obtained as getSum(r) getSum(l-1).
Applications:
Used to implement the arithmetic coding algorithm. Development of operations it supports
were primarily motivated by use in that case. See thisfor more details.
References:
http://en.wikipedia.org/wiki/Fenwick_tree
http://community.topcoder.com/tc?module=Static&d1=tutorials&d2=binaryIndexedTrees
Please write comments if you find anything incorrect, or you want to share more
information about the topic discussed above
Source
http://www.geeksforgeeks.org/binary-indexed-tree-or-fenwick-tree-2/
20
/ \
8 22
/ \ \
5 3 25
/ \
10 14
For the above tree the output should be 5, 10, 3, 14, 25.
If there are multiple bottom-most nodes for a horizontal distance from root, then print the
later one in level traversal. For example, in the below diagram, 3 and 4 are both the bottom-
most nodes at horizontal distance 0, we need to print 4.
20
/ \
8 22
/ \ / \
5 3 4 25
/ \
10 14
For the above tree the output should be 5, 10, 4, 14, 25.
We strongly recommend to minimize your browser and try this yourself first.
The following are steps to print Bottom View of Bianry Tree.
1. We put tree nodes in a queue for the level order traversal.
2. Start with the horizontal distance(hd) 0 of the root node, keep on adding left child to
queue along with the horizontal distance as hd-1 and right child as hd+1.
3. Also, use a TreeMap which stores key value pair sorted on key.
4. Every time, we encounter a new horizontal distance or an existing horizontal distance
put the node data for the horizontal distance as key. For the first time it will add to the map,
next time it will replace the value. This will make sure that the bottom most element for
that horizontal distance is present in the map and if you see the tree from beneath that you
will see that element.
A Java based implementation is below :
//Tree class
class Tree
{
TreeNode root; //root node of tree
// Default constructor
public Tree() {}
// Make an iterator
Iterator<Entry<Integer, Integer>> iterator = set.iterator();
Output:
Bottom view of the given binary tree:
5 10 4 14 25
Exercise: Extend the above solution to print all bottommost nodes at a horizontal distance
if there are multiple bottommost nodes. For the above second example, the output should
be 5 10 3 4 14 25.
This article is contributed by Kumar Gautam. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above.
Source
http://www.geeksforgeeks.org/bottom-view-binary-tree/
//Tree node
class TreeNode
{
int data; //node data
int vd; //vertical distance diagonally
TreeNode left, right; //left and right child's reference
// Tree class
class Tree
{
TreeNode root;//Tree root
// Tree constructor
public Tree(TreeNode root) { this.root = root; }
// Make an iterator
Iterator<Entry<Integer, Integer>> iterator = set.iterator();
//Driver class
public class DiagonalSum
{
public static void main(String[] args)
{
TreeNode root = new TreeNode(1);
root.left = new TreeNode(2);
root.right = new TreeNode(3);
root.left.left = new TreeNode(9);
root.left.right = new TreeNode(6);
root.right.left = new TreeNode(4);
root.right.right = new TreeNode(5);
root.right.left.left = new TreeNode(12);
root.right.left.right = new TreeNode(7);
root.left.right.left = new TreeNode(11);
root.left.left.right = new TreeNode(10);
Tree tree = new Tree(root);
tree.diagonalSum();
}
}
Output:
9, 19, 42
Exercise:
This problem was for diagonals from top to bottom and slope -1. Try the same problem for
slope +1.
This article is contributed by Kumar Gautam. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above.
Source
http://www.geeksforgeeks.org/diagonal-sum-binary-tree/
Category: Trees
A
/ \
B C
/ \
E F
/ \
G H
/ \ /
I J K
// A C++ program to find the closesr leaf of a given key in Binary Tree
#include <iostream>
#include <climits>
using namespace std;
/* A binary tree Node has key, pocharer to left and right children */
struct Node
{
char key;
struct Node* left, *right;
};
// Returns distance of the cloest leaf to a given key 'k'. The array
// ancestors is used to keep track of ancestors of current node and
// 'index' is used to keep track of curremt index in 'ancestors[]'
int findClosestUtil(struct Node *root, char k, struct Node *ancestors[],
int index)
{
// Base case
if (root == NULL)
return INT_MAX;
// If key found
if (root->key == k)
{
// Find the cloest leaf under the subtree rooted with given key
int res = closestDown(root);
// If key node found, store current node and recur for left and
// right childrens
ancestors[index] = root;
return getMin(findClosestUtil(root->left, k, ancestors, index+1),
findClosestUtil(root->right, k, ancestors, index+1));
// The main function that returns distance of the closest key to 'k'. It
// mainly uses recursive function findClosestUtil() to find the closes
// distance.
int findClosest(struct Node *root, char k)
{
// Create an array to store ancestors
// Assumptiom: Maximum height of tree is 100
struct Node *ancestors[100];
char k = 'H';
cout << "Distace of the closest key from " << k << " is "
<< findClosest(root, k) << endl;
k = 'C';
cout << "Distace of the closest key from " << k << " is "
<< findClosest(root, k) << endl;
k = 'E';
cout << "Distace of the closest key from " << k << " is "
<< findClosest(root, k) << endl;
k = 'B';
cout << "Distace of the closest key from " << k << " is "
<< findClosest(root, k) << endl;
return 0;
}
Output:
Distace of the closest key from H is 1
Distace of the closest key from C is 2
Distace of the closest key from E is 2
Distace of the closest key from B is 0
The above code can be optimized by storing the left/right information also in ancestor
array. The idea is, if given key is in left subtree of an ancestors, then there is no point to call
closestDown(). Also, the loop can that traverses ancestors array can be optimized to not
traverse ancestors which are at more distance than current result.
Exercise:
Extend the above solution to print not only distance, but the key of closest leaf also.
This article is contributed by Shubham. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above
Source
http://www.geeksforgeeks.org/find-closest-leaf-binary-tree/
Category: Trees
Post navigation
Nuts & Bolts Problem (Lock & Key problem) Print all possible strings that can be made
by placing spaces
Writing code in comment? Please use code.geeksforgeeks.org, generate link and share the
link here.
1
/ \
2 3
/ \ \
4 5 6
/ /
7 8
Input: Root of above Binary Tree
k = 4
We strongly recommend to minimize your browser and try this yourself first
The idea here is to use post order traversal of the tree. Before removing a node we need to
check that all the children of that node in the shorter path are already removed. There are 2
cases for a node whose child or cho
i) This node becomes a leaf node in which case it needs to be deleted.
ii) This node has other child on a path with path length >= k. In that case it needs not to be
deleted.
A C++ based code on this approach is below
struct Node
{
int data;
Node *left, *right;
};
// Utility method that actually removes the nodes which are not
// on the pathLen >= k. This method can change the root as well.
Node *removeShortPathNodesUtil(Node *root, int level, int k)
{
//Base condition
if (root == NULL)
return NULL;
// Return root;
return root;
}
// Method which calls the utitlity method to remove the short path
// nodes.
Node *removeShortPathNodes(Node *root, int k)
{
int pathLen = 0;
return removeShortPathNodesUtil(root, 1, k);
}
// Driver method.
int main()
{
int k = 4;
Node *root = newNode(1);
root->left = newNode(2);
root->right = newNode(3);
root->left->left = newNode(4);
root->left->right = newNode(5);
root->left->left->left = newNode(7);
root->right->right = newNode(6);
root->right->right->left = newNode(8);
cout << "Inorder Traversal of Original tree" << endl;
printInorder(root);
cout << endl;
cout << "Inorder Traversal of Modified tree" << endl;
Node *res = removeShortPathNodes(root, k);
printInorder(res);
return 0;
}
Output:
Inorder Traversal of Original tree
7 4 2 5 1 3 8 6
Inorder Traversal of Modified tree
7 4 2 1 3 8 6
Time complexity of the above solution is O(n) where n is number of nodes in given Binary
Tree.
This article is contributed by Kumar Gautam. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above
Source
http://www.geeksforgeeks.org/remove-nodes-root-leaf-paths-length-k/
Category: Trees Tags: tree-traversal
// return result
return res;
}
Output:
Sum of left leaves is 78
Time complexity of the above solution is O(n) where n is number of nodes in Binary Tree.
Following is Another Method to solve the above problem. This solution passes in a sum
variable as an accumulator. When a left leaf is encountered, the leafs data is added to sum.
Time complexity of this method is also O(n). Thanks to Xin Tong (geeksforgeeks userid
trent.tong) for suggesting this method.
return sum;
}
cout << "Sum of left leaves is " << leftLeavesSum(root) << endl;
return 0;
}
Output:
Sum of left leaves is 78
This article is contributed by Manish. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above
Source
http://www.geeksforgeeks.org/find-sum-left-leaves-given-binary-tree/
Category: Trees
We strongly recommend to minimize your browser and try this yourself first.
To check whether a binary tree is a full binary tree we need to test the following cases:-
1) If a binary tree node is NULL then it is a full binary tree.
2) If a binary tree node does have empty left and right sub-trees, then it is a full binary tree
by definition
3) If a binary tree node has left and right sub-trees, then it is a part of a full binary tree by
definition. In this case recursively check if the left and right sub-trees are also binary trees
themselves.
4) In all other combinations of right and left sub-trees, the binary tree is not a full binary
tree.
Following is the C code for checking if a binary tree is a full binary tree.
// If leaf node
if (root->left == NULL && root->right == NULL)
return true;
// If both left and right are not NULL, and left & right subtrees
// are full
if ((root->left) && (root->right))
return (isFullTree(root->left) && isFullTree(root->right));
// We reach here when none of the above if conditions work
return false;
}
// Driver Program
int main()
{
struct Node* root = NULL;
root = newNode(10);
root->left = newNode(20);
root->right = newNode(30);
root->left->right = newNode(40);
root->left->left = newNode(50);
root->right->left = newNode(60);
root->right->right = newNode(70);
root->left->left->left = newNode(80);
root->left->left->right = newNode(90);
root->left->right->left = newNode(80);
root->left->right->right = newNode(90);
root->right->left->left = newNode(80);
root->right->left->right = newNode(90);
root->right->right->left = newNode(80);
root->right->right->right = newNode(90);
if (isFullTree(root))
printf("The Binary Tree is full\n");
else
printf("The Binary Tree is not full\n");
return(0);
}
Output:
The Binary Tree is full
Time complexity of the above code is O(n) where n is number of nodes in given binary tree.
This article is contributed by Gaurav Gupta. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above
Source
http://www.geeksforgeeks.org/check-whether-binary-tree-full-binary-tree-not/
Category: Trees
Below tree is not a Complete Binary Tree (All the leaves are not aligned to the left. The left
child node of node with data 3 is empty while the right child node is non-empty).
Hence we proceed in the following manner in order to check if the binary tree is complete
binary tree.
1. Calculate the number of nodes (count) in the binary tree.
2. Start recursion of the binary tree from the root node of the binary tree with index (i)
being set as 0 and the number of nodes in the binary (count).
3. If the current node under examination is NULL, then the tree is a complete binary tree.
Return true.
4. If index (i) of the current node is greater than or equal to the number of nodes in the
binary tree (count) i.e. (i>= count), then the tree is not a complete binary. Return false.
5. Recursively check the left and right sub-trees of the binary tree for same condition. For
the left sub-tree use the index as (2*i + 1) while for the right sub-tree use the index as
(2*i + 2).
The time complexity of the above algorithm is O(n). Following is C code for checking if a
binary tree is a complete binary tree.
// Driver program
int main()
{
// Le us create tree in the last diagram above
struct Node* root = NULL;
root = newNode(1);
root->left = newNode(2);
root->right = newNode(3);
root->left->left = newNode(4);
root->left->right = newNode(5);
root->right->right = newNode(6);
Output:
This article is contributed by Gaurav Gupta. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above.
Source
http://www.geeksforgeeks.org/check-whether-binary-tree-complete-not-set-2-recursive-
solution/
Vertex Cover Problem | Set 2 (Dynamic Programming Solution for
Tree)
A vertex cover of an undirected graph is a subset of its vertices such that for every edge (u,
v) of the graph, either u or v is in vertex cover. Although the name is Vertex Cover, the set
covers all edges of the given graph.
The problem to find minimum size vertex cover of a graph is NP complete. But it can be
solved in polynomial time for trees. In this post a solution for Binary Tree is discussed. The
same solution can be extended for n-ary trees.
For example, consider the following binary tree. The smallest vertex cover is {20, 50, 30}
and size of the vertex cover is 3.
The idea is to consider following two possibilities for root and recursively for all nodes
down the root.
1) Root is part of vertex cover: In this case root covers all children edges. We recursively
calculate size of vertex covers for left and right subtrees and add 1 to the result (for root).
2) Root is not part of vertex cover: In this case, both children of root must be included in
vertex cover to cover all root to children edges. We recursively calculate size of vertex
covers of all grandchildren and number of children to the result (for two children of root).
Below is C implementation of above idea.
// A naive recursive C implementation for vertex cover problem for a tree
#include <stdio.h>
#include <stdlib.h>
/* A binary tree node has data, pointer to left child and a pointer to
right child */
struct node
{
int data;
struct node *left, *right;
};
return 0;
}
Output:
Size of the smallest vertex cover is 3
Time complexity of the above naive recursive approach is exponential. It should be noted
that the above function computes the same subproblems again and again. For example,
vCover of node with value 50 is evaluated twice as 50 is grandchild of 10 and child of 20.
Since same suproblems are called again, this problem has Overlapping Subprolems
property. So Vertex Cover problem has both properties (see thisand this) of a dynamic
programming problem. Like other typical Dynamic Programming(DP) problems, re-
computations of same subproblems can be avoided by storing the solutions to subproblems
and solving problems in bottom up manner.
Following is C implementation of Dynamic Programming based solution. In the following
solution, an additional field vc is added to tree nodes. The initial value of vc is set as 0 for
all nodes. The recursive function vCover() calculates vc for a node only if it is not already
set.
/* A binary tree node has data, pointer to left child and a pointer to
right child */
struct node
{
int data;
int vc;
struct node *left, *right;
};
return root->vc;
}
return 0;
}
Output:
Size of the smallest vertex cover is 3
References:
http://courses.csail.mit.edu/6.006/spring11/lectures/lec21.pdf
Exercise:
Extend the above solution for n-ary trees.
This article is contributed by Udit Gupta. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above
Source
http://www.geeksforgeeks.org/vertex-cover-problem-set-2-dynamic-programming-
solution-tree/
We have discussed two methods in thispost. The method 1 requires O(n) time. The method
2 takes O(h) time where h is height of BST, but requires augmenting the BST (storing count
of nodes in left subtree with every node).
Can we find kth largest element in better than O(n) time and no augmentation?
We strongly recommend to minimize your browser and try this yourself first.
In this post, a method is discussed that takes O(h + k) time. This method doesnt require
any change to BST.
The idea is to do reverse inorder traversal of BST. The reverse inorder traversal traverses
all nodes in decreasing order. While doing the traversal, we keep track of count of nodes
visited so far. When the count becomes equal to k, we stop the traversal and print the key.
struct Node
{
int key;
Node *left, *right;
};
int c = 0;
for (int k=1; k<=7; k++)
kthLargest(root, k);
return 0;
}
Time complexity: The code first traverses down to the rightmost node which takes O(h)
time, then traverses k elements in O(k) time. Therefore overall time complexity is O(h + k).
This article is contributed by Chirag Sharma. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above
Source
http://www.geeksforgeeks.org/kth-largest-element-in-bst-when-modification-to-bst-is-
not-allowed/
Category: Trees
Given a binary tree, how do you remove all the half nodes?
Given A binary Tree, how do you remove all the half nodes (which has only one child)? Note
leaves should not be touched as they have both children as NULL.
For example consider the below tree.
Nodes 7, 5 and 9 are half nodes as one of their child is Null. We need to remove all such half
nodes and return the root pointer of following new tree.
We strongly recommend to minimize your browser and try this yourself first.
The idea is to use post-order traversal to solve this problem efficiently. We first process the
left children, then right children, and finally the node itself. So we form the new tree bottom
up, starting from the leaves towards the root. By the time we process the current node,
both its left and right subtrees were already processed. Below is C implementation of this
idea.
// C program to remove all half nodes
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
struct node* left, *right;
};
root->left = RemoveHalfNodes(root->left);
root->right = RemoveHalfNodes(root->right);
return root;
}
// Driver program
int main(void)
{
struct node*NewRoot=NULL;
struct node *root = newNode(2);
root->left = newNode(7);
root->right = newNode(5);
root->left->right = newNode(6);
root->left->right->left=newNode(1);
root->left->right->right=newNode(11);
root->right->right=newNode(9);
root->right->right->left=newNode(4);
NewRoot = RemoveHalfNodes(root);
Output:
Inorder traversal of given tree
7 1 6 11 2 5 4 9
Inorder traversal of the modified tree
1 6 11 2 4
Time complexity of the above solution is O(n) as it does a simple traversal of binary tree.
This article is contributed by Jyoti Saini. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above
Source
http://www.geeksforgeeks.org/given-a-binary-tree-how-do-you-remove-all-the-half-
nodes/
Category: Trees
Source
http://www.geeksforgeeks.org/advantages-of-bst-over-hash-table/
Category: Trees Tags: Hashing
L = (k - 1)*I + 1
Where L = Number of leaf nodes
I = Number of internal nodes
Proof:
Proof can be divided in two cases.
Case 1 (Root is Leaf):There is only one node in tree. The above formula is true for single
node as L = 1, I = 0.
Case 2 (Root is Internal Node): For trees with more than 1 nodes, root is always internal
node. The above formula can be proved using Handshaking Lemma for this case. A tree is
an undirected acyclic graph.
Total number of edges in Tree is number of nodes minus 1, i.e., |E| = L + I 1.
All internal nodes except root in the given type of tree have degree k + 1. Root has degree k.
All leaves have degree 1. Applying the Handshaking lemma to such trees, we get following
relation.
So the above property is proved using Handshaking Lemma, let us discuss one more
interesting property.
2) In Binary tree, number of leaf nodes is always one more than nodes with two
children.
L = T + 1
Where L = Number of leaf nodes
T = Number of internal nodes with two children
Proof:
Let number of nodes with 2 children be T. Proof can be divided in three cases.
Source
http://www.geeksforgeeks.org/handshaking-lemma-and-interesting-tree-properties/
12
/ \
10 20
/ \ /
9 11 12
/ \
10 12
A Better Solution is to augment every tree node to store count together with regular fields
like key, left and right pointers.
Insertion of keys 12, 10, 20, 9, 11, 10, 12, 12 in an empty Binary Search Tree would create
following.
12(3)
/ \
10(2) 20(1)
/ \
9(1) 11(1)
struct node
{
int key;
int count;
struct node *left, *right;
};
printf("\nDelete 20\n");
root = deleteNode(root, 20);
printf("Inorder traversal of the modified tree \n");
inorder(root);
printf("\nDelete 12\n");
root = deleteNode(root, 12);
printf("Inorder traversal of the modified tree \n");
inorder(root);
printf("\nDelete 9\n");
root = deleteNode(root, 9);
printf("Inorder traversal of the modified tree \n");
inorder(root);
return 0;
}
Output:
Inorder traversal of the given tree
9(1) 10(2) 11(1) 12(3) 20(1)
Delete 20
Inorder traversal of the modified tree
9(1) 10(2) 11(1) 12(3)
Delete 12
Inorder traversal of the modified tree
9(1) 10(2) 11(1) 12(2)
Delete 9
Inorder traversal of the modified tree
10(2) 11(1) 12(2)
We will soon be discussing AVL and Red Black Trees with duplicates allowed.
This article is contributed by Chirag. Please write comments if you find anything incorrect,
or you want to share more information about the topic discussed above
Source
http://www.geeksforgeeks.org/how-to-handle-duplicates-in-binary-search-tree/
Category: Trees
Post navigation
Amazon Interview Experience | Set 188 (For SDE1) Flipkart Interview Experience | Set
25
Writing code in comment? Please use code.geeksforgeeks.org, generate link and share the
link here.
Input:
10
/ \
5 50
/ / \
1 40 100
Range: [5, 45]
Output: 3
There are three nodes in range, 5, 10 and 40
// A BST node
struct node
{
int data;
struct node* left, *right;
};
// Utility function to create new node
node *newNode(int data)
{
node *temp = new node;
temp->data = data;
temp->left = temp->right = NULL;
return (temp);
}
// Driver program
int main()
{
// Let us construct the BST shown in the above figure
node *root = newNode(10);
root->left = newNode(5);
root->right = newNode(50);
root->left->left = newNode(1);
root->right->left = newNode(40);
root->right->right = newNode(100);
/* Let us constructed BST shown in above example
10
/ \
5 50
/ / \
1 40 100 */
int l = 5;
int h = 45;
cout << "Count of nodes between [" << l << ", " << h
<< "] is " << getCount(root, l, h);
return 0;
}
Output:
Count of nodes between [5, 45] is 3
Time complexity of the above program is O(h + k) where h is height of BST and k is number
of nodes in given range.
This article is contributed by Gaurav Ahirwar. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above.
Source
http://www.geeksforgeeks.org/count-bst-nodes-that-are-in-a-given-range/
Category: Trees
Input:
10
/ \
5 50
/ / \
1 40 100
Range: [5, 45]
Output: 1
There is only 1 node whose subtree is in the given range.
The node is 40
Input:
10
/ \
5 50
/ / \
1 40 100
Range: [1, 45]
Output: 3
There are three nodes whose subtree is in the given range.
The nodes are 1, 5 and 40
We strongly recommend you to minimize your browser and try this yourself first.
The idea is to traverse the given Binary Search Tree (BST) in bottom up manner. For every
node, recur for its subtrees, if subtrees are in range and the nodes is also in range, then
increment count and return true (to tell the parent about its status). Count is passed as a
pointer so that it can be incremented across all function calls.
Below is C++ implementation of the above idea.
// A BST node
struct node
{
int data;
struct node* left, *right;
};
// If both left and right subtrees are in range and current node
// is also in range, then increment count and return true
if (l && r && inRange(root, low, high))
{
++*count;
return true;
}
return false;
}
// Driver program
int main()
{
// Let us construct the BST shown in the above figure
node *root = newNode(10);
root->left = newNode(5);
root->right = newNode(50);
root->left->left = newNode(1);
root->right->left = newNode(40);
root->right->right = newNode(100);
/* Let us constructed BST shown in above example
10
/ \
5 50
/ / \
1 40 100 */
int l = 5;
int h = 45;
cout << "Count of subtrees in [" << l << ", "
<< h << "] is " << getCount(root, l, h);
return 0;
}
Output:
Count of subtrees in [5, 45] is 1
This article is contributed by Gaurav Ahirwar. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above.
Source
http://www.geeksforgeeks.org/count-bst-subtrees-that-lie-in-given-range/
Category: Trees
Post navigation
Amazon Interview Experience | 193 (For SDE-1) Shortest Common Supersequence
Writing code in comment? Please use code.geeksforgeeks.org, generate link and share the
link here.
// A BST node
struct Node
{
int key;
Node *left, *right;
};
// A function to find
int KSmallestUsingMorris(Node *root, int k)
{
// Count to iterate over elements till we
// get the kth smallest number
int count = 0;
int ksmall = INT_MIN; // store the Kth smallest
Node *curr = root; // to store the current node
// building links
if (pre->right==NULL)
{
//link made to Inorder Successor
pre->right = curr;
curr = curr->left;
}
count++;
// If count is equal to K then we found
// the kth smallest and so store it in ksmall
if (count==k)
ksmall = curr->key;
curr = curr->right;
}
}
}
return ksmall; //return the found value
}
return 0;
}
Output:
20 30 40 50 60 70 80
This article is contributed by Abhishek Somani. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above
Source
http://www.geeksforgeeks.org/kth-largest-element-in-bst-using-o1-extra-space/
Category: Trees
// node structure
struct node
{
int key;
struct node *left, *right;
};
/* now looping through all left and right subtrees and connecting
them to ith root below */
for (int j = 0; j < leftSubtree.size(); j++)
{
struct node* left = leftSubtree[j];
for (int k = 0; k < rightSubtree.size(); k++)
{
struct node * right = rightSubtree[k];
struct node * node = newNode(i);// making value i as root
node->left = left; // connect left subtree
node->right = right; // connect right subtree
list.push_back(node); // add this tree to list
}
}
}
return list;
}
Output:
Preorder traversal of all constructed BSTs is
1 2 3
1 3 2
2 1 3
3 1 2
3 2 1
This article is contributed by Utkarsh Trivedi. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above
Source
http://www.geeksforgeeks.org/construct-all-possible-bsts-for-keys-1-to-n/
Category: Trees
Expression Tree
Expression tree is a binary tree in which each internal node corresponds to operator and
each leaf node corresponds to operand so for example expression tree for 3 + ((5+9)*2)
would be:
Inorder traversal of expression tree produces infix version of given postfix expression
(same with preorder traversal it gives prefix expression)
Evaluating the expression represented by expression tree:
return t;
}
Output:
infix expression is
a + b - e * f * g
This article is contributed by Utkarsh Trivedi. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above.
Source
http://www.geeksforgeeks.org/expression-tree/
Category: Trees
return max_single;
}
Output:
Max path sum is 42
Source
http://www.geeksforgeeks.org/find-maximum-path-sum-in-a-binary-tree/
Category: Trees
A Self Balancing Binary Search Tree like AVL Tree, Red-Black Tree, etc can also support
above operations with same time complexities.
1. Finding minimum and maximum are not naturally O(1), but can be easily implemented
in O(1) by keeping an extra pointer to minimum or maximum and updating the pointer
with insertion and deletion if required. With deletion we can update by finding inorder
predecessor or successor.
2. Inserting an element is naturally O(Logn)
3. Removing maximum or minimum are also O(Logn)
4. Decrease key can be done in O(Logn) by doing a deletion followed by insertion. See
this for details.
So why is Binary Heap Preferred for Priority Queue?
Since Binary Heap is implemented using arrays, there is always better locality of
reference and operations are more cache friendly.
Although operations are of same time complexity, constants in Binary Search Tree are
higher.
We can build a Binary Heap in O(n) time. Self Balancing BSTs require O(nLogn) time to
construct.
Binary Heap doesnt require extra space for pointers.
Binary Heap is easier to implement.
There are variations of Binary Heap like Fibonacci Heap that can support insert and
decrease-key in (1) time
Is Binary Heap always better?
Although Binary Heap is for Priority Queue, BSTs have their own advantages and the list of
advantages is in-fact bigger compared to binary heap.
Searching an element in self-balancing BST is O(Logn) which is O(n) in Binary Heap.
We can print all elements of BST in sorted order in O(n) time, but Binary Heap
requires O(nLogn) time.
Floor and ceil can be found in O(Logn) time.
Kth largest/smallest elementbe found in O(Logn) time by augmenting tree with an
additional field.
This article is contributed by Vivek Gupta. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above
Source
http://www.geeksforgeeks.org/why-is-binary-heap-preferred-over-bst-for-priority-
queue/
Given two Binary Search Trees, find common nodes in them. In other words, find
intersection of two BSTs.
Example:
We strongly recommend you to minimize your browser and try this yourself first.
Method 1 (Simple Solution) A simple way is to one by once search every node of first tree
in second tree. Time complexity of this solution is O(m * h) where m is number of nodes in
first tree and h is height of second tree.
Method 2 (Linear Time) We can find common elements in O(n) time.
1) Do inorder traversal of first tree and store the traversal in an auxiliary array ar1[]. See
sortedInorder() here.
2) Do inorder traversal of second tree and store the traversal in an auxiliary array ar2[]
3) Find intersection of ar1[] and ar2[]. See thisfor details.
Time complexity of this method is O(m+n) where m and n are number of nodes in first and
second tree respectively. This solution requires O(m+n) extra space.
Method 3 (Linear Time and limited Extra Space) We can find common elements in O(n)
time and O(h1 + h2) extra space where h1 and h2 are heights of first and second BSTs
respectively.
The idea is to use iterative inorder traversal. We use two auxiliary stacks for two BSTs.
Since we need to find common elements, whenever we get same element, we print it.
// A BST node
struct Node
{
int key;
struct Node *left, *right;
};
while (1)
{
// push the Nodes of first tree in stack s1
if (root1)
{
s1.push(root1);
root1 = root1->left;
}
// Driver program
int main()
{
// Create first tree as shown in example
Node *root1 = NULL;
root1 = insert(root1, 5);
root1 = insert(root1, 1);
root1 = insert(root1, 10);
root1 = insert(root1, 0);
root1 = insert(root1, 4);
root1 = insert(root1, 7);
root1 = insert(root1, 9);
return 0;
}
Output:
4 7 9 10
This article is contributed by Ekta Goel. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above.
Source
http://www.geeksforgeeks.org/print-common-nodes-in-two-binary-search-trees/
Category: Trees
// out of range
if (ss>se || ss>ue || se<us)
return ;
// Out of range
if (ss>se || ss>qe || se<qs)
return 0;
return 0;
}
Output:
Sum of values in given range = 15
Updated sum of values in given range = 45
This article is contributed by Ankit Mittal. Please write comments if you find anything
incorrect, or you want to share more information about the topic discussed above
Source
http://www.geeksforgeeks.org/lazy-propagation-in-segment-tree/
Category: Trees Tags: Advanced Data Structures
Post navigation
Find maximum value of Sum( i*arr[i]) with only rotations on given array allowed
Longest Repeating Subsequence
Writing code in comment? Please use code.geeksforgeeks.org, generate link and share the
link here.