Trees

Download as pdf or txt
Download as pdf or txt
You are on page 1of 685

FindtheclosestleafinaBinaryTree

GivenaBinaryTreeandakeyk,finddistanceoftheclosestleaffromk.
Examples:

A
/\
BC
/\
EF
/\
GH
/\/
IJK

Closestleafto'H'is'K',sodistanceis1for'H'
Closestleafto'C'is'B',sodistanceis2for'C'
Closestleafto'E'iseither'I'or'J',sodistanceis2for'E'
Closestleafto'B'is'B'itself,sodistanceis0for'B'

Westronglyrecommendtominimizeyourbrowserandtrythisyourselffirst
Themainpointtonotehereisthataclosestkeycaneitherbeadescendentofgivenkeyorcanbereached
throughoneoftheancestors.
Theideaistotraversethegiventreeinpreorderandkeeptrackofancestorsinanarray.Whenwereach
thegivenkey,weevaluatedistanceoftheclosestleafinsubtreerootedwithgivenkey.Wealsotraverseall
ancestorsonebyoneandfinddistanceoftheclosestleafinthesubtreerootedwithancestor.Wecompare
alldistancesandreturnminimum.
// 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;

};

/* Helper function that allocates a new node with the


given data and NULL left and right pocharers. */
Node *newNode(char k)
{
Node *node = new Node;
node->key = k;
node->right = node->left = NULL;
return node;
}

// A utility function to find minimum of x and y


int getMin(int x, int y)
{
return (x < y)? x :y;
}

// A utility function to find distance of closest leaf of the tree


// rooted under given root
int closestDown(struct Node *root)
{
// Base cases
if (root == NULL)
return INT_MAX;
if (root->left == NULL && root->right == NULL)
return 0;

// Return minimum of left and right, plus one


return 1 + getMin(closestDown(root->left), closestDown(root->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);

// Traverse all ancestors and update result if any parent node


// gives smaller distance
for (int i = index-1; i>=0; i--)
res = getMin(res, index - i + closestDown(ancestors[i]));
return res;
}

// 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];

return findClosestUtil(root, k, ancestors, 0);


}

/* Driver program to test above functions*/


int main()
{
// Let us construct the BST shown in the above figure
struct Node *root

= newNode('A');

root->left

= newNode('B');

root->right

= newNode('C');

root->right->left

= newNode('E');

root->right->right

= newNode('F');

root->right->left->left = newNode('G');
root->right->left->left->left = newNode('I');
root->right->left->left->right = newNode('J');
root->right->right->right

= newNode('H');

root->right->right->right->left = newNode('K');

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:

DistaceoftheclosestkeyfromHis1
DistaceoftheclosestkeyfromCis2
DistaceoftheclosestkeyfromEis2
DistaceoftheclosestkeyfromBis0

Theabovecodecanbeoptimizedbystoringtheleft/rightinformationalsoinancestorarray.Theideais,if
givenkeyisinleftsubtreeofanancestors,thenthereisnopointtocallclosestDown().Also,theloopcan
thattraversesancestorsarraycanbeoptimizedtonottraverseancestorswhichareatmoredistancethan
currentresult.

=======================================================

DiagonalSumofaBinaryTree
Considerlinesofslope1passingbetweennodes(dottedlinesinbelowdiagram).Diagonalsuminabinary
treeissumofallnodesdatalyingbetweentheselines.GivenaBinaryTree,printalldiagonalsums.
Forthefollowinginputtree,outputshouldbe9,19,42.
9issumof1,3and5.
19issumof2,6,4and7.
42issumof9,10,11and12.


Westronglyrecommendtominimizeyourbrowserandtrythisyourselffirst
Algorithm:
Theideaistokeeptrackofverticaldistancefromtopdiagonalpassingthroughroot.Weincrementthe
verticaldistancewegodowntonextdiagonal.
1.Addrootwithverticaldistanceas0tothequeue.
2.Processthesumofallrightchildandrightofrightchildandsoon.
3.Addleftchildcurrentnodeintothequeueforlaterprocessing.Theverticaldistanceofleftchildisvertical
distanceofcurrentnodeplus1.
4.Keepdoing2nd,3rdand4thsteptillthequeueisempty.
FollowingisJavaimplementationofaboveidea.
// Java Program to find diagonal sum in a Binary Tree
import java.util.*;
import java.util.Map.Entry;

//Tree node
class TreeNode
{
int data; //node data
int vd; //vertical distance diagonally
TreeNode left, right; //left and right child's reference

// Tree node constructor


public TreeNode(int data)
{
this.data = data;
vd = Integer.MAX_VALUE;
left = right = null;
}
}

// Tree class
class Tree
{
TreeNode root;//Tree root

// Tree constructor
public Tree(TreeNode root) { this.root = root; }

// Diagonal sum method


public void diagonalSum()
{
// Queue which stores tree nodes
Queue<TreeNode> queue = new LinkedList<TreeNode>();

// Map to store sum of node's data lying diagonally


Map<Integer, Integer> map = new TreeMap<>();

// Assign the root's vertical distance as 0.


root.vd = 0;

// Add root node to the queue


queue.add(root);

// Loop while the queue is not empty


while (!queue.isEmpty())
{
// Remove the front tree node from queue.
TreeNode curr = queue.remove();

// Get the vertical distance of the dequeued node.


int vd = curr.vd;

// Sum over this node's right-child, right-of-right-child


// and so on
while (curr != null)
{
int prevSum = (map.get(vd) == null)? 0: map.get(vd);
map.put(vd, prevSum + curr.data);

// If for any node the left child is not null add


// it to the queue for future processing.
if (curr.left != null)
{
curr.left.vd = vd+1;
queue.add(curr.left);
}

// Move to the current node's right child.


curr = curr.right;
}
}

// Make an entry set from map.


Set<Entry<Integer, Integer>> set = map.entrySet();

// Make an iterator
Iterator<Entry<Integer, Integer>> iterator = set.iterator();

// Traverse the map elements using the iterator.


while (iterator.hasNext())
{
Map.Entry<Integer, Integer> me = iterator.next();
System.out.print(me.getValue()+" ");
}
}
}

//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

=======================================================

BottomViewofaBinaryTree
GivenaBinaryTree,weneedtoprintthebottomviewfromlefttoright.Anodexisthereinoutputifxisthe
bottommostnodeatitshorizontaldistance.Horizontaldistanceofleftchildofanodexisequaltohorizontal
distanceofxminus1,andthatofrightchildishorizontaldistanceofxplus1.
Examples:

20
/\
822
/\\
5325
/\
1014

Fortheabovetreetheoutputshouldbe5,10,3,14,25.
Iftherearemultiplebottommostnodesforahorizontaldistancefromroot,thenprintthelateroneinlevel
traversal.Forexample,inthebelowdiagram,3and4areboththebottommostnodesathorizontaldistance
0,weneedtoprint4.

20
/\
822
/\/\
53425
/\
1014
Fortheabovetreetheoutputshouldbe5,10,4,14,25.
Westronglyrecommendtominimizeyourbrowserandtrythisyourselffirst.
ThefollowingarestepstoprintBottomViewofBianryTree.
1.Weputtreenodesinaqueueforthelevelordertraversal.
2.Startwiththehorizontaldistance(hd)0oftherootnode,keeponaddingleftchildtoqueuealongwiththe
horizontaldistanceashd1andrightchildashd+1.
3.Also,useaTreeMapwhichstoreskeyvaluepairsortedonkey.
4.Everytime,weencounteranewhorizontaldistanceoranexistinghorizontaldistanceputthenodedata
forthehorizontaldistanceaskey.Forthefirsttimeitwilladdtothemap,nexttimeitwillreplacethevalue.

Thiswillmakesurethatthebottommostelementforthathorizontaldistanceispresentinthemapandifyou
seethetreefrombeneaththatyouwillseethatelement.
AJavabasedimplementationisbelow:
// Java Program to print Bottom View of Binary Tree
import java.util.*;
import java.util.Map.Entry;

// Tree node class


class TreeNode
{
int data; //data of the node
int hd; //horizontal distance of the node
TreeNode left, right; //left and right references

// Constructor of tree node


public TreeNode(int key)
{
data = key;
hd = Integer.MAX_VALUE;
left = right = null;
}
}

//Tree class
class Tree
{
TreeNode root; //root node of tree

// Default constructor
public Tree() {}

// Parameterized tree constructor


public Tree(TreeNode node)
{
root = node;
}

// Method that prints the bottom view.


public void bottomView()
{
if (root == null)
return;

// Initialize a variable 'hd' with 0 for the root element.


int hd = 0;

// TreeMap which stores key value pair sorted on key value


Map<Integer, Integer> map = new TreeMap<>();

// Queue to store tree nodes in level order traversal


Queue<TreeNode> queue = new LinkedList<TreeNode>();

// Assign initialized horizontal distance value to root


// node and add it to the queue.
root.hd = hd;
queue.add(root);

// Loop until the queue is empty (standard level order loop)


while (!queue.isEmpty())
{
TreeNode temp = queue.remove();

// Extract the horizontal distance value from the


// dequeued tree node.
hd = temp.hd;

// Put the dequeued tree node to TreeMap having key


// as horizontal distance. Every time we find a node
// having same horizontal distance we need to replace
// the data in the map.
map.put(hd, temp.data);

// If the dequeued node has a left child add it to the


// queue with a horizontal distance hd-1.

if (temp.left != null)
{
temp.left.hd = hd-1;
queue.add(temp.left);
}
// If the dequeued node has a left child add it to the
// queue with a horizontal distance hd+1.
if (temp.right != null)
{
temp.right.hd = hd+1;
queue.add(temp.right);
}
}

// Extract the entries of map into a set to traverse


// an iterator over that.
Set<Entry<Integer, Integer>> set = map.entrySet();

// Make an iterator
Iterator<Entry<Integer, Integer>> iterator = set.iterator();

// Traverse the map elements using the iterator.


while (iterator.hasNext())
{
Map.Entry<Integer, Integer> me = iterator.next();
System.out.print(me.getValue()+" ");
}
}
}

// Main driver class


public class BottomView
{
public static void main(String[] args)
{
TreeNode root = new TreeNode(20);
root.left = new TreeNode(8);

root.right = new TreeNode(22);


root.left.left = new TreeNode(5);
root.left.right = new TreeNode(3);
root.right.left = new TreeNode(4);
root.right.right = new TreeNode(25);
root.left.right.left = new TreeNode(10);
root.left.right.right = new TreeNode(14);
Tree tree = new Tree(root);
System.out.println("Bottom view of the given binary tree:");
tree.bottomView();
}
}
Output:

Bottomviewofthegivenbinarytree:
51041425

=======================================================

BinaryIndexedTreeorFenwicktree
LetusconsiderthefollowingproblemtounderstandBinaryIndexedTree.
Wehaveanarrayarr[0...n1].Weshouldbeableto
1Findthesumoffirstielements.
2Changevalueofaspecifiedelementofthearrayarr[i]=xwhere0<=i<=n1.
Asimplesolutionistorunaloopfrom0toi1andcalculatesumofelements.Toupdateavalue,simplydo
arr[i]=x.ThefirstoperationtakesO(n)timeandsecondoperationtakesO(1)time.Anothersimplesolution
istocreateanotherarrayandstoresumfromstarttoiattheithindexinthisarray.Sumofagivenrange
cannowbecalculatedinO(1)time,butupdateoperationtakesO(n)timenow.Thisworkswellifthenumber
ofqueryoperationsarelargeandveryfewupdates.
CanweperformboththeoperationsinO(logn)timeoncegiventhearray?
OneEfficientSolutionistouseSegmentTreethatdoesbothoperationsinO(Logn)time.
UsingBinaryIndexedTree,wecandobothtasksinO(Logn)time.TheadvantagesofBinaryIndexedTree
overSegmentare,requireslessspaceandveryeasytoimplement..
Representation

BinaryIndexedTreeisrepresentedasanarray.LetthearraybeBITree[].EachnodeofBinaryIndexed
Treestoressumofsomeelementsofgivenarray.SizeofBinaryIndexedTreeisequaltonwherenissize
ofinputarray.Inthebelowcode,wehaveusedsizeasn+1foreaseofimplementation.
Construction
WeconstructtheBinaryIndexedTreebyfirstinitializingallvaluesinBITree[]as0.Thenwecallupdate()
operationforallindexestostoreactualsums,updateisdiscussedbelow.
Operations

getSum(index):Returnssumofarr[0..index]
//Returnssumofarr[0..index]usingBITree[0..n].Itassumesthat
//BITree[]isconstructedforgivenarrayarr[0..n1]
1)Initializesumas0andindexasindex+1.
2)Dofollowingwhileindexisgreaterthan0.
...a)AddBITree[index]tosum
...b)GotoparentofBITree[index].Parentcanbeobtainedbyremoving
thelastsetbitfromindex,i.e.,index=index(index&(index))
3)Returnsum.


TheabovediagramdemonstratesworkingofgetSum().Followingaresomeimportantobservations.
Nodeatindex0isadummynode.
Anodeatindexyisparentofanodeatindexx,iffycanbeobtainedbyremovinglastsetbitfrombinary
representationofx.
Achildxofanodeystoressumofelementsfromofy(exclusivey)andofx(inclusivex).

update(index,val):UpdatesBITforoperationarr[index]+=val
//Notethatarr[]isnotchangedhere.Itchanges
//onlyBITreeforthealreadymadechangeinarr[].
1)Initializeindexasindex+1.
2)Dofollowingwhileindexissmallerthanorequalton.
...a)AddvaluetoBITree[index]
...b)GotoparentofBITree[index].Parentcanbeobtainedbyremoving
thelastsetbitfromindex,i.e.,index=index(index&(index))


TheupdateprocessneedstomakesurethatallBITreenodesthathavearr[i]aspartofthesectionthey
covermustbeupdated.WegetallsuchnodesofBITreebyrepeatedlyaddingthedecimalnumber
correspondingtothelastsetbit.

HowdoesBinaryIndexedTreework?
Theideaisbasedonthefactthatallpositiveintegerscanberepresentedassumofpowersof2.For
example19canberepresentedas16+2+1.EverynodeofBITreestoressumofnelementswherenisa
powerof2.Forexample,intheabovefirstdiagramforgetSum(),sumoffirst12elementscanbeobtained
bysumoflast4elements(from9to12)plussumof8elements(from1to8).Thenumberofsetbitsin
binaryrepresentationofanumbernisO(Logn).Therefore,wetraverseatmostO(Logn)nodesinboth
getSum()andupdate()operations.TimecomplexityofconstructionisO(nLogn)asitcallsupdate()foralln
elements.

Implementation:
FollowingisC++implementationofBinaryIndexedTree.
// C++ code to demonstrate operations of Binary Index Tree
#include <iostream>
using namespace std;

/*

n --> No. of elements present in input array.


BITree[0..n] --> Array that represents Binary Indexed Tree.
arr[0..n-1] --> Input array for whic prefix sum is evaluated. */

// Returns sum of arr[0..index]. This function assumes


// that the array is preprocessed and partial sums of
// array elements are stored in BITree[].
int getSum(int BITree[], int n, int index)
{
int sum = 0; // Iniialize result

// index in BITree[] is 1 more than the index in arr[]


index = index + 1;

// Traverse ancestors of BITree[index]


while (index>0)
{
// Add current element of BITree to sum
sum += BITree[index];

// Move index to parent node


index -= index & (-index);
}
return sum;
}

// Updates a node in Binary Index Tree (BITree) at given index


// in BITree. The given value 'val' is added to BITree[i] and
// all of its ancestors in tree.
void updateBIT(int *BITree, int n, int index, int val)
{

// index in BITree[] is 1 more than the index in arr[]


index = index + 1;

// Traverse all ancestors and add 'val'


while (index <= n)
{
// Add 'val' to current node of BI Tree
BITree[index] += val;

// Update index to that of parent


index += index & (-index);
}
}

// Constructs and returns a Binary Indexed Tree for given


// array of size n.
int *constructBITree(int arr[], int n)
{
// Create and initialize BITree[] as 0
int *BITree = new int[n+1];
for (int i=1; i<=n; i++)
BITree[i] = 0;

// Store the actual values in BITree[] using update()


for (int i=0; i<n; i++)
updateBIT(BITree, n, i, arr[i]);

// Uncomment below lines to see contents of BITree[]


//for (int i=1; i<=n; i++)
//

cout << BITree[i] << " ";

return BITree;
}

// Driver program to test above functions


int main()

{
int freq[] = {2, 1, 1, 3, 2, 3, 4, 5, 6, 7, 8, 9};
int n = sizeof(freq)/sizeof(freq[0]);
int *BITree = constructBITree(freq, n);
cout << "Sum of elements in arr[0..5] is "
<< getSum(BITree, n, 5);

// Let use test the update operation


freq[3] += 6;
updateBIT(BITree, n, 3, 6); //Update BIT for above change in arr[]

cout << "\nSum of elements in arr[0..5] after update is "


<< getSum(BITree, n, 5);

return 0;
}
Output:

Sumofelementsinarr[0..5]is12
Sumofelementsinarr[0..5]afterupdateis18

CanweextendtheBinaryIndexedTreeforrangeSuminLogntime?
Thisissimpletoanswer.TherangeSum(l,r)canbeobtainedasgetSum(r)getSum(l1).

=======================================================

HowtoImplementReverseDNS
LookUpCache?
ReverseDNSlookupisusinganinternetIPaddresstofindadomainname.Forexample,ifyoutype
74.125.200.106inbrowser,itautomaticallyredirectstogoogle.in.
HowtoimplementReverseDNSLookUpcache?Followingaretheoperationsneededfromcache.
1)AddaIPaddresstoURLMappingincache.
2)FindURLforagivenIPaddress.
OnesolutionistouseHashing.

Inthispost,aTriebasedsolutionisdiscussed.OneadvantageofTriebasedsolutionsis,worstcaseupper
boundisO(1)forTrie,forhashing,thebestpossibleaveragecasetimecomplexityisO(1).Also,withTrie
wecanimplementprefixsearch(findingallurlsforacommonprefixofIPaddresses).
ThegeneraldisadvantageofTrieislargeamountofmemoryrequirement,thisisnotamajorproblemhere
asthealphabetsizeisonly11here.Tencharactersareneededfordigitsfrom0to9andonefordot(.).
TheideaistostoreIPaddressesinTrienodesandinthelastnodewestorethecorrespondingdomain
name.FollowingisCstyleimplementationinC++.
// C based program to implement reverse DNS lookup
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

// There are atmost 11 different chars in a valid IP address


#define CHARS 11

// Maximum length of a valid IP address


#define MAX 50

// A utility function to find index of child for a given character 'c'


int getIndex(char c) { return (c == '.')? 10: (c - '0'); }

// A utility function to find character for a given child index.


char getCharFromIndex(int i) { return (i== 10)? '.' : ('0' + i); }

// Trie Node.
struct trieNode
{
bool isLeaf;
char *URL;
struct trieNode *child[CHARS];
};

// Function to create a new trie node.


struct trieNode *newTrieNode(void)
{
struct trieNode *newNode = new trieNode;
newNode->isLeaf = false;

newNode->URL = NULL;
for (int i=0; i<CHARS; i++)
newNode->child[i] = NULL;
return newNode;
}

// This method inserts an ip address and the corresponding


// domain name in the trie. The last node in Trie contains the URL.
void insert(struct trieNode *root, char *ipAdd, char *URL)
{
// Length of the ip address
int len = strlen(ipAdd);
struct trieNode *pCrawl = root;

// Traversing over the length of the ip address.


for (int level=0; level<len; level++)
{
// Get index of child node from current character
// in ipAdd[]. Index must be from 0 to 10 where
// 0 to 9 is used for digits and 10 for dot
int index = getIndex(ipAdd[level]);

// Create a new child if not exist already


if (!pCrawl->child[index])
pCrawl->child[index] = newTrieNode();

// Move to the child


pCrawl = pCrawl->child[index];
}

//Below needs to be carried out for the last node.


//Save the corresponding URL of the ip address in the
//last node of trie.
pCrawl->isLeaf = true;
pCrawl->URL = new char[strlen(URL) + 1];
strcpy(pCrawl->URL, URL);
}

// This function returns URL if given IP address is present in DNS cache.


// Else returns NULL
char *searchDNSCache(struct trieNode *root, char *ipAdd)
{
// Root node of trie.
struct trieNode *pCrawl = root;
int len = strlen(ipAdd);

// Traversal over the length of ip address.


for (int level=0; level<len; level++)
{
int index = getIndex(ipAdd[level]);
if (!pCrawl->child[index])
return NULL;
pCrawl = pCrawl->child[index];
}

// 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]);

// If reverse DNS look up succeeds print the domain


// name along with DNS resolved.
char ip[] = "107.108.11.123";
char *res_url = searchDNSCache(root, ip);
if (res_url != NULL)
printf("Reverse DNS look up resolved in cache:\n%s --> %s",
ip, res_url);
else
printf("Reverse DNS look up not resolved in cache ");
return 0;
}
Output:

ReverseDNSlookupresolvedincache:
107.108.11.123>www.samsung.com

=======================================================

Givennappointments,findall
conflictingappointments
Givennappointments,findallconflictingappointments.
Examples:

Input:appointments[]={{1,5}{3,7},{2,6},{10,15},{5,6},{4,100}}
Output:Followingareconflictingintervals
[3,7]Conflictswith[1,5]
[2,6]Conflictswith[1,5]
[5,6]Conflictswith[3,7]
[4,100]Conflictswith[1,5]
Anappointmentisconflicting,ifitconflictswithanyofthepreviousappointmentsinarray.
Westronglyrecommendtominimizethebrowserandtrythisyourselffirst.

ASimpleSolutionistoonebyoneprocessallappointmentsfromsecondappointmenttolast.Forevery
appointmenti,checkifitconflictswithi1,i2,0.ThetimecomplexityofthismethodisO(n2).
WecanuseIntervalTreetosolvethisprobleminO(nLogn)time.Followingisdetailedalgorithm.

1)CreateanIntervalTree,initiallywiththefirstappointment.
2)Dofollowingforallotherappointmentsstartingfromthesecondone.
a)Checkifthecurrentappointmentconflictswithanyoftheexisting
appointmentsinIntervalTree.Ifconflicts,thenprintthecurrent
appointment.ThisstepcanbedoneO(Logn)time.
b)InsertthecurrentappointmentinIntervalTree.Thisstepalsocan
bedoneO(Logn)time.
FollowingisC++implementationofaboveidea.
// C++ program to print all conflicting appointments in a
// given set of appointments
#include <iostream>
using namespace std;

// Structure to represent an interval


struct Interval
{
int low, high;
};

// Structure to represent a node in Interval Search Tree


struct ITNode
{
Interval *i; // 'i' could also be a normal variable
int max;
ITNode *left, *right;
};

// A utility function to create a new Interval Search Tree Node


ITNode * newNode(Interval i)
{
ITNode *temp = new ITNode;
temp->i = new Interval(i);
temp->max = i.high;
temp->left = temp->right = NULL;

};

// A utility function to insert a new Interval Search Tree


// Node. This is similar to BST Insert. Here the low value
// of interval is used tomaintain BST property
ITNode *insert(ITNode *root, Interval i)
{
// Base case: Tree is empty, new node becomes root
if (root == NULL)
return newNode(i);

// Get low value of interval at root


int l = root->i->low;

// If root's low value is smaller, then new interval


// goes to left subtree
if (i.low < l)
root->left = insert(root->left, i);

// Else, new node goes to right subtree.


else
root->right = insert(root->right, i);

// Update the max value of this ancestor if needed


if (root->max < i.high)
root->max = i.high;

return root;
}

// A utility function to check if given two intervals overlap


bool doOVerlap(Interval i1, Interval i2)
{
if (i1.low < i2.high && i2.low < i1.high)
return true;
return false;
}

// The main function that searches a given interval i


// in a given Interval Tree.
Interval *overlapSearch(ITNode *root, Interval i)
{
// Base Case, tree is empty
if (root == NULL) return NULL;

// If given interval overlaps with root


if (doOVerlap(*(root->i), i))
return root->i;

// If left child of root is present and max of left child


// is greater than or equal to given interval, then i may
// overlap with an interval is left subtree
if (root->left != NULL && root->left->max >= i.low)
return overlapSearch(root->left, i);

// Else interval can only overlap with right subtree


return overlapSearch(root->right, i);
}

// This function prints all conflicting appointments in a given


// array of apointments.
void printConflicting(Interval appt[], int n)
{
// Create an empty Interval Search Tree, add first
// appointment
ITNode *root = NULL;
root = insert(root, appt[0]);

// Process rest of the intervals


for (int i=1; i<n; i++)
{
// If current appointment conflicts with any of the
// existing intervals, print it
Interval *res = overlapSearch(root, appt[i]);

if (res != NULL)
cout << "[" << appt[i].low << "," << appt[i].high
<< "] Conflicts with [" << res->low << ","
<< res->high << "]\n";

// Insert this appointment


root = insert(root, appt[i]);
}
}

// Driver program to test above functions


int main()
{
// Let us create interval tree shown in above figure
Interval appt[] = { {1, 5}, {3, 7}, {2, 6}, {10, 15},
{5, 6}, {4, 100}};
int n = sizeof(appt)/sizeof(appt[0]);
cout << "Following are conflicting intervals\n";
printConflicting(appt, n);
return 0;
}
Output:

Followingareconflictingintervals
[3,7]Conflictswith[1,5]
[2,6]Conflictswith[1,5]
[5,6]Conflictswith[3,7]
[4,100]Conflictswith[1,5]

=======================================================

PerfectBinaryTreeSpecificLevel
OrderTraversal
GivenaPerfectBinaryTreelikebelow:
(clickonimagetogetaclearview)

Printthelevelorderofnodesinfollowingspecificmanner:
12347568159141013111216311730182919282027212622252324

i.e.printnodesinlevelorderbutnodesshouldbefromleftandrightsidealternatively.Here1stand2ndlevels
aretrivial.
While3rdlevel:4(left),7(right),5(left),6(right)areprinted.
While4thlevel:8(left),15(right),9(left),14(right),..areprinted.
While5thlevel:16(left),31(right),17(left),30(right),..areprinted.
Westronglyrecommendtominimizeyourbrowserandtrythisyourselffirst.
InstandardLevelOrderTraversal,weenqueuerootintoaqueue1st,thenwedequeueONEnodefrom
queue,process(print)it,enqueueitschildrenintoqueue.Wekeepdoingthisuntilqueueisempty.
Approach1:
Wecandostandardlevelordertraversalheretoobutinsteadofprintingnodesdirectly,wehavetostore
nodesincurrentlevelinatemporaryarrayorlist1standthentakenodesfromalternateends(leftandright)
andprintnodes.Keeprepeatingthisforalllevels.
Thisapproachtakesmorememorythanstandardtraversal.
Approach2:
Thestandardlevelordertraversalideawillslightlychangehere.InsteadofprocessingONEnodeatatime,
wewillprocessTWOnodesatatime.Andwhilepushingchildrenintoqueue,theenqueueorderwillbe:1st
nodesleftchild,2ndnodesrightchild,1stnodesrightchildand2ndnodesleftchild.
/* C++ program for special order traversal */
#include <iostream>
#include <queue>

using namespace std;

/* A binary tree node has data, pointer to left child


and a pointer to right child */
struct Node
{
int data;
Node *left;
Node *right;
};

/* Helper function that allocates a new node with the


given data and NULL left and right pointers. */
Node *newNode(int data)
{
Node *node = new Node;
node->data = data;
node->right = node->left = NULL;
return node;
}

/* Given a perfect binary tree, print its nodes in specific


level order */
void printSpecificLevelOrder(Node *root)
{
if (root == NULL)
return;

// Let us print root and next level first


cout << root->data;

// / Since it is perfect Binary Tree, right is not checked


if (root->left != NULL)
cout << " " << root->left->data << " " << root->right->data;

// Do anything more if there are nodes at next level in


// given perfect Binary Tree

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

// Create a queue and enqueue left and right children of root


queue <Node *> q;
q.push(root->left);
q.push(root->right);

// We process two nodes at a time, so we need two variables


// to store two front items of queue
Node *first = NULL, *second = NULL;

// traversal loop
while (!q.empty())
{
// Pop two items from queue
first = q.front();
q.pop();
second = q.front();
q.pop();

// Print children of first and second in reverse order


cout << " " << first->left->data << " " << second->right->data;
cout << " " << first->right->data << " " << second->left->data;

// If first and second have grandchildren, enqueue them


// in reverse order
if (first->left->left != NULL)
{
q.push(first->left);
q.push(second->right);
q.push(first->right);
q.push(second->left);
}
}
}

/* Driver program to test above functions*/


int main()
{
//Perfect Binary Tree of Height 4
Node *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);
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);

cout << "Specific Level Order traversal of binary tree is \n";


printSpecificLevelOrder(root);

return 0;
}
Output:
SpecificLevelOrdertraversalofbinarytreeis
12347568159141013111216311730182919282027212622252324

=======================================================

PrintNodesinTopViewofBinary
Tree
Topviewofabinarytreeisthesetofnodesvisiblewhenthetreeisviewedfromthetop.Givenabinary
tree,printthetopviewofit.Theoutputnodescanbeprintedinanyorder.ExpectedtimecomplexityisO(n)
Anodexisthereinoutputifxisthetopmostnodeatitshorizontaldistance.Horizontaldistanceofleftchild
ofanodexisequaltohorizontaldistanceofxminus1,andthatofrightchildishorizontaldistanceofxplus
1.

1
/\
23
/\/\
4567
Topviewoftheabovebinarytreeis
42137

1
/\
23
\
4
\

5
\
6
Topviewoftheabovebinarytreeis
2136
Westronglyrecommendtominimizeyourbrowserandtrythisyourselffirst.
TheideaistodosomethingsimilartoverticalOrderTraversal.LikeverticalOrderTraversal,weneedto
nodesofsamehorizontaldistancetogether.Wedoalevelordertraversalsothatthetopmostnodeata
horizontalnodeisvisitedbeforeanyothernodeofsamehorizontaldistancebelowit.Hashingisusedto
checkifanodeatgivenhorizontaldistanceisseenornot.
// Java program to print top view of Binary tree
import java.util.*;

// Class for a tree node


class TreeNode
{
// Members
int key;
TreeNode left, right;

// Constructor
public TreeNode(int key)
{
this.key = key;
left = right = null;
}
}

// A class to represent a queue item. The queue is used to do Level


// order traversal. Every Queue item contains node and horizontal
// distance of node from root
class QItem
{
TreeNode node;
int hd;
public QItem(TreeNode n, int h)
{

node = n;
hd = h;
}
}

// Class for a Binary Tree


class Tree
{
TreeNode root;

// Constructors
public Tree() { root = null; }
public Tree(TreeNode n) { root = n; }

// This method prints nodes in top view of binary tree


public void printTopView()
{
// base case
if (root == null) { return; }

// Creates an empty hashset


HashSet<Integer> set = new HashSet<>();

// Create a queue and add root to it


Queue<QItem> Q = new LinkedList<QItem>();
Q.add(new QItem(root, 0)); // Horizontal distance of root is 0

// Standard BFS or level order traversal loop


while (!Q.isEmpty())
{
// Remove the front item and get its details
QItem qi = Q.remove();
int hd = qi.hd;
TreeNode n = qi.node;

// If this is the first node at its horizontal distance,


// then this node is in top view

if (!set.contains(hd))
{
set.add(hd);
System.out.print(n.key + " ");
}

// Enqueue left and right children of current node


if (n.left != null)
Q.add(new QItem(n.left, hd-1));
if (n.right != null)
Q.add(new QItem(n.right, hd+1));
}
}
}

// Driver class to test above methods


public class Main
{
public static void main(String[] args)
{
/* Create following Binary Tree
1
/ \
2 3
\
4
\
5
\
6*/
TreeNode root = new TreeNode(1);
root.left = new TreeNode(2);
root.right = new TreeNode(3);
root.left.right = new TreeNode(4);
root.left.right.right = new TreeNode(5);
root.left.right.right.right = new TreeNode(6);
Tree t = new Tree(root);

System.out.println("Following are nodes in top view of Binary Tree");


t.printTopView();
}
}
Output:

FollowingarenodesintopviewofBinaryTree
1236

=======================================================

KDimensionalTree
AKDTree(alsocalledasKDimensionalTree)isabinarysearchtreewheredataineachnodeisa
KDimensionalpointinspace.Inshort,itisaspacepartitioning(detailsbelow)datastructurefororganizing
pointsinaKDimensionalspace.
AnonleafnodeinKDtreedividesthespaceintotwoparts,calledashalfspaces.
Pointstotheleftofthisspacearerepresentedbytheleftsubtreeofthatnodeandpointstotherightofthe
spacearerepresentedbytherightsubtree.Wewillsoonbeexplainingtheconceptonhowthespaceis
dividedandtreeisformed.
Forthesakeofsimplicity,letusunderstanda2DTreewithanexample.
Therootwouldhaveanxalignedplane,therootschildrenwouldbothhaveyalignedplanes,theroots
grandchildrenwouldallhavexalignedplanes,andtherootsgreatgrandchildrenwouldallhaveyaligned
planesandsoon.
Generalization:
Letusnumbertheplanesas0,1,2,(K1).Fromtheaboveexample,itisquiteclearthatapoint(node)
atdepthDwillhaveAalignedplanewhereAiscalculatedas:
A=DmodK
Howtodetermineifapointwilllieintheleftsubtreeorinrightsubtree?
IftherootnodeisalignedinplaneA,thentheleftsubtreewillcontainallpointswhosecoordinatesinthat
planearesmallerthanthatofrootnode.Similarly,therightsubtreewillcontainallpointswhosecoordinates
inthatplanearegreaterequaltothatofrootnode.
Creationofa2DTree:
Considerfollowingpointsina2Dplane:
(3,6),(17,15),(13,15),(6,12),(9,1),(2,7),(10,19)
1.

Insert(3,6):Sincetreeisempty,makeittherootnode.

2.

Insert(17,15):Compareitwithrootnodepoint.SincerootnodeisXaligned,theXcoordinatevalue
willbecomparedtodetermineifitliesintherightsubtreeorintherightsubtree.Thispointwillbe
Yaligned.

3.

Insert(13,15):XvalueofthispointisgreaterthanXvalueofpointinrootnode.So,thiswillliein
therightsubtreeof(3,6).AgainCompareYvalueofthispointwiththeYvalueofpoint(17,15)
(Why?).Since,theyareequal,thispointwilllieintherightsubtreeof(17,15).Thispointwillbe
Xaligned.

4.

Insert(6,12):XvalueofthispointisgreaterthanXvalueofpointinrootnode.So,thiswilllieinthe
rightsubtreeof(3,6).AgainCompareYvalueofthispointwiththeYvalueofpoint(17,15)(Why?).
Since,12<15,thispointwilllieintheleftsubtreeof(17,15).ThispointwillbeXaligned.

5.

Insert(9,1):Similarly,thispointwilllieintherightof(6,12).

6.

Insert(2,7):Similarly,thispointwilllieintheleftof(3,6).

7.

Insert(10,19):Similarly,thispointwilllieintheleftof(13,15).

Howisspacepartitioned?
All7pointswillbeplottedintheXYplaneasfollows:
1.

Point(3,6)willdividethespaceintotwoparts:DrawlineX=3.

2.

3.

Point(2,7)willdividethespacetotheleftoflineX=3intotwopartshorizontally.

4.

DrawlineY=7totheleftoflineX=3.

5.

6.

Point(17,15)willdividethespacetotherightoflineX=3intotwopartshorizontally.

7.

DrawlineY=15totherightoflineX=3.

8.

Point(6,12)willdividethespacebelowlineY=15andtotherightoflineX=3intotwoparts.

DrawlineX=6totherightoflineX=3andbelowlineY=15.

Point(13,15)willdividethespacebelowlineY=15andtotherightoflineX=6intotwoparts.

DrawlineX=13totherightoflineX=6andbelowlineY=15.

Point(9,1)willdividethespacebetweenlinesX=3,X=6andY=15intotwoparts.

DrawlineY=1betweenlinesX=3andX=6.

Point(10,19)willdividethespacetotherightoflineX=3andabovelineY=15intotwoparts.

DrawlineY=19totherightoflineX=3andabovelineY=15.

FollowingisC++implementationofKDTreebasicoperationslikesearch,insertanddelete.
// A C++ program to demonstrate operations of KD tree
#include <iostream>
#include <cstdio>
#include <cassert>
#include <cstdlib>
using namespace std;

// A structure to represent a point in K dimensional space


// k: K dimensional space
// coord: An array to represent position of point
struct Point
{
unsigned k;
int* coord; // Coordinate (A pointer to array of size k)
};

// A structure to represent the Input


// n: Number of points in space
// pointArray: An array to keep information of each point
struct Input
{

// n --> NUMBER OF POINTS


unsigned n;
Point* *pointArray;
};

// A structure to represent node of 2 dimensional tree


struct Node
{
Point point;
Node *left, *right;
};

// Creates and return a Point structure


Point* CreatePoint(unsigned k)
{
Point* point = new Point;

// Memory allocation failure


assert(NULL != point);

point->k = k;
point->coord = new int[k];

// Memory allocation failure


assert(NULL != point->coord);

return point;
}

// Creates and returns an Input structure


struct Input* CreateInput(unsigned k, unsigned n)
{
struct Input* input = new Input;

// Memory allocation failure


assert(NULL != input);

input->n = n;
input->pointArray = new Point*[n];

// Memory allocation failure


assert(NULL != input->pointArray);

return input;
}

// A method to create a node of K D tree


struct Node* CreateNode(struct Point* point)
{
struct Node* tempNode = new Node;

// Memory allocation failure


assert(NULL != tempNode);

// Avoid shallow copy [We could have directly use


// the below assignment, But didn't, why?]
/*tempNode->point = point;*/
(tempNode->point).k = point->k;
(tempNode->point).coord = new int[point->k];

// Copy coordinate values


for (int i=0; i<(tempNode->point).k; ++i)
(tempNode->point).coord[i] = point->coord[i];

tempNode->left = tempNode->right = NULL;


return tempNode;
}

// Root is passed as pointer to pointer so that


// The parameter depth is used to decide axis of comparison
void InsertKDTreeUtil(Node * * root, Node* newNode, unsigned depth)
{
// Tree is empty?
if (!*root)

{
*root = newNode;
return;
}

// Calculate axis of comparison to determine left/right


unsigned axisOfComparison = depth % (newNode->point).k;

// 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);
}

// Function to insert a new point in KD Tree. It mainly uses


// above recursive function "InsertKDTreeUtil()"
void InsertKDTree(Node* *root, Point* point)
{
Node* newNode = CreateNode(point);
unsigned zeroDepth = 0;
InsertKDTreeUtil(root, newNode, zeroDepth);
}

// A utility method to determine if two Points are same


// in K Dimensional space
int ArePointsSame(Point firstPoint, Point secondPoint)
{
if (firstPoint.k != secondPoint.k)
return 0;

// Compare individual coordinate values


for (int i = 0; i < firstPoint.k; ++i)
if (firstPoint.coord[i] != secondPoint.coord[i])
return 0;

return 1;
}

// Searches a Point in the K D tree. The parameter depth is used


// to determine current axis.
int SearchKDTreeUtil(Node* root, Point point, unsigned depth)
{
if (!root)
return 0;

if (ArePointsSame(root->point, point))
return 1;

unsigned axisOfComparison = depth % point.k;

if (point.coord[axisOfComparison] <
(root->point).coord[axisOfComparison])
return SearchKDTreeUtil(root->left, point, depth + 1);

return SearchKDTreeUtil(root->right, point, depth + 1);


}

// Searches a Point in the K D tree. It mainly uses


// SearchKDTreeUtil()
int SearchKDTree(Node* root, Point point)
{
unsigned zeroDepth = 0;
return SearchKDTreeUtil(root, point, zeroDepth);
}

// Creates a KD tree from given input points. It mainly


// uses InsertKDTree
Node* CreateKDTree(Input* input)
{
Node* root = NULL;
for (int i = 0; i < input->n; ++i)

InsertKDTree(&root, input->pointArray[i]);
return root;
}

// A utility function to print an array


void PrintArray(int* array, unsigned size)
{
for (unsigned i = 0; i < size; ++i)
cout << array[i];
cout << endl;
}

// A utility function to do inorder tree traversal


void inorderKD(Node* root)
{
if (root)
{
inorderKD(root->left);
PrintArray((root->point).coord, (root->point).k);
inorderKD(root->right);
}
}

// Driver program to test above functions


int main()
{
// 2 Dimensional tree [For the sake of simplicity]
unsigned k = 2;

// Total number of Points is 7


unsigned n = 7;
Input* input = CreateInput(k, n);

// itc --> ITERATOR for coord


// itp --> ITERATOR for POINTS
for (int itp = 0; itp < n; ++itp)
{

input->pointArray[itp] = CreatePoint(k);

for (int itc = 0; itc < k; ++itc)


input->pointArray[itp]->coord[itc] = rand() % 20;

PrintArray(input->pointArray[itp]->coord, k);
}

Node* root = CreateKDTree(input);

cout << "Inorder traversal of K-D Tree created is:\n";


inorderKD(root);

return 0;
}
Output:

17
140
94
1818
24
55
17
InordertraversalofKDTreecreatedis:
17
140
24
17
55
94
1818

=======================================================

ConvertaBinaryTreetoThreaded
binarytree
WehavediscussedThreadedBinaryTree.Theideaofthreadedbinarytreesistomakeinordertraversal
fasteranddoitwithoutstackandwithoutrecursion.Inasimplethreadedbinarytree,theNULLrightpointers
areusedtostoreinordersuccessor.WhereeverarightpointerisNULL,itisusedtostoreinorder
successor.
FollowingdiagramshowsanexampleSingleThreadedBinaryTree.Thedottedlinesrepresentthreads.

Followingisstructureofsinglethreadedbinarytree.
struct Node
{
int key;
Node *left, *right;

// Used to indicate whether the right pointer is a normal right


// pointer or a pointer to inorder successor.
bool isThreaded;
};
HowtoconvertaGivenBinaryTreetoThreadedBinaryTree?
WebasicallyneedtosetNULLrightpointerstoinordersuccessor.Wefirstdoaninordertraversalofthe
treeandstoreitinaqueue(wecanuseasimplearrayalso)sothattheinordersuccessorbecomesthenext
node.WeagaindoaninordertraversalandwheneverwefindanodewhoserightisNULL,wetakethefront
itemfromqueuueandmakeittherightofcurrentnode.WealsosetisThreadedtotruetoindicatethatthe
rightpointerisathreadedlink.

FollowingisC++implementationoftheaboveidea.
/* C++ program to convert a Binary Tree to Threaded Tree */
#include <iostream>
#include <queue>
using namespace std;

/* Structure of a node in threaded binary tree */


struct Node
{
int key;
Node *left, *right;

// Used to indicate whether the right pointer is a normal


// right pointer or a pointer to inorder successor.
bool isThreaded;
};

// Helper function to put the Nodes in inorder into queue


void populateQueue(Node *root, std::queue <Node *> *q)
{
if (root == NULL) return;
if (root->left)
populateQueue(root->left, q);
q->push(root);
if (root->right)
populateQueue(root->right, q);
}

// Function to traverse queue, and make tree threaded


void createThreadedUtil(Node *root, std::queue <Node *> *q)
{
if (root == NULL) return;

if (root->left)
createThreadedUtil(root->left, q);
q->pop();

if (root->right)
createThreadedUtil(root->right, q);

// If right pointer is NULL, link it to the


// inorder successor and set 'isThreaded' bit.
else
{
root->right = q->front();
root->isThreaded = true;
}
}

// This function uses populateQueue() and


// createThreadedUtil() to convert a given binary tree
// to threaded tree.
void createThreaded(Node *root)
{
// Create a queue to store inorder traversal
std::queue <Node *> q;

// Store inorder traversal in queue


populateQueue(root, &q);

// Link NULL right pointers to inorder successor


createThreadedUtil(root, &q);
}

// A utility function to find leftmost node in a binary


// tree rooted with 'root'. This function is used in inOrder()
Node *leftMost(Node *root)
{
while (root != NULL && root->left != NULL)
root = root->left;
return root;
}

// Function to do inorder traversal of a threadded binary tree

void inOrder(Node *root)


{
if (root == NULL) return;

// Find the leftmost node in Binary Tree


Node *cur = leftMost(root);

while (cur != NULL)


{
cout << cur->key << " ";

// If this Node is a thread Node, then go to


// inorder successor
if (cur->isThreaded)
cur = cur->right;

else // Else go to the leftmost child in right subtree


cur = leftMost(cur->right);
}
}

// A utility function to create a new node


Node *newNode(int key)
{
Node *temp = new Node;
temp->left = temp->right = NULL;
temp->key = key;
return temp;
}

// Driver program to test above functions


int main()
{
/*

1
/\
2

/\/\

4 56 7

*/

Node *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);

createThreaded(root);

cout << "Inorder traversal of creeated threaded tree is\n";


inOrder(root);
return 0;
}
Output:

Inordertraversalofcreeatedthreadedtreeis
4251637
==================================================================================

SerializeandDeserializeanNary
Tree
GivenanNarytreewhereeverynodehasatmostNchildren.Howtoserializeanddeserialzeit?
Serializationistostoretreeinafilesothatitcanbelaterrestored.Thestructureoftreemustbemaintained.
Deserializationisreadingtreebackfromfile.
Thispostismainlyanextensionofbelowpost.
SerializeandDeserializeaBinaryTree
InanNarytree,therearenodesignatedleftandrightchildren.AnNarytreeisrepresentedbystoringan
arrayorlistofchildpointerswitheverynode.
Theideaistostoreanendofchildrenmarkerwitheverynode.Thefollowingdiagramshowsserialization
where)isusedasendofchildrenmarker.Thediagramistakenfromhere.


FollowingisC++implementationofaboveidea.
// A C++ Program serialize and deserialize an N-ary tree
#include<cstdio>
#define MARKER ')'
#define N 5
using namespace std;

// A node of N-ary tree


struct Node {
char key;
Node *child[N]; // An array of pointers for N children
};

// A utility function to create a new N-ary tree node


Node *newNode(char key)
{
Node *temp = new Node;
temp->key = key;
for (int i = 0; i < N; i++)
temp->child[i] = NULL;
return temp;
}

// This function stores the given N-ary tree in a file pointed by fp


void serialize(Node *root, FILE *fp)

{
// Base case
if (root == NULL) return;

// Else, store current node and recur for its children


fprintf(fp, "%c ", root->key);
for (int i = 0; i < N && root->child[i]; i++)
serialize(root->child[i], fp);

// Store marker at the end of children


fprintf(fp, "%c ", MARKER);
}

// This function constructs N-ary tree from a file pointed by 'fp'.


// This functionr returns 0 to indicate that the next item is a valid
// tree key. Else returns 0
int deSerialize(Node *&root, FILE *fp)
{
// Read next item from file. If theere are no more items or next
// item is marker, then return 1 to indicate same
char val;
if ( !fscanf(fp, "%c ", &val) || val == MARKER )
return 1;

// 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;

// Finally return 0 for successful finish


return 0;
}

// A utility function to create a dummy tree shown in above diagram


Node *createDummyTree()
{

Node *root = newNode('A');


root->child[0] = newNode('B');
root->child[1] = newNode('C');
root->child[2] = newNode('D');
root->child[0]->child[0] = newNode('E');
root->child[0]->child[1] = newNode('F');
root->child[2]->child[0] = newNode('G');
root->child[2]->child[1] = newNode('H');
root->child[2]->child[2] = newNode('I');
root->child[2]->child[3] = newNode('J');
root->child[0]->child[1]->child[0] = newNode('K');
return root;
}

// A utlity function to traverse the constructed N-ary tree


void traverse(Node *root)
{
if (root)
{
printf("%c ", root->key);
for (int i = 0; i < N; i++)
traverse(root->child[i]);
}
}

// Driver program to test above functions


int main()
{
// Let us create an N-ary tree shown in above diagram
Node *root = createDummyTree();

// 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);

printf("Constructed N-Ary Tree from file is \n");


traverse(root1);

return 0;
}
Output:

ConstructedNAryTreefromfileis
ABEFKCDGHIJ
==================================================================================

SerializeandDeserializeaBinary
Tree
Serializationistostoretreeinafilesothatitcanbelaterrestored.Thestructureoftreemustbemaintained.
Deserializationisreadingtreebackfromfile.
Followingaresomesimplerversionsoftheproblem:
IfgivenTreeisBinarySearchTree?
IfthegivenBinaryTreeisBinarySearchTree,wecanstoreitbyeitherstoringpreorderorpostorder
traversal.IncaseofBinarySearchTrees,onlypreorderorpostordertraversalissufficienttostorestructure
information.
IfgivenBinaryTreeisCompleteTree?
ABinaryTreeiscompleteifalllevelsarecompletelyfilledexceptpossiblythelastlevelandallnodesoflast
levelareasleftaspossible(BinaryHeapsarecompleteBinaryTree).ForacompleteBinaryTree,level
ordertraversalissufficienttostorethetree.Weknowthatthefirstnodeisroot,nexttwonodesarenodesof
nextlevel,nextfournodesarenodesof2ndlevelandsoon.
IfgivenBinaryTreeisFullTree?

AfullBinaryisaBinaryTreewhereeverynodehaseither0or2children.Itiseasytoserializesuchtreesas
everyinternalnodehas2children.Wecansimplystorepreordertraversalandstoreabitwitheverynodeto
indicatewhetherthenodeisaninternalnodeoraleafnode.
HowtostoreageneralBinaryTree?
AsimplesolutionistostorebothInorderandPreordertraversals.Thissolutionrequiresrequiresspace
twicethesizeofBinaryTree.
WecansavespacebystoringPreordertraversalandamarkerforNULLpointers.

LetthemarkerforNULLpointersbe'1'
Input:
12
/
13
Output:121311

Input:
20
/\
822
Output:208112211

Input:
20
/
8
/\
412
/\
1014
Output:20841112101114111

Input:
20
/
8
/
10
/

5
Output:20810511111

Input:
20
\
8
\
10
\
5
Output:20181101511

Deserializationcanbedonebysimplyreadingdatafromfileonebyone.
FollowingisC++implementationoftheaboveidea.
// A C++ program to demonstrate serialization and deserialiation of
// Binary Tree
#include <stdio.h>
#define MARKER -1

/* A binary tree Node has key, pointer to left and right children */
struct Node
{
int key;
struct Node* left, *right;
};

/* Helper function that allocates a new Node with the


given key and NULL left and right pointers. */
Node* newNode(int key)
{
Node* temp = new Node;
temp->key = key;
temp->left = temp->right = NULL;
return (temp);
}

// This function stores a tree in a file pointed by fp


void serialize(Node *root, FILE *fp)
{
// If current node is NULL, store marker
if (root == NULL)
{
fprintf(fp, "%d ", MARKER);
return;
}

// Else, store current node and recur for its children


fprintf(fp, "%d ", root->key);
serialize(root->left, fp);
serialize(root->right, fp);
}

// This function constructs a tree from a file pointed by 'fp'


void deSerialize(Node *&root, FILE *fp)
{
// Read next item from file. If theere are no more items or next
// item is marker, then return
int val;
if ( !fscanf(fp, "%d ", &val) || val == MARKER)
return;

// Else create node with this item and recur for children
root = newNode(val);
deSerialize(root->left, fp);
deSerialize(root->right, fp);
}

// A simple inorder traversal used for testing the constructed tree


void inorder(Node *root)
{
if (root)
{
inorder(root->left);

printf("%d ", root->key);


inorder(root->right);
}
}

/* Driver program to test above functions*/


int main()
{
// Let us construct a tree shown in the above figure
struct Node *root

= newNode(20);

root->left

= newNode(8);

root->right

= newNode(22);

root->left->left

= newNode(4);

root->left->right

= newNode(12);

root->left->right->left = newNode(10);
root->left->right->right = newNode(14);

// 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);

printf("Inorder Traversal of the tree constructed from file:\n");


inorder(root1);

return 0;
}

Output:

InorderTraversalofthetreeconstructedfromfile:
481012142022
Howmuchextraspaceisrequiredinabovesolution?
Iftherearenkeys,thentheabovesolutionrequiresn+1markerswhichmaybebetterthansimplesolution
(storingkeystwice)insituationswherekeysarebigorkeyshavebigdataitemsassociatedwiththem.
Canweoptimizeitfurther?
Theabovesolutioncanbeoptimizedinmanyways.Ifwetakeacloserlookataboveserializedtrees,we
canobserverthatallleafnodesrequiretwomarkers.Onesimpleoptimizationistostoreaseparatebitwith
everynodetoindicatethatthenodeisinternalorexternal.Thiswaywedonthavetostoretwomarkerswith
everyleafnodeasleavescanbeidentifiedbyextrabit.Westillneedmarkerforinternalnodeswithone
child.Forexampleinthefollowingdiagramisusedtoindicateaninternalnodesetbit,and/isusedas
NULLmarker.Thediagramistakenfromhere.

PleasenotethattherearealwaysmoreleafnodesthaninternalnodesinaBinaryTree(Numberofleaf
nodesisnumberofinternalnodesplus1,sothisoptimizationmakessense.
Howtoserializenarytree?
Inannarytree,thereisnodesignatedleftorrightchild.Wecanstoreanendofchildrenmarkerwithevery
node.Thefollowingdiagramshowsserializationwhere)isusedasendofchildrenmarker.Wewillsoonbe
coveringimplementationfornarytree.Thediagramistakenfromhere.


==================================================================================

Printnodesbetweentwogivenlevel
numbersofabinarytree
Givenabinarytreeandtwolevelnumberslowandhigh,printnodesfromlevellowtolevelhigh.

Forexampleconsiderthebinarytreegiveninbelowdiagram.

Input:Rootofbelowtree,low=2,high=4

Output:
822
412
1014<>


ASimpleMethodistofirstwritearecursivefunctionthatprintsnodesofagivenlevelnumber.Thencall
recursivefunctioninaloopfromlowtohigh.TimecomplexityofthismethodisO(n2)
WecanprintnodesinO(n)timeusingqueuebasediterativelevelordertraversal.Theideaistodosimple
queuebasedlevelordertraversal.Whiledoinginordertraversal,addamarkernodeattheend.Whenever
weseeamarkernode,weincreaselevelnumber.Iflevelnumberisbetweenlowandhigh,thenprintnodes.
ThefollowingisC++implementationofaboveidea.
// 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;

Node *marker = new Node; // Marker node to indicate end of level

int level = 1;

// Initialize level number

// Enqueue the only first level node and marker node for end of level
Q.push(root);
Q.push(marker);

// Simple level order traversal loop


while (Q.empty() == false)
{
// Remove the front item from queue
Node *n = Q.front();
Q.pop();

// Check if end of level is reached


if (n == marker)
{
// print a new line and increment level number
cout << endl;
level++;

// Check if marker node was last node in queue or


// level number is beyond the given upper limit
if (Q.empty() == true || level > high) break;

// Enqueue the marker for end of next level


Q.push(marker);

// If this is marker, then we don't need print it


// and enqueue its children
continue;
}

// If level is equal to or greater than given lower level,


// print it
if (level >= low)

cout << n->key << " ";

// Enqueue children of non-marker node


if (n->left != NULL) Q.push(n->left);
if (n->right != NULL) Q.push(n->right);
}
}

/* Helper function that allocates a new Node with the


given key and NULL left and right pointers. */
Node* newNode(int key)
{
Node* temp = new Node;
temp->key = key;
temp->left = temp->right = NULL;
return (temp);
}

/* Driver program to test above functions*/


int main()
{
// Let us construct the BST shown in the above figure
struct Node *root

= newNode(20);

root->left

= newNode(8);

root->right

= newNode(22);

root->left->left

= newNode(4);

root->left->right

= newNode(12);

root->left->right->left = newNode(10);
root->left->right->right = newNode(14);

cout << "Level Order traversal between given two levels is";
printLevels(root, 2, 3);

return 0;
}

LevelOrdertraversalbetweengiventwolevelsis
822
412
==================================================================================

FindHeightofBinaryTree
representedbyParentarray

Agivenarrayrepresentsatreeinsuchawaythatthearrayvaluegivestheparentnodeofthatparticular
index.Thevalueoftherootnodeindexwouldalwaysbe1.Findtheheightofthetree.
HeightofaBinaryTreeisnumberofnodesonthepathfromroottothedeepestleafnode,thenumber
includesbothrootandleaf.

Input:parent[]={1552213}
Output:4
ThegivenarrayrepresentsfollowingBinaryTree
5
/\
12
//\
034
/
6

Input:parent[]={1,0,0,1,1,3,5}
Output:5
ThegivenarrayrepresentsfollowingBinaryTree
0
/\
12
/\
34
/
5
/

Source:AmazonInterviewexperience|Set128(ForSDET)
Westronglyrecommendtominimizeyourbrowserandtrythisyourselffirst.
Asimplesolutionistofirstconstructthetreeandthenfindheightoftheconstructedbinarytree.Thetree
canbeconstructedrecursivelybyfirstsearchingthecurrentroot,thenrecurringforthefoundindexesand
makingthemleftandrightsubtreesofroot.ThissolutiontakesO(n2)aswehavetolinearlysearchforevery
node.
AnefficientsolutioncansolvetheaboveprobleminO(n)time.Theideaistofirstcalculatedepthofevery
nodeandstoreinanarraydepth[].Oncewehavedepthsofallnodes,wereturnmaximumofalldepths.
1)Finddepthofallnodesandfillinanauxiliaryarraydepth[].
2)Returnmaximumvalueindepth[].
Followingarestepstofinddepthofanodeatindexi.
1)Ifitisroot,depth[i]is1.
2)Ifdepthofparent[i]isevaluated,depth[i]isdepth[parent[i]]+1.
3)Ifdepthofparent[i]isnotevaluated,recurforparentandassigndepth[i]asdepth[parent[i]]+1(sameas
above).
FollowingisC++implementationofaboveidea.
// C++ program to find height using parent array
#include <iostream>
using namespace std;

// This function fills depth of i'th element in parent[]. The depth is


// filled in depth[i].
void fillDepth(int parent[], int i, int depth[])
{
// If depth[i] is already filled
if (depth[i])
return;

// If node at index i is root


if (parent[i] == -1)
{
depth[i] = 1;
return;
}

// If depth of parent is not evaluated before, then evaluate


// depth of parent first
if (depth[parent[i]] == 0)
fillDepth(parent, parent[i], depth);

// Depth of this node is depth of parent plus 1


depth[i] = depth[parent[i]] + 1;
}

// This function returns height of binary tree represented by


// parent array
int findHeight(int parent[], int n)
{
// Create an array to store depth of all nodes/ and
// initialize depth of every node as 0 (an invalid
// value). Depth of root is 1
int depth[n];
for (int i = 0; i < n; i++)
depth[i] = 0;

// fill depth of all nodes


for (int i = 0; i < n; i++)
fillDepth(parent, i, depth);

// The height of binary tree is maximum of all depths.


// Find the maximum value in depth[] and assign it to ht.
int ht = depth[0];
for (int i=1; i<n; i++)
if (ht < depth[i])
ht = depth[i];
return ht;
}

// Driver program to test above functions


int main()
{
// int parent[] = {1, 5, 5, 2, 2, -1, 3};

int parent[] = {-1, 0, 0, 1, 1, 3, 5};

int n = sizeof(parent)/sizeof(parent[0]);
cout << "Height is " << findHeight(parent, n);
return 0;
}
Output:

Heightis5
==================================================================================

Minimumno.ofiterationstopass
informationtoallnodesinthetree

Givenaverylargenarytree.Wheretherootnodehassomeinformationwhichitwantstopasstoallofits
childrendowntotheleaveswiththeconstraintthatitcanonlypasstheinformationtooneofitschildrenata
time(takeitasoneiteration).
Nowinthenextiterationthechildnodecantransferthatinformationtoonlyoneofitschildrenandatthe
sametimeinstancethechildsparenti.e.rootcanpasstheinfotooneofitsremainingchildren.Continuing
inthiswaywehavetofindtheminimumnoofiterationsrequiredtopasstheinformationtoallnodesinthe
tree.
Minimumnoofiterationsfortreebelowis6.TherootAfirstpassesinformationtoB.Innextiteration,A
passesinformationtoEandBpassesinformationtoHandsoon.


Westronglyrecommendtominimizethebrowserandtrythisyourselffirst.
ThiscanbedoneusingPostOrderTraversal.Theideaistoconsiderheightandchildrencountoneachand
everynode.
Ifachildnodeitakesciiterationstopassinfobelowitssubtree,thenitsparentwilltake(ci+1)iterationsto
passinfotosubtreerootedatthatchildi.
Ifparenthasmorechildren,itwillpassinfototheminsubsequentiterations.Letssaychildrenofaparent
takesc1,c2,c3,c4,,cniterationstopassinfointheirownsubtree,Nowparenthastopassinfotothese
nchildrenonebyoneinniterations.Ifparentpickschildiinithiteration,thenparentwilltake(i+ci)
iterationstopassinfotochildiandallitssubtree.
Inanyiteration,whenparentpassesinfoachildi+1,children(1toi)whichgotinfofromparentalreadyin
previousiterations,willpassinfotofurtherdowninsubsequentiterations,ifanychild(1toi)hasitsown
childfurtherdown.
Topassinfotowholetreeinminimumiterations,itneedstobemadesurethatbandwidthisutilizedas
efficientlyaspossible(i.e.maximumpassablenoofnodesshouldpassinfofurtherdowninanyiteration)
Thebestpossiblescenariowouldbethatinnthiteration,ndifferentnodespassinfototheirchild.
Nodeswithheight=0:(Trivialcase)Leafnodehasnochildren(noinformationpassingneeded),sonoof
iterationswouldbeZERO.
Nodeswithheight=1:Herenodehastopassinfotoallthechildrenonebyone(allchildrenareleafnode,
sonomoreinformationpassingfurtherdown).Sinceallchildrenareleaf,nodecanpassinfotoanychildin
anyorder(pickanychildwhodidntreceivetheinfoyet).Oneiterationneededforeachchildandsonoof
iterationswouldbenoofchildren.Sonodewithheight1withnchildrenwilltakeniterations.
TakeacounterinitializedwithZERO,loopthroughallchildrenandkeepincrementingcounter.

Nodeswithheight>1:Letsassumethattherearenchildren(1ton)ofanodeandminimumnoiterations
forallnchildrenarec1,c2,.,cn.
Tomakesuremaximumnoofnodesparticipateininfopassinginanyiteration,parentshould1stpassinfo
tothatchildwhowilltakemaximumiterationtopassinfofurtherdowninsubsequentiterations.i.e.inany
iteration,parentshouldchoosethechildwhotakesmaximumiterationlateron.Itcanbethoughtofasa
greedyapproachwhereparentchoosethatchild1st,whoneedsmaximumnoofiterationssothatall
subsequentiterationscanbeutilizedefficiently.
Ifparentgoesinanyotherfashion,thenintheend,therecouldbesomenodeswhicharedonequiteearly,
sittingidleandsobandwidthisnotutilizedefficientlyinfurtheriterations.
Iftherearetwochildreniandjwithminimumiterationsciandcjwhereci>cj,thenIfparentpickschildj1st
thennoofiterationsneededbyparenttopassinfotobothchildrenandtheirsubtreewouldbe:max(1+cj,2
+ci)=2+ci
Ifparentpickschildi1stthennoofiterationsneededbyparenttopassinfotobothchildrenandtheir
subtreewouldbe:max(1+ci,2+cj)=1+ci(Sopickingcigivesbetterresultthanpickingcj)
Thistellsthatparentshouldalwayschoosechildiwithmaxcivalueinanyiteration.
SOheregreedyapproachis:
sortallcivaluesdecreasingorder,
letssayaftersorting,valuesarec1>c2>c3>.>cn
takeacounterc,setc=1+c1(forchildwithmaximumnoofiterations)
forallchildrenifrom2ton,c=c+1+ci
thentotalnoofiterationsneededbyparentismax(n,c)
LetminItr(A)betheminimumiterationneededtopassinfofromnodeAtoitsallthesubtree.Letchild(A)
bethecountofallchildrenfornodeA.Sorecursiverelationwouldbe:

1.GetminItr(B)ofallchildren(B)ofanode(A)
2.SortallminItr(B)indescendingorder
3.GetminItrofAbasedonallminItr(B)
minItr(A)=child(A)
ForchildrenBfromi=0tochild(A)
minItr(A)=max(minItr(A),minItr(B)+i+1)

Basecaseswouldbe:
Ifnodeisleaf,minItr=0
Ifnode'sheightis1,minItr=childrencount
FollowingisC++implementationofaboveidea.
// C++ program to find minimum number of iterations to pass
// information from root to all nodes in an n-ary tree
#include<iostream>

#include<list>
#include<cmath>
#include <stdlib.h>
using namespace std;

// A class to represent n-ary tree (Note that the implementation


// is similar to graph for simplicity of implementation
class NAryTree
{
int N;

// No. of nodes in Tree

// Pointer to an array containing list of children


list<int> *adj;

// A function used by getMinIter(), it basically does postorder


void getMinIterUtil(int v, int minItr[]);
public:
NAryTree(int N);

// Constructor

// function to add a child w to v


void addChild(int v, int w);

// The main function to find minimum iterations


int getMinIter();

static int compare(const void * a, const void * b);


};

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.


}

/* A recursive function to used by getMinIter(). This function


// mainly does postorder traversal and get minimum iteration of all children
// of node u, sort them in decreasing order and then get minimum iteration
// of node u

1. Get minItr(B) of all children (B) of a node (A)


2. Sort all minItr(B) in descending order
3. Get minItr of A based on all minItr(B)
minItr(A) = child(A) -->> child(A) is children count of node A
For children B from i = 0 to child(A)
minItr(A) = max ( minItr(A), minItr(B) + i + 1)

Base cases would be:


If node is leaf, minItr = 0
If node's height is 1, minItr = children count
*/

void NAryTree::getMinIterUtil(int u, int minItr[])


{
minItr[u] = adj[u].size();
int *minItrTemp = new int[minItr[u]];
int k = 0, tmp = 0;
// Recur for all the vertices adjacent to this vertex
list<int>::iterator i;
for (i = adj[u].begin(); i!= adj[u].end(); ++i)
{
getMinIterUtil(*i, minItr);
minItrTemp[k++] = minItr[*i];
}
qsort(minItrTemp, minItr[u], sizeof (int), compare);
for (k = 0; k < adj[u].size(); k++)
{
tmp = minItrTemp[k] + k + 1;
minItr[u] = max(minItr[u], tmp);

}
delete[] minItrTemp;
}

// The function to do PostOrder traversal. It uses


// recursive getMinIterUtil()
int NAryTree::getMinIter()
{
// Set minimum iteration all the vertices as zero
int *minItr = new int[N];
int res = -1;
for (int i = 0; i < N; i++)
minItr[i] = 0;

// Start Post Order Traversal from Root


getMinIterUtil(0, minItr);
res = minItr[0];
delete[] minItr;
return res;
}

int NAryTree::compare(const void * a, const void * b)


{
return ( *(int*)b - *(int*)a );
}

// Driver function to test above functions


int main()
{
// TestCase 1
NAryTree tree1(17);
tree1.addChild(0, 1);
tree1.addChild(0, 2);
tree1.addChild(0, 3);
tree1.addChild(0, 4);
tree1.addChild(0, 5);
tree1.addChild(0, 6);

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);

cout << "TestCase 1 - Minimum Iteration: "


<< tree1.getMinIter() << endl;

// 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);

cout << "TestCase 9 - Minimum Iteration: "


<< tree9.getMinIter() << endl;

return 0;
}
Output:

TestCase1MinimumIteration:6
TestCase2MinimumIteration:2
TestCase3MinimumIteration:0
TestCase4MinimumIteration:5
TestCase5MinimumIteration:4
TestCase6MinimumIteration:3
TestCase7MinimumIteration:6
TestCase8MinimumIteration:6
TestCase9MinimumIteration:8
==================================================================================

CloneaBinaryTreewithRandom
Pointers

GivenaBinaryTreewhereeverynodehasfollowingstructure.

structnode{
intkey
structnode*left,*right,*random
}
TherandompointerpointstoanyrandomnodeofthebinarytreeandcanevenpointtoNULL,clonethe
givenbinarytree.
Method1(UseHashing)
Theideaistostoremappingfromgiventreenodestoclonetrenodeinhashtable.Followingaredetailed
steps.
1)RecursivelytraversethegivenBinaryandcopykeyvalue,leftpointerandrightpointertoclonetree.
Whilecopying,storethemappingfromgiventreenodetoclonetreenodeinahashtable.Inthefollowing
pseudocode,cloneNodeiscurrentlyvisitednodeofclonetreeandtreeNodeiscurrentlyvisitednodeof
giventree.

cloneNode>key=treeNode>key
cloneNode>left=treeNode>left
cloneNode>right=treeNode>right
map[treeNode]=cloneNode
2)Recursivelytraversebothtreesandsetrandompointersusingentriesfromhashtable.

cloneNode>random=map[treeNode>random]
FollowingisC++implementationofaboveidea.ThefollowingimplementationusesmapfromC++STL.
Notethatmapdoesntimplementhashtable,itactuallyisbasedonselfbalancingbinarysearchtree.
// 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);
}

/* Given a binary tree, print its Nodes in inorder*/


void printInorder(Node* node)
{
if (node == NULL)
return;

/* First recur on left sutree */


printInorder(node->left);

/* then print data of Node and its random */


cout << "[" << node->key << " ";
if (node->random == NULL)
cout << "NULL], ";
else
cout << node->random->key << "], ";

/* now recur on right subtree */


printInorder(node->right);
}

// 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;
}

// This function copies random node by using the hashmap built by


// copyLeftRightNode()
void copyRandom(Node* treeNode, Node* cloneNode, map<Node *, Node *> *mymap)
{
if (cloneNode == NULL)
return;
cloneNode->random = (*mymap)[treeNode->random];
copyRandom(treeNode->left, cloneNode->left, mymap);
copyRandom(treeNode->right, cloneNode->right, mymap);
}

// This function makes the clone of given tree. It mainly uses


// copyLeftRightNode() and copyRandom()
Node* cloneTree(Node* tree)
{
if (tree == NULL)
return NULL;
map<Node *, Node *> *mymap = new map<Node *, Node *>;
Node* newTree = copyLeftRightNode(tree, mymap);
copyRandom(tree, newTree, mymap);
return newTree;
}

/* Driver program to test above functions*/


int main()
{
//Test No 1

Node *tree = newNode(1);


tree->left = newNode(2);
tree->right = newNode(3);
tree->left->left = newNode(4);
tree->left->right = newNode(5);
tree->random = tree->left->right;
tree->left->left->random = tree;
tree->left->right->random = tree->right;

// 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;
*/

cout << "Inorder traversal of original binary tree is: \n";


printInorder(tree);

Node *clone = cloneTree(tree);

cout << "\n\nInorder traversal of cloned binary tree is: \n";


printInorder(clone);

return 0;
}
Output:

Inordertraversaloforiginalbinarytreeis:
[41],[2NULL],[53],[15],[3NULL],

Inordertraversalofclonedbinarytreeis:
[41],[2NULL],[53],[15],[3NULL],

Method2(TemporarilyModifytheGivenBinaryTree)
1.Createnewnodesinclonedtreeandinserteachnewnodeinoriginaltreebetweentheleftpointeredge
ofcorrespondingnodeintheoriginaltree(Seethebelowimage).
i.e.ifcurrentnodeisAanditsleftchildisB(A>>B),thennewclonednodewithkeyAwilbecreated
(saycA)anditwillbeputasA>>cA>>B(BcanbeaNULLoranonNULLleftchild).Rightchild
pointerwillbesetcorrectlyi.e.ifforcurrentnodeA,rightchildisCinoriginaltree(A>>C)then
correspondingclonednodescAandcCwilllikecA>>cC

2.Setrandompointerinclonedtreeasperoriginaltree
i.e.ifnodeAsrandompointerpointstonodeB,theninclonedtree,cAwillpointtocB(cAandcBarenew
nodeinclonedtreecorrespondingtonodeAandBinoriginaltree)
3.Restoreleftpointerscorrectlyinbothoriginalandclonedtree
FollowingisC++implementationofabovealgorithm.
#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;
};

/* 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);
}

/* Given a binary tree, print its Nodes in inorder*/


void printInorder(Node* node)
{
if (node == NULL)
return;

/* First recur on left sutree */


printInorder(node->left);

/* then print data of Node and its random */


cout << "[" << node->key << " ";
if (node->random == NULL)
cout << "NULL], ";
else
cout << node->random->key << "], ";

/* now recur on right subtree */


printInorder(node->right);
}

// This function creates new nodes cloned tree and puts new cloned node
// in between current node and it's left child
// i.e. if current node is A and it's left child is B ( A --- >> B ),
//

then new cloned node with key A wil be created (say cA) and

//

it will be put as

//

A --- >> cA --- >> B

// Here B can be a NULL or a non-NULL left child


// Right child pointer will be set correctly
// i.e. if for current node A, right child is C in original tree
// (A --- >> C) then corresponding cloned nodes cA and cC will like
// cA ---- >> cC
Node* copyLeftRightNode(Node* treeNode)
{
if (treeNode == NULL)
return NULL;

Node* left = treeNode->left;


treeNode->left = newNode(treeNode->key);
treeNode->left->left = left;
if(left != NULL)
left->left = copyLeftRightNode(left);

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;

if(treeNode->left != NULL && cloneNode->left != NULL)


copyRandomNode(treeNode->left->left, cloneNode->left->left);
copyRandomNode(treeNode->right, cloneNode->right);
}

// This function will restore left pointers correctly in


// both original and cloned tree
void restoreTreeLeftNode(Node* treeNode, Node* cloneNode)
{
if (treeNode == NULL)
return;
if (cloneNode->left != NULL)
{
Node* cloneLeft = cloneNode->left->left;
treeNode->left = treeNode->left->left;
cloneNode->left = cloneLeft;
}
else
treeNode->left = NULL;

restoreTreeLeftNode(treeNode->left, cloneNode->left);
restoreTreeLeftNode(treeNode->right, cloneNode->right);
}

//This function makes the clone of given tree


Node* cloneTree(Node* treeNode)
{
if (treeNode == NULL)
return NULL;
Node* cloneNode = copyLeftRightNode(treeNode);
copyRandomNode(treeNode, cloneNode);
restoreTreeLeftNode(treeNode, cloneNode);
return cloneNode;
}

/* Driver program to test above functions*/


int main()
{
/* //Test No 1
Node *tree = newNode(1);

tree->left = newNode(2);
tree->right = newNode(3);
tree->left->left = newNode(4);
tree->left->right = newNode(5);
tree->random = tree->left->right;
tree->left->left->random = tree;
tree->left->right->random = tree->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);

Node *clone = cloneTree(tree);

cout << "\n\nInorder traversal of cloned binary tree is: \n";


printInorder(clone);

return 0;
}

Output:

Inordertraversaloforiginalbinarytreeis:
[59],[67],[7NULL],[810],[97],[106],[119],[128],[13NULL],

Inordertraversalofclonedbinarytreeis:
[59],[67],[7NULL],[810],[97],[106],[119],[128],[13NULL],

==================================================================================

Checkiftwonodesarecousinsina
BinaryTree

GiventhebinaryTreeandthetwonodessayaandb,determinewhetherthetwonodesarecousinsof
eachotherornot.
Twonodesarecousinsofeachotheriftheyareatsamelevelandhavedifferentparents.
Example

6
/\
35
/\/\
7813
Saytwonodebe7and1,resultisTRUE.
Saytwonodesare3and5,resultisFALSE.
Saytwonodesare7and5,resultisFALSE.
Westronglyrecommendtominimizethebrowserandtrythisyourselffirst.
Theideaistofindlevelofoneofthenodes.Usingthefoundlevel,checkifaandbareatthislevel.Ifa
andbareatgivenlevel,thenfinallycheckiftheyarenotchildrenofsameparent.
FollowingisCimplementationoftheaboveapproach.
// C program to check if two Nodes in a binary tree are cousins
#include <stdio.h>
#include <stdlib.h>

// A Binary Tree Node


struct Node

{
int data;
struct Node *left, *right;
};

// A utility function to create a new Binary Tree Node


struct Node *newNode(int item)
{
struct Node *temp = (struct Node *)malloc(sizeof(struct Node));
temp->data = item;
temp->left = temp->right = NULL;
return temp;
}

// Recursive function to check if two Nodes are siblings


int isSibling(struct Node *root, struct Node *a, struct Node *b)
{
// Base case
if (root==NULL) return 0;

return ((root->left==a && root->right==b)||


(root->left==b && root->right==a)||
isSibling(root->left, a, b)||
isSibling(root->right, a, b));
}

// Recursive function to find level of Node 'ptr' in a binary tree


int level(struct Node *root, struct Node *ptr, int lev)
{
// base cases
if (root == NULL) return 0;
if (root == ptr) return lev;

// Return level if Node is present in left subtree


int l = level(root->left, ptr, lev+1);
if (l != 0) return l;

// Else search in right subtree


return level(root->right, ptr, lev+1);
}

// Returns 1 if a and b are cousins, otherwise 0


int isCousin(struct Node *root, struct Node *a, struct Node *b)
{
//1. The two Nodes should be on the same level in the binary tree.
//2. The two Nodes should not be siblings (means that they should
// not have the same parent Node).
if ((level(root,a,1) == level(root,b,1)) && !(isSibling(root,a,b)))
return 1;
else return 0;
}

// Driver Program to test above functions


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->right->right = newNode(15);
root->right->left = newNode(6);
root->right->right = newNode(7);
root->right->left->right = newNode(8);

struct Node *Node1,*Node2;


Node1 = root->left->left;
Node2 = root->right->right;

isCousin(root,Node1,Node2)? puts("Yes"): puts("No");

return 0;
}

Ouput:

Yes
==================================================================================

Checkifabinarytreeissubtreeof
anotherbinarytree|Set2

Giventwobinarytrees,checkifthefirsttreeissubtreeofthesecondone.AsubtreeofatreeTisatreeS
consistingofanodeinTandallofitsdescendantsinT.
Thesubtreecorrespondingtotherootnodeistheentiretreethesubtreecorrespondingtoanyothernodeis
calledapropersubtree.
Forexample,inthefollowingcase,Tree1isasubtreeofTree2.

Tree1
x
/\
ab
\
c

Tree2
z
/\
xe
/\\
abk
\
c
WehavediscussedaO(n2)solutionforthisproblem.InthispostaO(n)solutionisdiscussed.Theideais
basedonthefactthatinorderandpreorder/postorderuniquelyidentifyabinarytree.TreeSisasubtreeofT
ifbothinorderandpreordertraversalsofSarewsubstringsofinorderandpreordertraversalsofT
respectively.
Followingaredetailedsteps.
1)FindinorderandpreordertraversalsofT,storethemintwoauxiliaryarraysinT[]andpreT[].

2)FindinorderandpreordertraversalsofS,storethemintwoauxiliaryarraysinS[]andpreS[].
3)IfinS[]isasubarrayofinT[]andpreS[]isasubarraypreT[],thenSisasubtreeofT.Elsenot.
Wecanalsousepostordertraversalinplaceofpreorderintheabovealgorithm.
Letusconsidertheaboveexample

InorderandPreordertraversalsofthebigtreeare.
inT[]={a,c,x,b,z,e,k}
preT[]={z,x,a,c,b,e,k}

InorderandPreordertraversalsofsmalltreeare
inS[]={a,c,x,b}
preS[]={x,a,c,b}

WecaneasilyfigureoutthatinS[]isasubarrayof
inT[]andpreS[]isasubarrayofpreT[].
EDIT

Theabovealgorithmdoesn'tworkforcaseswhereatreeispresent
inanothertree,butnotasasubtree.Considerthefollowingexample.

Tree1
x
/\
ab
/

Tree2
x
/\
ab
/\
cd

InorderandPreordertraversalsofthebigtreeorTree2are.

InorderandPreordertraversalsofsmalltreeorTree1are

TheTree2isnotasubtreeofTree1,butinS[]andpreS[]are
subarraysofinT[]andpreT[]respectively.

Theabovealgorithmcanbeextendedtohandlesuchcasesbyaddingaspecialcharacterwheneverwe
encounterNULLininorderandpreordertraversals.ThankstoShivamGoelforsuggestingthisextension.
FollowingisC++implementationofabovealgorithm.
#include <iostream>
#include <cstring>
using namespace std;
#define MAX 100

// Structure of a tree node


struct Node
{
char key;
struct Node *left, *right;
};

// A utility function to create a new BST node


Node *newNode(char item)
{
Node *temp = new Node;
temp->key = item;
temp->left = temp->right = NULL;
return temp;
}

// A utility function to store inorder traversal of tree rooted


// with root in an array arr[]. Note that i is passed as reference
void storeInorder(Node *root, char arr[], int &i)
{
if (root == NULL)
{
arr[i++] = '$';
return;
}
storeInorder(root->left, arr, i);

arr[i++] = root->key;
storeInorder(root->right, arr, i);
}

// A utility function to store preorder traversal of tree rooted


// with root in an array arr[]. Note that i is passed as reference
void storePreOrder(Node *root, char arr[], int &i)
{
if (root == NULL)
{
arr[i++] = '$';
return;
}
arr[i++] = root->key;
storePreOrder(root->left, arr, i);
storePreOrder(root->right, arr, i);
}

/* This function returns true if S is a subtree of T, otherwise false */


bool isSubtree(Node *T, Node *S)
{
/* base cases */
if (S == NULL) return true;
if (T == NULL) return false;

// Store Inorder traversals of T and S in inT[0..m-1]


// and inS[0..n-1] respectively
int m = 0, n = 0;
char inT[MAX], inS[MAX];
storeInorder(T, inT, m);
storeInorder(S, inS, n);
inT[m] = '\0', inS[n] = '\0';

// If inS[] is not a substring of preS[], return false


if (strstr(inT, inS) == NULL)
return false;

// Store Preorder traversals of T and S in inT[0..m-1]


// and inS[0..n-1] respectively
m = 0, n = 0;
char preT[MAX], preS[MAX];
storePreOrder(T, preT, m);
storePreOrder(S, preS, n);
preT[m] = '\0', preS[n] = '\0';

// If inS[] is not a substring of preS[], return false


// Else return true
return (strstr(preT, preS) != NULL);
}

// Driver program to test above function


int main()
{
Node *T = newNode('a');
T->left = newNode('b');
T->right = newNode('d');
T->left->left = newNode('c');
T->right->right = newNode('e');

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:SisNOTasubtreeofT
==================================================================================

Inorderpredecessorandsuccessor
foragivenkeyinBST

Irecentlyencounteredwithaquestioninaninterviewatecommercecompany.Theintervieweraskedthe
followingquestion:
ThereisBSTgivenwithrootnodewithkeypartasintegeronly.Thestructureofeachnodeisasfollows:
struct Node
{
int key;
struct Node *left, *right ;
};
Youneedtofindtheinordersuccessorandpredecessorofagivenkey.Incasethegivenkeyisnotfoundin
BST,thenreturnthetwovalueswithinwhichthiskeywilllie.
Followingisthealgorithmtoreachthedesiredresult.Itsarecursivemethod:

Input:rootnode,key
output:predecessornode,successornode

1.IfrootisNULL
thenreturn
2.ifkeyisfoundthen
a.Ifitsleftsubtreeisnotnull
Thenpredecessorwillbetherightmost
childofleftsubtreeorleftchilditself.
b.Ifitsrightsubtreeisnotnull
Thesuccessorwillbetheleftmostchild
ofrightsubtreeorrightchilditself.
return
3.Ifkeyissmallerthenrootnode
setthesuccessorasroot
searchrecursivelyintoleftsubtree
else
setthepredecessorasroot
searchrecursivelyintorightsubtree

FollowingisC++implementationoftheabovealgorithm:
// C++ program to find predecessor and successor in a BST
#include <iostream>
using namespace std;

// BST Node
struct Node
{
int key;
struct Node *left, *right;
};

// This function finds predecessor and successor of key in BST.


// It sets pre and suc as predecessor and successor respectively
void findPreSuc(Node* root, Node*& pre, Node*& suc, int key)
{
// Base case
if (root == NULL) return ;

// If key is present at root


if (root->key == key)
{
// the maximum value in left subtree is predecessor
if (root->left != NULL)
{
Node* tmp = root->left;
while (tmp->right)
tmp = tmp->right;
pre = tmp ;
}

// the minimum value in right subtree is successor


if (root->right != NULL)
{
Node* tmp = root->right ;
while (tmp->left)
tmp = tmp->left ;

suc = tmp ;
}
return ;
}

// If key is smaller than root's key, go to left subtree


if (root->key > key)
{
suc = root ;
findPreSuc(root->left, pre, suc, key) ;
}
else // go to right subtree
{
pre = root ;
findPreSuc(root->right, pre, suc, key) ;
}
}

// A utility function to create a new BST node


Node *newNode(int item)
{
Node *temp = new Node;
temp->key = item;
temp->left = temp->right = NULL;
return temp;
}

/* A utility function to insert a new node with given key in BST */


Node* insert(Node* node, int key)
{
if (node == NULL) return newNode(key);
if (key < node->key)
node->left = insert(node->left, key);
else
node->right = insert(node->right, key);
return node;
}

// Driver program to test above function


int main()
{
int key = 65;

//Key to be searched in BST

/* Let us create following BST


50
/\
30

70

/ \/ \
20

40 60

80 */

Node *root = NULL;


root = insert(root, 50);
insert(root, 30);
insert(root, 20);
insert(root, 40);
insert(root, 70);
insert(root, 60);
insert(root, 80);

Node* pre = NULL, *suc = NULL;

findPreSuc(root, pre, suc, key);


if (pre != NULL)
cout << "Predecessor is " << pre->key << endl;
else
cout << "No Predecessor";

if (suc != NULL)
cout << "Successor is " << suc->key;
else
cout << "No Successor";
return 0;
}
Output:

Predecessoris60
Successoris70
==================================================================================

Findthemaximumpathsum
betweentwoleavesofabinarytree

Givenabinarytreeinwhicheachnodeelementcontainsanumber.Findthemaximumpossiblesumfrom
oneleafnodetoanother.
Themaximumsumpathmayormaynotgothroughroot.Forexample,inthefollowingbinarytree,the
maximumsumis27(3+6+9+01+10).ExpectedtimecomplexityisO(n).

AsimplesolutionistotraversethetreeanddofollowingforeverytraversednodeX.
1)FindmaximumsumfromleaftorootinleftsubtreeofX(wecanusethispostforthisandnextsteps)
2)FindmaximumsumfromleaftorootinrightsubtreeofX.
3)AddtheabovetwocalculatedvaluesandX>dataandcomparethesumwiththemaximumvalue
obtainedsofarandupdatethemaximumvalue.
4)Returnthemaximumvalue.
ThetimecomplexityofabovesolutionisO(n2)
Wecanfindthemaximumsumusingsingletraversalofbinarytree.Theideaistomaintaintwovalues
inrecursivecalls
1)Maximumroottoleafpathsumforthesubtreerootedundercurrentnode.

2)Themaximumpathsumbetweenleaves(desiredoutput).
ForeveryvisitednodeX,wefindthemaximumroottoleafsuminleftandrightsubtreesofX.Weaddthe
twovalueswithX>data,andcomparethesumwithmaximumpathsumfoundsofar.
FollowingisC++implementationoftheaboveO(n)solution.
// C++ program to find maximum path sum between two leaves of
// a binary tree
#include <iostream>
using namespace std;

// A binary tree node


struct Node
{
int data;
struct Node* left, *right;
};

// Utility function to allocate memory for a new node


struct Node* newNode(int data)
{
struct Node* node = new(struct Node);
node->data = data;
node->left = node->right = NULL;
return (node);
}

// Utility function to find maximum of two integers


int max(int a, int b)
{

return (a >= b)? a: b; }

// 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 case
if (root==NULL) return 0;

// Find maximum sum in left and right subtree. Also find


// maximum root to leaf sums in left and right subtrees
// and store them in lLPSum and rLPSum
int lLPSum = maxPathSumUtil(root->left, res);
int rLPSum = maxPathSumUtil(root->right, res);

// Find the maximum path sum passing through root


int curr_sum = max((lLPSum+rLPSum+root->data), max(lLPSum, rLPSum));

// Update res (or result) if needed


if (res < curr_sum)
res = curr_sum;

// Return the maximum root to leaf path sum


return max(lLPSum, rLPSum)+root->data;
}

// The main function which returns sum of the maximum


// sum path between two leaves. This function mainly uses
// maxPathSumUtil()
int maxPathSum(struct Node *root)
{
int res = 0;
maxPathSumUtil(root, res);
return res;
}

// driver program to test above function


int main()
{
struct Node *root = newNode(-15);
root->left = newNode(5);
root->right = newNode(6);
root->left->left = newNode(-8);
root->left->right = newNode(1);
root->left->left->left = newNode(2);

root->left->left->right = newNode(6);
root->right->left = newNode(3);
root->right->right = newNode(9);
root->right->right->right= newNode(0);
root->right->right->right->left= newNode(4);
root->right->right->right->right= newNode(-1);
root->right->right->right->right->left= newNode(10);
cout << "Max pathSum of the given binary tree is " << maxPathSum(root);
return 0;
}
Output:

MaxpathSumofthegivenbinarytreeis27.
==================================================================================

Reversealternatelevelsofaperfect
binarytree

GivenaPerfectBinaryTree,reversethealternatelevelnodesofthebinarytree.

Giventree:
a
/\
bc
/\/\
defg
/\/\/\/\
hijklmno

Modifiedtree:

a
/\
cb
/\/\
defg

/\/\/\/\
onmlkjih
Westronglyrecommendtominimizethebrowserandtrythisyourselffirst.
Asimplesolutionistodofollowingsteps.
1)Accessnodeslevelbylevel.
2)Ifcurrentlevelisodd,thenstorenodesofthislevelinanarray.
3)Reversethearrayandstoreelementsbackintree.
Atrickysolutionistodotwoinordertraversals.Followingarestepstobefollowed.
1)Traversethegiventreeininorderfashionandstorealloddlevelnodesinanauxiliaryarray.Forthe
aboveexamplegiventree,contentsofarraybecome{h,i,b,j,k,l,m,c,n,o}
2)Reversethearray.Thearraynowbecomes{o,n,c,m,l,k,j,b,i,h}
3)Traversethetreeagaininorderfashion.Whiletraversingthetree,onebyonetakeelementsfromarray
andstoreelementsfromarraytoeveryoddleveltraversednode.
Fortheaboveexample,wetraversehfirstinabovearrayandreplacehwitho.Thenwetraverseiand
replaceitwithn.
FollowingisC++implementationoftheabovealgorithm.
// C++ program to reverse alternate levels of a binary tree
#include<iostream>
#define MAX 100
using namespace std;

// A Binary Tree node


struct Node
{
char data;
struct Node *left, *right;
};

// A utility function to create a new Binary Tree Node


struct Node *newNode(char item)
{
struct Node *temp = new Node;
temp->data = item;
temp->left = temp->right = NULL;
return temp;
}

// Function to store nodes of alternate levels in an array


void storeAlternate(Node *root, char arr[], int *index, int l)
{
// Base case
if (root == NULL) return;

// Store elements of left subtree


storeAlternate(root->left, arr, index, l+1);

// Store this node only if this is a odd level node


if (l%2 != 0)
{
arr[*index] = root->data;
(*index)++;
}

// Store elements of right subtree


storeAlternate(root->right, arr, index, l+1);
}

// Function to modify Binary Tree (All odd level nodes are


// updated by taking elements from array in inorder fashion)
void modifyTree(Node *root, char arr[], int *index, int l)
{
// Base case
if (root == NULL) return;

// Update nodes in left subtree


modifyTree(root->left, arr, index, l+1);

// Update this node only if this is an odd level node


if (l%2 != 0)
{
root->data = arr[*index];
(*index)++;
}

// Update nodes in right subtree


modifyTree(root->right, arr, index, l+1);
}

// A utility function to reverse an array from index


// 0 to n-1
void reverse(char arr[], int n)
{
int l = 0, r = n-1;
while (l < r)
{
int temp = arr[l];
arr[l] = arr[r];
arr[r] = temp;
l++; r--;
}
}

// The main function to reverse alternate nodes of a binary tree


void reverseAlternate(struct Node *root)
{
// Create an auxiliary array to store nodes of alternate levels
char *arr = new char[MAX];
int index = 0;

// First store nodes of alternate levels


storeAlternate(root, arr, &index, 0);

// Reverse the array


reverse(arr, index);

// Update tree by taking elements from array


index = 0;
modifyTree(root, arr, &index, 0);
}

// A utility function to print indorder traversal of a

// binary tree
void printInorder(struct Node *root)
{
if (root == NULL) return;
printInorder(root->left);
cout << root->data << " ";
printInorder(root->right);
}

// Driver Program to test above functions


int main()
{
struct Node *root = newNode('a');
root->left = newNode('b');
root->right = newNode('c');
root->left->left = newNode('d');
root->left->right = newNode('e');
root->right->left = newNode('f');
root->right->right = newNode('g');
root->left->left->left = newNode('h');
root->left->left->right = newNode('i');
root->left->right->left = newNode('j');
root->left->right->right = newNode('k');
root->right->left->left = newNode('l');
root->right->left->right = newNode('m');
root->right->right->left = newNode('n');
root->right->right->right = newNode('o');

cout << "Inorder Traversal of given tree\n";


printInorder(root);

reverseAlternate(root);

cout << "\n\nInorder Traversal of modified tree\n";


printInorder(root);

return 0;

}
Output:

InorderTraversalofgiventree
hdibjekalfmcngo

InorderTraversalofmodifiedtree
odncmelakfjbigh

TimecomplexityoftheabovesolutionisO(n)asitdoestwoinordertraversalsofbinarytree.
==================================================================================

TransformaBSTtogreatersumtree

GivenaBST,transformitintogreatersumtreewhereeachnodecontainssumofallnodesgreaterthanthat
node.

Westronglyrecommendtominimizethegbrowserandtrythisyourselffirst.
Method1(Naive):
ThismethoddoesntrequirethetreetobeaBST.Followingaresteps.
1.Traversenodebynode(Inorder,preorder,etc.)
2.Foreachnodefindallthenodesgreaterthanthatofthecurrentnode,sumthevalues.Storeallthese
sums.
3.ReplaceeachnodevaluewiththeircorrespondingsumbytraversinginthesameorderasinStep1.
ThistakesO(n^2)TimeComplexity.
Method2(Usingonlyonetraversal)
ByleveragingthefactthatthetreeisaBST,wecanfindanO(n)solution.TheideaistotraverseBSTin
reverseinorder.ReverseinordertraversalofaBSTgivesuskeysindecreasingorder.Beforevisitinga

node,wevisitallgreaternodesofthatnode.Whiletraversingwekeeptrackofsumofkeyswhichisthesum
ofallthekeysgreaterthanthekeyofcurrentnode.
// C++ program to transform a BST to sum tree
#include<iostream>
using namespace std;

// A BST node
struct Node
{
int data;
struct Node *left, *right;
};

// A utility function to create a new Binary Tree Node


struct Node *newNode(int item)
{
struct Node *temp = new Node;
temp->data = item;
temp->left = temp->right = NULL;
return temp;
}

// Recursive function to transform a BST to sum tree.


// This function traverses the tree in reverse inorder so
// that we have visited all greater key nodes of the currently
// visited node
void transformTreeUtil(struct Node *root, int *sum)
{
// Base case
if (root == NULL) return;

// Recur for right subtree


transformTreeUtil(root->right, sum);

// Update sum
*sum = *sum + root->data;

// Store old sum in current node


root->data = *sum - root->data;

// Recur for left subtree


transformTreeUtil(root->left, sum);
}

// A wrapper over transformTreeUtil()


void transformTree(struct Node *root)
{
int sum = 0; // Initialize sum
transformTreeUtil(root, &sum);
}

// A utility function to print indorder traversal of a


// binary tree
void printInorder(struct Node *root)
{
if (root == NULL) return;

printInorder(root->left);
cout << root->data << " ";
printInorder(root->right);
}

// Driver Program to test above functions


int main()
{
struct Node *root = newNode(11);
root->left = newNode(2);
root->right = newNode(29);
root->left->left = newNode(1);
root->left->right = newNode(7);
root->right->left = newNode(15);
root->right->right = newNode(40);
root->right->right->left = newNode(35);

cout << "Inorder Traversal of given tree\n";


printInorder(root);

transformTree(root);

cout << "\n\nInorder Traversal of transformed tree\n";


printInorder(root);

return 0;
}
Output:

InorderTraversalofgiventree
1271115293540

InorderTraversaloftransformedtree
13913713011910475400
TimecomplexityofthismethodisO(n)asitdoesasimpletraversaloftree.

==================================================================================

PrintaBinaryTreeinVertical
Order|Set2(Hashmapbased
Method)

Givenabinarytree,printitvertically.Thefollowingexampleillustratesverticalordertraversal.

1
/\
23
/\/\
4567
\\
89


Theoutputofprintthistreeverticallywillbe:
4
2
156
38
7
9
Westronglyrecommendtominimizethebrowserandtrythisyourselffirst.
WehavediscussedaO(n2)solutioninthepreviouspost.Inthispost,anefficientsolutionbasedonhash
mapisdiscussed.WeneedtochecktheHorizontalDistancesfromrootforallnodes.Iftwonodeshavethe
sameHorizontalDistance(HD),thentheyareonsameverticalline.TheideaofHDissimple.HDforrootis
0,arightedge(edgeconnectingtorightsubtree)isconsideredas+1horizontaldistanceandaleftedgeis
consideredas1horizontaldistance.Forexample,intheabovetree,HDforNode4isat2,HDforNode2
is1,HDfor5and6is0andHDfornode7is+2.
WecandoinordertraversalofthegivenBinaryTree.Whiletraversingthetree,wecanrecursivelycalculate
HDs.Weinitiallypassthehorizontaldistanceas0forroot.Forleftsubtree,wepasstheHorizontalDistance
asHorizontaldistanceofrootminus1.Forrightsubtree,wepasstheHorizontalDistanceasHorizontal
Distanceofrootplus1.ForeveryHDvalue,wemaintainalistofnodesinahaspmap.Wheneverweseea
nodeintraversal,wegotothehashmapentryandaddthenodetothehashmapusingHDasakeyin
map.
FollowingisC++implementationoftheabovemethod.ThankstoChiragforprovidingthebelowC++
implementation.
// C++ program for printing vertical order of a given binary tree
#include <iostream>
#include <vector>
#include <map>
using namespace std;

// Structure for a binary tree node


struct Node
{
int key;
Node *left, *right;
};

// A utility function to create a new node

struct Node* newNode(int key)


{
struct Node* node = new Node;
node->key = key;
node->left = node->right = NULL;
return node;
}

// Utility function to store vertical order in map 'm'


// 'hd' is horigontal distance of current node from root.
// 'hd' is initally passed as 0
void getVerticalOrder(Node* root, int hd, map<int, vector<int>> &m)
{
// Base case
if (root == NULL)
return;

// Store current node in map 'm'


m[hd].push_back(root->key);

// Store nodes in left subtree


getVerticalOrder(root->left, hd-1, m);

// Store nodes in right subtree


getVerticalOrder(root->right, hd+1, m);
}

// The main function to print vertical oder of a binary tree


// with given root
void printVerticalOrder(Node* root)
{
// Create a map and store vertical oder in map using
// function getVerticalOrder()
map < int,vector<int> > m;
int hd = 0;
getVerticalOrder(root, hd,m);

// Traverse the map and print nodes at every horigontal


// distance (hd)
map< int,vector<int> > :: iterator it;
for (it=m.begin(); it!=m.end(); it++)
{
for (int i=0; i<it->second.size(); ++i)
cout << it->second[i] << " ";
cout << endl;
}
}

// Driver program to test above functions


int main()
{
Node *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->right->left->right = newNode(8);
root->right->right->right = newNode(9);
cout << "Vertical order traversal is \n";
printVerticalOrder(root);
return 0;
}
Output:

Verticalordertraversalis
4
2
156
38
7
9
TimeComplexityofhashingbasedsolutioncanbeconsideredasO(n)undertheassumptionthatwehave
goodhashingfunctionthatallowsinsertionandretrievaloperationsinO(1)time.IntheaboveC++

implementation,mapofSTLisused.mapinSTListypicallyimplementedusingaSelfBalancingBinary
SearchTreewherealloperationstakeO(Logn)time.Thereforetimecomplexityofaboveimplementationis
O(nLogn).
==================================================================================

PrintRightViewofaBinaryTree

GivenaBinaryTree,printRightviewofit.RightviewofaBinaryTreeissetofnodesvisiblewhentreeis
visitedfromRightside.

Rightviewoffollowingtreeis1378

1
/\
23
/\/\
4567
\
8
Westronglyrecommendtominimizethebrowserandtrythisyourselffirst.
TheRightviewcontainsallnodesthatarelastnodesintheirlevels.Asimplesolutionistodolevelorder
traversalandprintthelastnodeineverylevel.
Theproblemcanalsobesolvedusingsimplerecursivetraversal.Wecankeeptrackoflevelofanodeby
passingaparametertoallrecursivecalls.Theideaistokeeptrackofmaximumlevelalso.Andtraversethe
treeinamannerthatrightsubtreeisvisitedbeforeleftsubtree.Wheneverweseeanodewhoselevelis
morethanmaximumlevelsofar,weprintthenodebecausethisisthelastnodeinitslevel(Notethatwe
traversetherightsubtreebeforeleftsubtree).FollowingisCimplementationofthisapproach.
// C program to print right view of Binary Tree
#include<stdio.h>
#include<stdlib.h>

struct Node
{
int data;
struct Node *left, *right;
};

// A utility function to create a new Binary Tree Node


struct Node *newNode(int item)
{
struct Node *temp = (struct Node *)malloc(sizeof(struct Node));
temp->data = item;
temp->left = temp->right = NULL;
return temp;
}

// Recursive function to print right view of a binary tree.


void rightViewUtil(struct Node *root, int level, int *max_level)
{
// Base Case
if (root==NULL) return;

// If this is the last Node of its level


if (*max_level < level)
{
printf("%d\t", root->data);
*max_level = level;
}

// Recur for right subtree first, then left subtree


rightViewUtil(root->right, level+1, max_level);
rightViewUtil(root->left, level+1, max_level);
}

// A wrapper over rightViewUtil()


void rightView(struct Node *root)
{
int max_level = 0;
rightViewUtil(root, 1, &max_level);
}

// Driver Program to test above functions


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->right->left = newNode(6);
root->right->right = newNode(7);
root->right->left->right = newNode(8);

rightView(root);

return 0;
}
Output:

1378
TimeComplexity:Thefunctiondoesasimpletraversalofthetree,sothecomplexityisO(n).

==================================================================================

RedBlackTree|Set3(Delete)

WehavediscussedfollowingtopicsonRedBlacktreeinpreviousposts.Westronglyrecommendtorefer
followingpostasprerequisiteofthispost.
RedBlackTreeIntroduction
RedBlackTreeInsert
InsertionVsDeletion:
LikeInsertion,recoloringandrotationsareusedtomaintaintheRedBlackproperties.
Ininsertoperation,wecheckcolorofuncletodecidetheappropriatecase.Indeleteoperation,wecheck
colorofsiblingtodecidetheappropriatecase.
Themainpropertythatviolatesafterinsertionistwoconsecutivereds.Indelete,themainviolatedproperty
is,changeofblackheightinsubtreesasdeletionofablacknodemaycausereducedblackheightinone
roottoleafpath.
Deletionisfairlycomplexprocess.Tounderstanddeletion,notionofdoubleblackisused.Whenablack
nodeisdeletedandreplacedbyablackchild,thechildismarkedasdoubleblack.Themaintasknow
becomestoconvertthisdoubleblacktosingleblack.

DeletionSteps
Followingaredetailedstepsfordeletion.
1)PerformstandardBSTdelete.WhenweperformstandarddeleteoperationinBST,wealwaysendup
deletinganodewhichiseitherleaforhasonlyonechild(Foraninternalnode,wecopythesuccessorand
thenrecursivelycalldeleteforsuccessor,successorisalwaysaleafnodeoranodewithonechild).Sowe
onlyneedtohandlecaseswhereanodeisleaforhasonechild.Letvbethenodedeletedandubethe
childthatreplacesv.
2)SimpleCase:Ifeitheruorvisred,wemarkthereplacedchildasblack(Nochangeinblackheight).
Notethatbothuandvcannotberedasvisparentofuandtwoconsecutiveredsarenotallowedin
redblacktree.

3)IfBothuandvareBlack.
3.1)Coloruasdoubleblack.Nowourtaskreducestoconvertthisdoubleblacktosingleblack.NotethatIf
visleaf,thenuisNULLandcolorofNULLisconsideredasblack.Sothedeletionofablackleafalso
causesadoubleblack.

3.2)Dofollowingwhilethecurrentnodeuisdoubleblackoritisnotroot.Letsiblingofnodebes.

.(a):Ifsiblingsisblackandatleastoneofsiblingschildrenisred,performrotation(s).Letthered
childofsber.Thiscasecanbedividedinfoursubcasesdependinguponpositionsofsandr.
..(i)LeftLeftCase(sisleftchildofitsparentandrisleftchildofsorbothchildrenofsarered).
Thisismirrorofrightrightcaseshowninbelowdiagram.
..(ii)LeftRightCase(sisleftchildofitsparentandrisrightchild).Thisismirrorofrightleftcase
showninbelowdiagram.
..(iii)RightRightCase(sisrightchildofitsparentandrisrightchildofsorbothchildrenofsare
red)

..(iv)RightLeftCase(sisrightchildofitsparentandrisleftchildofs)

..(b):Ifsiblingisblackanditsbothchildrenareblack,performrecoloring,andrecurfortheparentif
parentisblack.


Inthiscase,ifparentwasred,thenwedidntneedtorecurforprent,wecansimplymakeitblack(red+
doubleblack=singleblack)
..(c):Ifsiblingisred,performarotationtomoveoldsiblingup,recolortheoldsiblingandparent.The
newsiblingisalwaysblack(Seethebelowdiagram).Thismainlyconvertsthetreetoblacksiblingcase(by
rotation)andleadstocase(a)or(b).Thiscasecanbedividedintwosubcases.
..(i)LeftCase(sisleftchildofitsparent).Thisismirrorofrightrightcaseshowninbelowdiagram.
Werightrotatetheparentp.
..(iii)RightCase(sisrightchildofitsparent).Weleftrotatetheparentp.


3.3)Ifuisroot,makeitsingleblackandreturn(Blackheightofcompletetreereducesby1).
==================================================================================

ConstructatreefromInorderand
Levelordertraversals
GiveninorderandlevelordertraversalsofaBinaryTree,constructtheBinaryTree.Followingisanexample
toillustratetheproblem.

Input:TwoarraysthatrepresentInorder
andlevelordertraversalsofa
BinaryTree
in[]={4,8,10,12,14,20,22}
level[]={20,8,22,4,12,10,14}

Output:Constructthetreerepresented
bythetwoarrays.
Fortheabovetwoarrays,the
constructedtreeisshownin
thediagramonrightside

Westronglyrecommendtominimizethebrowserandtrythisyourselffirst.
Thefollowingpostcanbeconsideredasaprerequisiteforthis.
ConstructTreefromgivenInorderandPreordertraversals
Letusconsidertheaboveexample.
in[]={4,8,10,12,14,20,22}
level[]={20,8,22,4,12,10,14}
InaLevelordersequence,thefirstelementistherootofthetree.Soweknow20isrootforgiven
sequences.Bysearching20inInordersequence,wecanfindoutallelementsonleftsideof20areinleft
subtreeandelementsonrightareinrightsubtree.Soweknowbelowstructurenow.

20
/\
/\

{4,8,10,12,14}{22}

Letuscall{4,8,10,12,14}asleftsubarrayinInordertraversaland{22}asrightsubarrayinInordertraversal.
Inlevelordertraversal,keysofleftandrightsubtreesarenotconsecutive.Soweextractallnodesfromlevel
ordertraversalwhichareinleftsubarrayofInordertraversal.Toconstructtheleftsubtreeofroot,werecur
fortheextractedelementsfromlevelordertraversalandleftsubarrayofinordertraversal.Intheabove
example,werecurforfollowingtwoarrays.

//Recurforfollowingarraystoconstructtheleftsubtree
In[]={4,8,10,12,14}
level[]={8,4,12,10,14}
Similarly,werecurforfollowingtwoarraysandconstructtherightsubtree.

//Recurforfollowingarraystoconstructtherightsubtree
In[]={22}
level[]={22}
FollowingisC++implementationoftheaboveapproach.
/* program to construct tree using inorder and levelorder traversals */
#include <iostream>
using namespace std;

/* A binary tree node */


struct Node
{
int key;
struct Node* left, *right;
};

/* Function to find index of value in arr[start...end] */


int search(int arr[], int strt, int end, int value)
{
for (int i = strt; i <= end; i++)
if (arr[i] == value)
return i;
return -1;
}

// n is size of level[], m is size of in[] and m < n. This


// function extracts keys from level[] which are present in

// in[]. The order of extracted keys must be maintained


int *extrackKeys(int in[], int level[], int m, int n)
{
int *newlevel = new int[m], j = 0;
for (int i = 0; i < n; i++)
if (search(in, 0, m-1, level[i]) != -1)
newlevel[j] = level[i], j++;
return newlevel;
}

/* function that allocates a new node with the given key */


Node* newNode(int key)
{
Node *node = new Node;
node->key = key;
node->left = node->right = NULL;
return (node);
}

/* Recursive function to construct binary tree of size n from


Inorder traversal in[] and Level Order traversal level[].
inSrt and inEnd are start and end indexes of array in[]
Initial values of inStrt and inEnd should be 0 and n -1.
The function doesn't do any error checking for cases
where inorder and levelorder do not form a tree */
Node* buildTree(int in[], int level[], int inStrt, int inEnd, int n)
{

// If start index is more than the end index


if (inStrt > inEnd)
return NULL;

/* The first node in level order traversal is root */


Node *root = newNode(level[0]);

/* If this node has no children then return */


if (inStrt == inEnd)

return root;

/* Else find the index of this node in Inorder traversal */


int inIndex = search(in, inStrt, inEnd, root->key);

// Extract left subtree keys from level order traversal


int *llevel = extrackKeys(in, level, inIndex, n);

// Extract right subtree keys from level order traversal


int *rlevel = extrackKeys(in + inIndex + 1, level, n-inIndex-1, n);

/* construct left and right subtress */


root->left = buildTree(in, llevel, inStrt, inIndex-1, n);
root->right = buildTree(in, rlevel, inIndex+1, inEnd, n);

// Free memory to avoid memory leak


delete [] llevel;
delete [] rlevel;

return root;
}

/* Uti;ity function to print inorder traversal of binary tree */


void printInorder(Node* node)
{
if (node == NULL)
return;
printInorder(node->left);
cout << node->key << " ";
printInorder(node->right);
}

/* Driver program to test above functions */


int main()
{
int in[] = {4, 8, 10, 12, 14, 20, 22};
int level[] = {20, 8, 22, 4, 12, 10, 14};

int n = sizeof(in)/sizeof(in[0]);
Node *root = buildTree(in, level, 0, n - 1, n);

/* Let us test the built tree by printing Insorder traversal */


cout << "Inorder traversal of the constructed tree is \n";
printInorder(root);

return 0;
}
Output:

Inordertraversaloftheconstructedtreeis
481012142022
AnupperboundontimecomplexityofabovemethodisO(n3).Inthemainrecursivefunction,extractNodes()
iscalledwhichtakesO(n2)time.
==================================================================================

Printallnodesatdistancekfroma
givennode

Givenabinarytree,atargetnodeinthebinarytree,andanintegervaluek,printallthenodesthatareat
distancekfromthegiventargetnode.Noparentpointersareavailable.

Considerthetreeshownindiagram

Input:target=pointertonodewithdata8.
root=pointertonodewithdata20.
k=2.
Output:101422

Iftargetis14andkis3,thenoutput
shouldbe"420"

Westronglyrecommendtominimizethebrowserandtrythisyourselffirst.
Therearetwotypesofnodestobeconsidered.
1)Nodesinthesubtreerootedwithtargetnode.Forexampleifthetargetnodeis8andkis2,thensuch
nodesare10and14.
2)Othernodes,maybeanancestoroftarget,oranodeinsomeothersubtree.Fortargetnode8andkis2,
thenode22comesinthiscategory.
Findingthefirsttypeofnodesiseasytoimplement.Justtraversesubtreesrootedwiththetargetnodeand
decrementkinrecursivecall.Whenthekbecomes0,printthenodecurrentlybeingtraversed(Seethisfor
moredetails).HerewecallthefunctionasprintkdistanceNodeDown().
Howtofindnodesofsecondtype?Fortheoutputnodesnotlyinginthesubtreewiththetargetnodeasthe
root,wemustgothroughallancestors.Foreveryancestor,wefinditsdistancefromtargetnode,letthe
distancebed,nowwegotoothersubtree(iftargetwasfoundinleftsubtree,thenwegotorightsubtreeand
viceversa)oftheancestorandfindallnodesatkddistancefromtheancestor.
FollowingisC++implementationoftheaboveapproach.
#include <iostream>
using namespace std;

// A binary Tree node


struct node
{
int data;
struct node *left, *right;
};

/* Recursive function to print all the nodes at distance k in the

tree (or subtree) rooted with given root. See */


void printkdistanceNodeDown(node *root, int k)
{
// Base Case
if (root == NULL || k < 0) return;

// If we reach a k distant node, print it


if (k==0)
{
cout << root->data << endl;
return;
}

// Recur for left and right subtrees


printkdistanceNodeDown(root->left, k-1);
printkdistanceNodeDown(root->right, k-1);
}

// Prints all nodes at distance k from a given target node.


// The k distant nodes may be upward or downward. This function
// Returns distance of root from target node, it returns -1 if target
// node is not present in tree rooted with root.
int printkdistanceNode(node* root, node* target , int k)
{
// Base Case 1: If tree is empty, return -1
if (root == NULL) return -1;

// If target is same as root. Use the downward function


// to print all nodes at distance k in subtree rooted with
// target or root
if (root == target)
{
printkdistanceNodeDown(root, k);
return 0;
}

// Recur for left subtree

int dl = printkdistanceNode(root->left, target, k);

// Check if target node was found in left subtree


if (dl != -1)
{
// If root is at distance k from target, print root
// Note that dl is Distance of root's left child from target
if (dl + 1 == k)
cout << root->data << endl;

// Else go to right subtree and print all k-dl-2 distant nodes


// Note that the right child is 2 edges away from left child
else
printkdistanceNodeDown(root->right, k-dl-2);

// Add 1 to the distance and return value for parent calls


return 1 + dl;
}

// MIRROR OF ABOVE CODE FOR RIGHT SUBTREE


// Note that we reach here only when node was not found in left subtree
int dr = printkdistanceNode(root->right, target, k);
if (dr != -1)
{
if (dr + 1 == k)
cout << root->data << endl;
else
printkdistanceNodeDown(root->left, k-dr-2);
return 1 + dr;
}

// If target was neither present in left nor in right subtree


return -1;
}

// A utility function to create a new binary tree node


node *newnode(int data)

{
node *temp = new node;
temp->data = data;
temp->left = temp->right = NULL;
return temp;
}

// Driver program to test above functions


int main()
{
/* Let us construct the tree shown in above diagram */
node * root = newnode(20);
root->left = newnode(8);
root->right = newnode(22);
root->left->left = newnode(4);
root->left->right = newnode(12);
root->left->right->left = newnode(10);
root->left->right->right = newnode(14);
node * target = root->left->right;
printkdistanceNode(root, target, 2);
return 0;
}
Output:

4
20
TimeComplexity:AtfirstlookthetimecomplexitylooksmorethanO(n),butifwetakeacloserlook,wecan
observethatnonodeistraversedmorethantwice.ThereforethetimecomplexityisO(n).
==================================================================================

PrintaBinaryTreeinVertical
Order|Set1
Givenabinarytree,printitvertically.Thefollowingexampleillustratesverticalordertraversal.

1
/\

23
/\/\
4567
\\
89

Theoutputofprintthistreeverticallywillbe:
4
2
156
38
7
9
Westronglyrecommendtominimizethebrowserandtrythisyourselffirst.
Theideaistotraversethetreeonceandgettheminimumandmaximumhorizontaldistancewithrespectto
root.Forthetreeshownabove,minimumdistanceis2(fornodewithvalue4)andmaximumdistanceis3
(Fornodewithvalue9).
Oncewehavemaximumandminimumdistancesfromroot,weiterateforeachverticallineatdistance
minimumtomaximumfromroot,andforeachverticallinetraversethetreeandprintthenodeswhichlieon
thatverticalline.
Algorithm:

//min>Minimumhorizontaldistancefromroot
//max>Maximumhorizontaldistancefromroot
//hd>Horizontaldistanceofcurrentnodefromroot
findMinMax(tree,min,max,hd)
iftreeisNULLthenreturn

ifhdislessthanminthen
min=hd
elseifhdisgreaterthanmaxthen
*max=hd

findMinMax(tree>left,min,max,hd1)
findMinMax(tree>right,min,max,hd+1)

printVerticalLine(tree,line_no,hd)
iftreeisNULLthenreturn

ifhdisequaltoline_no,then
print(tree>data)
printVerticalLine(tree>left,line_no,hd1)
printVerticalLine(tree>right,line_no,hd+1)
Implementation:
FollowingisC++implementationofabovealgorithm.
#include <iostream>
using namespace std;

// A node of binary tree


struct Node
{
int data;
struct Node *left, *right;
};

// A utility function to create a new Binary Tree node


Node* newNode(int data)
{
Node *temp = new Node;
temp->data = data;
temp->left = temp->right = NULL;
return temp;
}

// A utility function to find min and max distances with respect


// to root.
void findMinMax(Node *node, int *min, int *max, int hd)
{
// Base case
if (node == NULL) return;

// Update min and max


if (hd < *min) *min = hd;

else if (hd > *max) *max = hd;

// Recur for left and right subtrees


findMinMax(node->left, min, max, hd-1);
findMinMax(node->right, min, max, hd+1);
}

// A utility function to print all nodes on a given line_no.


// hd is horizontal distance of current node with respect to root.
void printVerticalLine(Node *node, int line_no, int hd)
{
// Base case
if (node == NULL) return;

// If this node is on the given line number


if (hd == line_no)
cout << node->data << " ";

// Recur for left and right subtrees


printVerticalLine(node->left, line_no, hd-1);
printVerticalLine(node->right, line_no, hd+1);
}

// The main function that prints a given binary tree in


// vertical order
void verticalOrder(Node *root)
{
// Find min and max distances with resepect to root
int min = 0, max = 0;
findMinMax(root, &min, &max, 0);

// Iterate through all possible vertical lines starting


// from the leftmost line and print nodes line by line
for (int line_no = min; line_no <= max; line_no++)
{
printVerticalLine(root, line_no, 0);
cout << endl;

}
}

// Driver program to test above functions


int main()
{
// Create binary tree shown in above figure
Node *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->right->left->right = newNode(8);
root->right->right->right = newNode(9);

cout << "Vertical order traversal is \n";


verticalOrder(root);

return 0;
}
Output:

Verticalordertraversalis
4
2
156
38
7
9
TimeComplexity:TimecomplexityofabovealgorithmisO(w*n)wherewiswidthofBinaryTreeandnis
numberofnodesinBinaryTree.Inworstcase,thevalueofwcanbeO(n)(consideracompletetreefor
example)andtimecomplexitycanbecomeO(n2).

=======================================================================

IntervalTree
Considerasituationwherewehaveasetofintervalsandweneedfollowingoperationstobeimplemented
efficiently.
1)Addaninterval
2)Removeaninterval
3)Givenanintervalx,findifxoverlapswithanyoftheexistingintervals.
IntervalTree:TheideaistoaugmentaselfbalancingBinarySearchTree(BST)likeRedBlackTree,AVL
Tree,etctomaintainsetofintervalssothatalloperationscanbedoneinO(Logn)time.
EverynodeofIntervalTreestoresfollowinginformation.
a)i:Anintervalwhichisrepresentedasapair[low,high]
b)max:Maximumhighvalueinsubtreerootedwiththisnode.
ThelowvalueofanintervalisusedaskeytomaintainorderinBST.Theinsertanddeleteoperationsare
sameasinsertanddeleteinselfbalancingBSTused.

Themainoperationistosearchforanoverlappinginterval.Followingisalgorithmforsearchingan
overlappingintervalxinanIntervaltreerootedwithroot.

IntervaloverlappingIntervalSearch(root,x)
1)Ifxoverlapswithroot'sinterval,returntheroot'sinterval.

2)Ifleftchildofrootisnotemptyandthemaxinleftchild
isgreaterthanx'slowvalue,recurforleftchild


3)Elserecurforrightchild.

Howdoestheabovealgorithmwork?
Lettheintervaltobesearchedbex.Weneedtoprovethisinforfollowingtwocases.
Case1:Whenwegotorightsubtree,oneofthefollowingmustbetrue.
a)Thereisanoverlapinrightsubtree:Thisisfineasweneedtoreturnoneoverlappinginterval.
b)Thereisnooverlapineithersubtree:WegotorightsubtreeonlywheneitherleftisNULLormaximum
valueinleftissmallerthanx.low.Sotheintervalcannotbepresentinleftsubtree.
Case2:Whenwegotoleftsubtree,oneofthefollowingmustbetrue.
a)Thereisanoverlapinleftsubtree:Thisisfineasweneedtoreturnoneoverlappinginterval.
b)Thereisnooverlapineithersubtree:Thisisthemostimportantpart.Weneedtoconsiderfollowingfacts.
Wewenttoleftsubtreebecausex.low<=maxinleftsubtree
.maxinleftsubtreeisahighofoneoftheintervalsletussay[a,max]inleftsubtree.
.Sincexdoesntoverlapwithanynodeinleftsubtreex.lowmustbesmallerthana.
.AllnodesinBSTareorderedbylowvalue,soallnodesinrightsubtreemusthavelowvaluegreaterthan
a.
.Fromabovetwofacts,wecansayallintervalsinrightsubtreehavelowvaluegreaterthanx.low.Sox
cannotoverlapwithanyintervalinrightsubtree.
ImplementationofIntervalTree:
FollowingisC++implementationofIntervalTree.TheimplementationusesbasicinsertoperationofBSTto
keepthingssimple.IdeallyitshouldbeinsertionofAVLTreeorinsertionofRedBlackTree.Deletionfrom
BSTisleftasanexercise.
#include <iostream>
using namespace std;

// Structure to represent an interval


struct Interval
{
int low, high;
};

// Structure to represent a node in Interval Search Tree


struct ITNode
{
Interval *i; // 'i' could also be a normal variable
int max;

ITNode *left, *right;


};

// A utility function to create a new Interval Search Tree Node


ITNode * newNode(Interval i)
{
ITNode *temp = new ITNode;
temp->i = new Interval(i);
temp->max = i.high;
temp->left = temp->right = NULL;
};

// A utility function to insert a new Interval Search Tree Node


// This is similar to BST Insert. Here the low value of interval
// is used tomaintain BST property
ITNode *insert(ITNode *root, Interval i)
{
// Base case: Tree is empty, new node becomes root
if (root == NULL)
return newNode(i);

// Get low value of interval at root


int l = root->i->low;

// If root's low value is smaller, then new interval goes to


// left subtree
if (i.low < l)
root->left = insert(root->left, i);

// Else, new node goes to right subtree.


else
root->right = insert(root->right, i);

// Update the max value of this ancestor if needed


if (root->max < i.high)
root->max = i.high;

return root;
}

// A utility function to check if given two intervals overlap


bool doOVerlap(Interval i1, Interval i2)
{
if (i1.low <= i2.high && i2.low <= i1.high)
return true;
return false;
}

// The main function that searches a given interval i in a given


// Interval Tree.
Interval *overlapSearch(ITNode *root, Interval i)
{
// Base Case, tree is empty
if (root == NULL) return NULL;

// If given interval overlaps with root


if (doOVerlap(*(root->i), i))
return root->i;

// If left child of root is present and max of left child is


// greater than or equal to given interval, then i may
// overlap with an interval is left subtree
if (root->left != NULL && root->left->max >= i.low)
return overlapSearch(root->left, i);

// Else interval can only overlap with right subtree


return overlapSearch(root->right, i);
}

void inorder(ITNode *root)


{
if (root == NULL) return;

inorder(root->left);

cout << "[" << root->i->low << ", " << root->i->high << "]"
<< " max = " << root->max << endl;

inorder(root->right);
}

// Driver program to test above functions


int main()
{
// Let us create interval tree shown in above figure
Interval ints[] = {{15, 20}, {10, 30}, {17, 19},
{5, 20}, {12, 15}, {30, 40}
};
int n = sizeof(ints)/sizeof(ints[0]);
ITNode *root = NULL;
for (int i = 0; i < n; i++)
root = insert(root, ints[i]);

cout << "Inorder traversal of constructed Interval Tree is\n";


inorder(root);

Interval x = {6, 7};

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:

InordertraversalofconstructedIntervalTreeis
[5,20]max=20
[10,30]max=30
[12,15]max=15

[15,20]max=40
[17,19]max=40
[30,40]max=40

Searchingforinterval[6,7]
Overlapswith[5,20]
ApplicationsofIntervalTree:
Intervaltreeismainlyageometricdatastructureandoftenusedforwindowingqueries,forinstance,tofind
allroadsonacomputerizedmapinsidearectangularviewport,ortofindallvisibleelementsinsidea
threedimensionalscene(SourceWiki).
IntervalTreevsSegmentTree
Bothsegmentandintervaltreesstoreintervals.Segmenttreeismainlyoptimizedforqueriesforagiven
point,andintervaltreesaremainlyoptimizedforoverlappingqueriesforagiveninterval.

=======================================================================

CheckifagivenBinaryTreeis
heightbalancedlikeaRedBlack
Tree
InaRedBlackTree,themaximumheightofanodeisatmosttwicetheminimumheight(Thefour
RedBlacktreepropertiesmakesurethisisalwaysfollowed).GivenaBinarySearchTree,weneedtocheck
forfollowingproperty.
Foreverynode,lengthofthelongestleaftonodepathhasnotmorethantwicethenodesonshortestpath
fromnodetoleaf.

1240
\/\
1410100
\/\
1660150
CannotbeaRedBlackTreeItcanbeRedBlackTree
withanycolorassignment
Maxheightof12is1
Minheightof12is3

10
/\
5100
/\
50150
/
40
ItcanalsobeRedBlackTree

ExpectedtimecomplexityisO(n).Thetreeshouldbetraversedatmostonceinthesolution.
Westronglyrecommendtominimizethebrowserandtrythisyourselffirst.
Foreverynode,weneedtogetthemaximumandminimumheightsandcomparethem.Theideaisto
traversethetreeandforeverynodecheckifitsbalanced.Weneedtowritearecursivefunctionthatreturns
threethings,abooleanvaluetoindicatethetreeisbalancedornot,minimumheightandmaximumheight.
Toreturnmultiplevalues,wecaneitheruseastructureorpassvariablesbyreference.Wehavepassed
maxhandminhbyreferencesothatthevaluescanbeusedinparentcalls.
/* Program to check if a given Binary Tree is balanced like a Red-Black Tree */
#include <iostream>
using namespace std;

struct Node
{
int key;
Node *left, *right;
};

/* utility that allocates a new Node with the given key */


Node* newNode(int key)
{
Node* node = new Node;
node->key = key;
node->left = node->right = NULL;
return (node);
}

// Returns returns tree if the Binary tree is balanced like a Red-Black


// tree. This function also sets value in maxh and minh (passed by
// reference). maxh and minh are set as maximum and minimum heights of root.
bool isBalancedUtil(Node *root, int &maxh, int &minh)
{
// Base case
if (root == NULL)
{
maxh = minh = 0;
return true;
}

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;

// Check if right subtree is balanced, also set rmxh and rmnh


if (isBalancedUtil(root->right, rmxh, rmnh) == 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;

// See if this node is balanced


if (maxh <= 2*minh)
return true;

return false;
}

// A wrapper over isBalancedUtil()


bool isBalanced(Node *root)
{

int maxh, minh;


return isBalancedUtil(root, maxh, minh);
}

/* Driver program to test above functions*/


int main()
{
Node * root = newNode(10);
root->left = newNode(5);
root->right = newNode(100);
root->right->left = newNode(50);
root->right->right = newNode(150);
root->right->left->left = newNode(40);
isBalanced(root)? cout << "Balanced" : cout << "Not Balanced";

return 0;
}
Output:

Balanced
TimeComplexity:TimeComplexityofabovecodeisO(n)asthecodedoesasimpletreetraversal.

=======================================================================

Printallnodesthatareatdistancek
fromaleafnode
GivenaBinaryTreeandapositiveintegerk,printallnodesthataredistancekfromaleafnode.
Herethemeaningofdistanceisdifferentfrompreviouspost.Herekdistancefromaleafmeansklevels
higherthanaleafnode.ForexampleifkismorethanheightofBinaryTree,thennothingshouldbeprinted.
ExpectedtimecomplexityisO(n)wherenisthenumbernodesinthegivenBinaryTree.


Westronglyrecommendtominimizethebrowserandtrythisyourselffirst.
Theideaistotraversethetree.Keepstoringallancestorstillwehitaleafnode.Whenwereachaleafnode,
weprinttheancestoratdistancek.Wealsoneedtokeeptrackofnodesthatarealreadyprintedasoutput.
Forthatweuseabooleanarrayvisited[].
/* Program to print all nodes which are at distance k from a leaf */
#include <iostream>
using namespace std;
#define MAX_HEIGHT 10000

struct Node
{
int key;
Node *left, *right;
};

/* utility that allocates a new Node with the given key */


Node* newNode(int key)
{
Node* node = new Node;
node->key = key;
node->left = node->right = NULL;
return (node);
}

/* 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;

/* append this Node to the path array */


path[pathLen] = node->key;
visited[pathLen] = false;
pathLen++;

/* it's a leaf, so print the ancestor at distance k only


if the ancestor is not already printed */
if (node->left == NULL && node->right == NULL &&
pathLen-k-1 >= 0 && visited[pathLen-k-1] == false)
{
cout << path[pathLen-k-1] << " ";
visited[pathLen-k-1] = true;
return;
}

/* If not leaf node, recur for left and right subtrees */


kDistantFromLeafUtil(node->left, path, visited, pathLen, k);
kDistantFromLeafUtil(node->right, path, visited, pathLen, k);
}

/* 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);


}

/* Driver program to test above functions*/


int main()
{
// Let us create binary tree given in the above example
Node * 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->right->left->right = newNode(8);

cout << "Nodes at distance 2 are: ";


printKDistantfromLeaf(root, 2);

return 0;
}
Output:

Nodesatdistance2are:31
TimeComplexity:TimeComplexityofabovecodeisO(n)asthecodedoesasimpletreetraversal.

======================================================================

Finddistancebetweentwogivenkeys
ofaBinaryTree
Findthedistancebetweentwokeysinabinarytree,noparentpointersaregiven.Distancebetweentwo
nodesistheminimumnumberofedgestobetraversedtoreachonenodefromother.


Westronglyrecommendtominimizethebrowserandtrythisyourselffirst.
Thedistancebetweentwonodescanbeobtainedintermsoflowestcommonancestor.Followingisthe
formula.

Dist(n1,n2)=Dist(root,n1)+Dist(root,n2)2*Dist(root,lca)
'n1'and'n2'arethetwogivenkeys
'root'isrootofgivenBinaryTree.
'lca'islowestcommonancestorofn1andn2
Dist(n1,n2)isthedistancebetweenn1andn2.

FollowingisC++implementationofaboveapproach.Theimplementationisadoptedfromlastcodeprovided
inLowestCommonAncestorPost.
/* Program to find distance between n1 and n2 using one traversal */
#include <iostream>
using namespace std;

// A Binary Tree Node


struct Node
{
struct Node *left, *right;
int key;
};

// Utility function to create a new tree Node


Node* newNode(int key)
{
Node *temp = new Node;
temp->key = key;
temp->left = temp->right = NULL;
return temp;
}

// Returns level of key k if it is present in tree, otherwise returns -1


int findLevel(Node *root, int k, int level)
{
// Base Case
if (root == NULL)
return -1;

// If key is present at root, or in left subtree or right subtree,


// return true;
if (root->key == k)
return level;

int l = findLevel(root->left, k, level+1);


return (l != -1)? l : findLevel(root->right, k, level+1);
}

// 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;

// If either n1 or n2 matches with root's key, report


// the presence by returning root (Note that if a key is
// ancestor of other, then the ancestor key becomes LCA
if (root->key == n1)
{
d1 = lvl;
return root;
}
if (root->key == n2)
{
d2 = lvl;
return root;
}

// Look for n1 and n2 in left and right subtrees


Node *left_lca = findDistUtil(root->left, n1, n2, d1, d2, dist, lvl+1);
Node *right_lca = findDistUtil(root->right, n1, n2, d1, d2, dist, lvl+1);

// If both of the above calls return Non-NULL, then one key


// is present in once subtree and other is present in other,
// So this node is the LCA
if (left_lca && right_lca)
{
dist = d1 + d2 - 2*lvl;
return root;
}

// Otherwise check if left subtree or right subtree is LCA


return (left_lca != NULL)? left_lca: right_lca;
}

// The main function that returns distance between n1 and n2


// This function returns -1 if either n1 or n2 is not present in
// Binary Tree.
int findDistance(Node *root, int n1, int n2)
{
// Initialize d1 (distance of n1 from root), d2 (distance of n2

// from root) and dist(distance between n1 and n2)


int d1 = -1, d2 = -1, dist;
Node *lca = findDistUtil(root, n1, n2, d1, d2, dist, 1);

// If both n1 and n2 were present in Binary Tree, return dist


if (d1 != -1 && d2 != -1)
return dist;

// If n1 is ancestor of n2, consider n1 as root and find level


// of n2 in subtree rooted with n1
if (d1 != -1)
{
dist = findLevel(lca, n2, 0);
return dist;
}

// If n2 is ancestor of n1, consider n2 as root and find level


// of n1 in subtree rooted with n2
if (d2 != -1)
{
dist = findLevel(lca, n1, 0);
return dist;
}

return -1;
}

// Driver program to test above functions


int main()
{
// Let us create binary tree given in the above example
Node * 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->right->left->right = newNode(8);
cout << "Dist(4, 5) = " << findDistance(root, 4, 5);
cout << "\nDist(4, 6) = " << findDistance(root, 4, 6);
cout << "\nDist(3, 4) = " << findDistance(root, 3, 4);
cout << "\nDist(2, 4) = " << findDistance(root, 2, 4);
cout << "\nDist(8, 5) = " << findDistance(root, 8, 5);
return 0;
}
Output:

Dist(4,5)=2
Dist(4,6)=4
Dist(3,4)=3
Dist(2,4)=1
Dist(8,5)=5
TimeComplexity:TimecomplexityoftheabovesolutionisO(n)asthemethoddoesasingletreetraversal.

=======================================================================

LowestCommonAncestorina
BinaryTree|Set1

Givenabinarytree(notabinarysearchtree)andtwovaluessayn1andn2,writeaprogramtofindtheleast
commonancestor.
FollowingisdefinitionofLCAfromWikipedia:
LetTbearootedtree.Thelowestcommonancestorbetweentwonodesn1andn2isdefinedasthelowest
nodeinTthathasbothn1andn2asdescendants(whereweallowanodetobeadescendantofitself).
TheLCAofn1andn2inTisthesharedancestorofn1andn2thatislocatedfarthestfromtheroot.
Computationoflowestcommonancestorsmaybeuseful,forinstance,aspartofaprocedurefor
determiningthedistancebetweenpairsofnodesinatree:thedistancefromn1ton2canbecomputedas
thedistancefromtherootton1,plusthedistancefromtherootton2,minustwicethedistancefromtheroot
totheirlowestcommonancestor.(SourceWiki)


WehavediscussedanefficientsolutiontofindLCAinBinarySearchTree.InBinarySearchTree,using
BSTproperties,wecanfindLCAinO(h)timewherehisheightoftree.Suchanimplementationisnot
possibleinBinaryTreeaskeysBinaryTreenodesdontfollowanyorder.Followingaredifferentapproaches
tofindLCAinBinaryTree.
Method1(ByStoringrootton1androotton2paths):
FollowingissimpleO(n)algorithmtofindLCAofn1andn2.
1)Findpathfromrootton1andstoreitinavectororarray.
2)Findpathfromrootton2andstoreitinanothervectororarray.
3)Traversebothpathstillthevaluesinarraysaresame.Returnthecommonelementjustbeforethe
mismatch.
FollowingisC++implementationofabovealgorithm.
// A O(n) solution to find LCA of two given values n1 and n2
#include <iostream>
#include <vector>
using namespace std;

// A Bianry Tree node


struct Node
{
int key;
struct Node *left, *right;
};

// 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;

// Store this node in path vector. The node will be removed if


// not in path from root to k
path.push_back(root->key);

// See if the k is same as root's key


if (root->key == k)
return true;

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


if ( (root->left && findPath(root->left, path, k)) ||
(root->right && findPath(root->right, path, k)) )
return true;

// If not present in subtree rooted with root, remove root from


// path[] and return false
path.pop_back();
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;

// Find paths from root to n1 and root to n1. If either n1 or n2


// is not present, return -1
if ( !findPath(root, path1, n1) || !findPath(root, path2, n2))
return -1;

/* Compare the paths to get the first different value */


int i;
for (i = 0; i < path1.size() && i < path2.size() ; i++)
if (path1[i] != path2[i])
break;
return path1[i-1];
}

// Driver program to test above functions


int main()
{
// Let us create the Binary Tree shown in above diagram.
Node * 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);
cout << "LCA(4, 5) = " << findLCA(root, 4, 5);
cout << "\nLCA(4, 6) = " << findLCA(root, 4, 6);
cout << "\nLCA(3, 4) = " << findLCA(root, 3, 4);
cout << "\nLCA(2, 4) = " << findLCA(root, 2, 4);
return 0;
}
Output:

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

TimeComplexity:TimecomplexityoftheabovesolutionisO(n).Thetreeistraversedtwice,andthenpath
arraysarecompared.
ThankstoRaviChandraEnagantiforsuggestingtheinitialsolutionbasedonthismethod.

Method2(UsingSingleTraversal)
Themethod1findsLCAinO(n)time,butrequiresthreetreetraversalsplusextraspacesforpatharrays.If
weassumethatthekeysn1andn2arepresentinBinaryTree,wecanfindLCAusingsingletraversalof
BinaryTreeandwithoutextrastorageforpatharrays.
Theideaistotraversethetreestartingfromroot.Ifanyofthegivenkeys(n1andn2)matcheswithroot,
thenrootisLCA(assumingthatbothkeysarepresent).Ifrootdoesntmatchwithanyofthekeys,werecur
forleftandrightsubtree.Thenodewhichhasonekeypresentinitsleftsubtreeandtheotherkeypresentin
rightsubtreeistheLCA.Ifbothkeyslieinleftsubtree,thenleftsubtreehasLCAalso,otherwiseLCAliesin
rightsubtree.
/* Program to find LCA of n1 and n2 using one traversal of Binary Tree */
#include <iostream>
using namespace std;

// A Binary Tree Node


struct Node
{
struct Node *left, *right;
int key;
};

// Utility function to create a new tree Node


Node* newNode(int key)
{
Node *temp = new Node;
temp->key = key;
temp->left = temp->right = NULL;
return temp;
}

// 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;

// If either n1 or n2 matches with root's key, report


// the presence by returning root (Note that if a key is
// ancestor of other, then the ancestor key becomes LCA
if (root->key == n1 || root->key == n2)
return root;

// Look for keys in left and right subtrees


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

// If both of the above calls return Non-NULL, then one key


// is present in once subtree and other is present in other,
// So this node is the LCA
if (left_lca && right_lca) return root;

// Otherwise check if left subtree or right subtree is LCA


return (left_lca != NULL)? left_lca: right_lca;
}

// Driver program to test above functions


int main()
{
// Let us create binary tree given in the above example
Node * 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);
cout << "LCA(4, 5) = " << findLCA(root, 4, 5)->key;
cout << "\nLCA(4, 6) = " << findLCA(root, 4, 6)->key;
cout << "\nLCA(3, 4) = " << findLCA(root, 3, 4)->key;

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


return 0;
}
Output:

LCA(4,5)=2
LCA(4,6)=1
LCA(3,4)=1
LCA(2,4)=2
ThankstoAtulSinghforsuggestingthissolution.
TimeComplexity:TimecomplexityoftheabovesolutionisO(n)asthemethoddoesasimpletreetraversal
inbottomupfashion.
NotethattheabovemethodassumesthatkeysarepresentinBinaryTree.Ifonekeyispresentandotheris
absent,thenitreturnsthepresentkeyasLCA(IdeallyshouldhavereturnedNULL).
Wecanextendthismethodtohandleallcasesbypassingtwobooleanvariablesv1andv2.v1issetastrue
whenn1ispresentintreeandv2issetastrueifn2ispresentintree.
/* Program to find LCA of n1 and n2 using one traversal of Binary Tree.
It handles all cases even when n1 or n2 is not there in Binary Tree */
#include <iostream>
using namespace std;

// A Binary Tree Node


struct Node
{
struct Node *left, *right;
int key;
};

// Utility function to create a new tree Node


Node* newNode(int key)
{
Node *temp = new Node;
temp->key = key;
temp->left = temp->right = NULL;
return temp;
}

// 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;

// If either n1 or n2 matches with root's key, report the presence


// by setting v1 or v2 as true and return root (Note that if a key
// is ancestor of other, then the ancestor key becomes LCA)
if (root->key == n1)
{
v1 = true;
return root;
}
if (root->key == n2)
{
v2 = true;
return root;
}

// Look for keys in left and right subtrees


Node *left_lca = findLCAUtil(root->left, n1, n2, v1, v2);
Node *right_lca = findLCAUtil(root->right, n1, n2, v1, v2);

// If both of the above calls return Non-NULL, then one key


// is present in once subtree and other is present in other,
// So this node is the LCA
if (left_lca && right_lca) return root;

// Otherwise check if left subtree or right subtree is LCA


return (left_lca != NULL)? left_lca: right_lca;
}

// Returns true if key k is present in tree rooted with root


bool find(Node *root, int k)
{

// Base Case
if (root == NULL)
return false;

// If key is present at root, or in left subtree or right subtree,


// return true;
if (root->key == k || find(root->left, k) || find(root->right, k))
return true;

// Else return false


return false;
}

// 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;

// Find lca of n1 and n2 using the technique discussed above


Node *lca = findLCAUtil(root, n1, n2, v1, v2);

// Return LCA only if both n1 and n2 are present in tree


if (v1 && v2 || v1 && find(lca, n2) || v2 && find(lca, n1))
return lca;

// Else return NULL


return NULL;
}

// Driver program to test above functions


int main()
{
// Let us create binary tree given in the above example
Node * 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);
Node *lca = findLCA(root, 4, 5);
if (lca != NULL)
cout << "LCA(4, 5) = " << lca->key;
else
cout << "Keys are not present ";

lca = findLCA(root, 4, 10);


if (lca != NULL)
cout << "\nLCA(4, 10) = " << lca->key;
else
cout << "\nKeys are not present ";

return 0;
}
Output:

LCA(4,5)=2
Keysarenotpresent
=======================================================================

Printallnodesthatdonthave
sibling

GivenaBinaryTree,printallnodesthatdonthaveasibling(asiblingisanodethathassameparent.Ina
BinaryTree,therecanbeatmostonesibling).Rootshouldnotbeprintedasrootcannothaveasibling.
Forexample,theoutputshouldbe456forthefollowingtree.


Westronglyrecommendtominimizethebrowserandtrythisyourselffirst.
Thisisatypicaltreetraversalquestion.Westartfromrootandcheckifthenodehasonechild,ifyesthen
printtheonlychildofthatnode.Ifnodehasbothchildren,thenrecurforboththechildren.
/* Program to find singles in a given binary tree */
#include <iostream>
using namespace std;

// A Binary Tree Node


struct node
{
struct node *left, *right;
int key;
};

// Utility function to create a new tree node


node* newNode(int key)
{
node *temp = new node;
temp->key = key;
temp->left = temp->right = NULL;
return temp;

// Function to print all non-root nodes that don't have a sibling


void printSingles(struct node *root)
{
// Base case
if (root == NULL)
return;

// If this is an internal node, recur for left


// and right subtrees
if (root->left != NULL && root->right != NULL)
{
printSingles(root->left);
printSingles(root->right);
}

// If left child is NULL and right is not, print right child


// and recur for right child
else if (root->right != NULL)
{
cout << root->right->key << " ";
printSingles(root->right);
}

// If right child is NULL and left is not, print left child


// and recur for left child
else if (root->left != NULL)
{
cout << root->left->key << " ";
printSingles(root->left);
}
}

// Driver program to test above functions


int main()
{

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


node *root = newNode(1);
root->left = newNode(2);
root->right = newNode(3);
root->left->right = newNode(4);
root->right->left = newNode(5);
root->right->left->left = newNode(6);
printSingles(root);
return 0;
}
Output:

456
TimeComplexityofabovecodeisO(n)asthecodedoesasimpletreetraversal.

=======================================================================

ConvertagivenBinaryTreeto
DoublyLinkedList|Set3

GivenaBinaryTree(BT),convertittoaDoublyLinkedList(DLL)InPlace.Theleftandrightpointersin
nodesaretobeusedaspreviousandnextpointersrespectivelyinconvertedDLL.Theorderofnodesin
DLLmustbesameasInorderofthegivenBinaryTree.ThefirstnodeofInordertraversal(leftmostnodein
BT)mustbeheadnodeoftheDLL.


Followingtwodifferentsolutionshavebeendiscussedforthisproblem.
ConvertagivenBinaryTreetoDoublyLinkedList|Set1
ConvertagivenBinaryTreetoDoublyLinkedList|Set2
Inthispost,athirdsolutionisdiscussedwhichseemstobethesimplestofall.Theideaistodoinorder
traversalofthebinarytree.Whiledoinginordertraversal,keeptrackofthepreviouslyvisitednodeina
variablesayprev.Foreveryvisitednode,makeitnextofprevandpreviousofthisnodeasprev.
Thankstorahul,wishallandallotherreadersfortheirusefulcommentsontheabovetwoposts.
FollowingisC++implementationofthissolution.
// A C++ program for in-place conversion of Binary Tree to DLL
#include <iostream>
using namespace std;

/* A binary tree node has data, and left and right pointers */
struct node
{
int data;
node* left;
node* right;
};

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


// Linked List

// root --> Root of Binary Tree


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

// Initialize previously visited node as NULL. This is


// static so that the same value is accessible in all recursive
// calls
static node* prev = NULL;

// Recursively convert left subtree


BinaryTree2DoubleLinkedList(root->left, head);

// Now convert this node


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

// Finally convert right subtree


BinaryTree2DoubleLinkedList(root->right, head);
}

/* Helper function that allocates a new node with the


given data and NULL left and right pointers. */
node* newNode(int data)
{
node* new_node = new node;
new_node->data = data;
new_node->left = new_node->right = NULL;
return (new_node);

/* Function to print nodes in a given doubly linked list */


void printList(node *node)
{
while (node!=NULL)
{
cout << node->data << " ";
node = node->right;
}
}

/* Driver program to test above functions*/


int main()
{
// Let us create the tree shown in above diagram
node *root

= newNode(10);

root->left

= newNode(12);

root->right

= newNode(15);

root->left->left = newNode(25);
root->left->right = newNode(30);
root->right->left = newNode(36);

// Convert to DLL
node *head = NULL;
BinaryTree2DoubleLinkedList(root, &head);

// Print the converted list


printList(head);

return 0;
}
Output:

251230103615
Notethatuseofstaticvariableslikeaboveisnotarecommendedpractice(wehaveusedstaticfor
simplicity).Imagineasituationwheresamefunctioniscalledfortwoormoretrees,theoldvalueofprev

wouldbeusedinnextcallforadifferenttree.Toavoidsuchproblems,wecanusedoublepointeror
referencetoapointer.
TimeComplexity:Theaboveprogramdoesasimpleinordertraversal,sotimecomplexityisO(n)wherenis
thenumberofnodesingivenbinarytree.

=======================================================================

RedBlackTree|Set2(Insert)

Inthepreviouspost,wediscussedintroductiontoRedBlackTrees.Inthispost,insertionisdiscussed.
InAVLtreeinsertion,weusedrotationasatooltodobalancingafterinsertioncausedimbalance.In
RedBlacktree,weusetwotoolstodobalancing.
1)Recoloring
2)Rotation
Wetryrecoloringfirst,ifrecoloringdoesntwork,thenwegoforrotation.Followingisdetailedalgorithm.The
algorithmshasmainlytwocasesdependinguponthecolorofuncle.Ifuncleisred,wedorecoloring.Ifuncle
isblack,wedorotationsand/orrecoloring.
ColorofaNULLnodeisconsideredasBLACK.
Letxbethenewlyinsertednode.
1)PerformstandardBSTinsertionandmakethecolorofnewlyinsertednodesasRED.
2)DofollowingifcolorofxsparentisnotBLACKorxisnotroot.
.a)IfxsuncleisRED(Grandparentmusthavebeenblackfromproperty4)
..(i)ChangecolorofparentanduncleasBLACK.
..(ii)colorofgrandparentasRED.
..(iii)Changex=xsgrandparent,repeatsteps2and3fornewx.

.b)IfxsuncleisBLACK,thentherecanbefourconfigurationsforx,xsparent(p)andxsgrandparent
(g)(ThisissimilartoAVLTree)
..i)LeftLeftCase(pisleftchildofgandxisleftchildofp)
..ii)LeftRightCase(pisleftchildofgandxisrightchildofp)
..iii)RightRightCase(Mirrorofcasea)
..iv)RightLeftCase(Mirrorofcasec)
3)Ifxisroot,changecolorofxasBLACK(Blackheightofcompletetreeincreasesby1).
FollowingareoperationstobeperformedinfoursubcaseswhenuncleisBLACK.

AllfourcaseswhenUncleisBLACK
LeftLeftCase(Seeg,pandx)

LeftRightCase(Seeg,pandx)

RightRightCase(Seeg,pandx)


RightLeftCase(Seeg,pandx)

ExamplesofInsertion

PleasereferCProgramforRedBlackTreeInsertionforcompleteimplementationofabovealgorithm.

=======================================================================

RedBlackTree|Set1(Introduction)
RedBlackTreeisaselfbalancingBinarySearchTree(BST)whereeverynodefollowsfollowingrules.


1)Everynodehasacoloreitherredorblack.
2)Rootoftreeisalwaysblack.
3)Therearenotwoadjacentrednodes(Arednodecannothavearedparentorredchild).
4)EverypathfromroottoaNULLnodehassamenumberofblacknodes.
WhyRedBlackTrees?
MostoftheBSToperations(e.g.,search,max,min,insert,delete..etc)takeO(h)timewherehistheheight
oftheBST.ThecostoftheseoperationsmaybecomeO(n)foraskewedBinarytree.Ifwemakesurethat
heightofthetreeremainsO(Logn)aftereveryinsertionanddeletion,thenwecanguaranteeanupper
boundofO(Logn)foralltheseoperations.TheheightofaRedBlacktreeisalwaysO(Logn)wherenisthe
numberofnodesinthetree.
ComparisonwithAVLTree
TheAVLtreesaremorebalancedcomparedtoRedBlackTrees,buttheymaycausemorerotationsduring
insertionanddeletion.Soifyourapplicationinvolvesmanyfrequentinsertionsanddeletions,thenRed
Blacktreesshouldbepreferred.Andiftheinsertionsanddeletionsarelessfrequentandsearchismore
frequentoperation,thenAVLtreeshouldbepreferredoverRedBlackTree.
HowdoesaRedBlackTreeensurebalance?
Asimpleexampletounderstandbalancingis,achainof3nodesisnotpossibleinredblacktree.Wecantry
anycombinationofcolorsandseeallofthemviolateRedBlacktreeproperty.

Achainof3nodesisnodesisnotpossibleinRedBlackTrees.
FollowingareNOTRedBlackTrees
303030

/\/\/\
20NIL20NIL20NIL
/\/\/\
10NIL10NIL10NIL
ViolatesViolatesViolates

Property4.Property4Property3

FollowingaredifferentpossibleRedBlackTreeswithabove3keys
2020
/\/\
10301030
/\/\/\/\
NILNILNILNILNILNILNILNIL

Fromtheaboveexamples,wegetsomeideahowRedBlacktreesensurebalance.Followingisan
importantfactaboutbalancinginRedBlackTrees.

EveryRedBlackTreewithnnodeshasheight<=

Thiscanbeprovedusingfollowingfacts:
1)ForageneralBinaryTree,letkbetheminimumnumberofnodesonallroottoNULLpaths,thenn>=2k
1(Ex.Ifkis3,thennisatleast7).Thisexpressioncanalsobewrittenask<=

2)Fromproperty4ofRedBlacktreesandaboveclaim,wecansayinaRedBlackTreewithnnodes,there
isaroottoleafpathwithatmost

blacknodes.

3)Fromproperty3ofRedBlacktrees,wecanclaimthatthenumberblacknodesinaRedBlacktreeisat
least

wherenistotalnumberofnodes.

Fromabove2points,wecanconcludethefactthatRedBlackTreewithnnodeshasheight<=

Inthispost,weintroducedRedBlacktreesanddiscussedhowbalanceisensured.Thehardpartisto
maintainbalancewhenkeysareaddedandremoved.Wewillsoonbediscussinginsertionanddeletion
operationsincomingpostsonRedBlacktree.
Exercise:
1)IsitpossibletohaveallblacknodesinaRedBlacktree?
2)DrawaRedBlackTreethatisnotanAVLtreestructurewise?
InsertionandDeletion
RedBlackTreeInsertion
RedBlackTreeDeletion
References:
IntroductiontoAlgorithms3rdEditionbyCliffordStein,ThomasH.Cormen,CharlesE.Leiserson,RonaldL.
Rivest

http://en.wikipedia.org/wiki/Red%E2%80%93black_tree
VideoLectureonRedBlackTreebyTimRoughgarden
MITVideoLectureonRedBlackTree
MITLectureNotesonRedBlackTree

=======================================================================

Sumofallthenumbersthatare
formedfromroottoleafpaths
Givenabinarytree,whereeverynodevalueisaDigitfrom19.Findthesumofallthenumberswhichare
formedfromroottoleafpaths.
ForexampleconsiderthefollowingBinaryTree.

6
/\
35
/\\
254
/\
74
Thereare4leaves,hence4roottoleafpaths:
PathNumber
6>3>2632
6>3>5>76357
6>3>5>46354
6>5>4654
Answer=632+6357+6354+654=13997
Westronglyrecommendyoutominimizethebrowserandtrythisyourselffirst.
Theideaistodoapreordertraversalofthetree.Inthepreordertraversal,keeptrackofthevaluecalculated
tillthecurrentnode,letthisvaluebeval.Foreverynode,weupdatethevalasval*10plusnodesdata.
// C program to find sum of all paths from root to leaves
#include <stdio.h>
#include <stdlib.h>

struct node

{
int data;
struct node *left, *right;
};

// function to allocate new 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);
}

// 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);

// if current node is leaf, return the current value of val


if (root->left==NULL && root->right==NULL)
return val;

// recur sum of values for left and right subtree


return treePathsSumUtil(root->left, val) +
treePathsSumUtil(root->right, val);
}

// A wrapper function over treePathsSumUtil()


int treePathsSum(struct node *root)
{

// Pass the initial value as 0 as there is nothing above root


return treePathsSumUtil(root, 0);
}

// Driver function to test the above functions


int main()
{
struct node *root = newNode(6);
root->left

= newNode(3);

root->right

= newNode(5);

root->right->right= newNode(7);
root->left->left = newNode(2);
root->left->right = newNode(5);
root->right->right = newNode(4);
root->left->right->left = newNode(7);
root->left->right->right = newNode(4);
printf("Sum of all paths is %d", treePathsSum(root));
return 0;
}
Output:

Sumofallpathsis13997
TimeComplexity:Theabovecodeisasimplepreordertraversalcodewhichvisitseveryexactlyonce.
Therefore,thetimecomplexityisO(n)wherenisthenumberofnodesinthegivenbinarytree.

=======================================================================

SplayTree|Set2(Insert)
Itisrecommendedtoreferfollowingpostasprerequisiteofthispost.
SplayTree|Set1(Search)
Asdiscussedinthepreviouspost,Splaytreeisaselfbalancingdatastructurewherethelastaccessedkey
isalwaysatroot.TheinsertoperationissimilartoBinarySearchTreeinsertwithadditionalstepstomake
surethatthenewlyinsertedkeybecomesthenewroot.
Followingaredifferentcasestoinsertakeykinsplaytree.
1)RootisNULL:Wesimplyallocateanewnodeandreturnitasroot.

2)Splaythegivenkeyk.Ifkisalreadypresent,thenitbecomesthenewroot.Ifnotpresent,thenlast
accessedleafnodebecomesthenewroot.
3)Ifnewrootskeyissameask,dontdoanythingaskisalreadypresent.
4)Elseallocatememoryfornewnodeandcomparerootskeywithk.
.4.a)Ifkissmallerthanrootskey,makerootasrightchildofnewnode,copyleftchildofrootasleft
childofnewnodeandmakeleftchildofrootasNULL.
.4.b)Ifkisgreaterthanrootskey,makerootasleftchildofnewnode,copyrightchildofrootasright
childofnewnodeandmakerightchildofrootasNULL.
5)Returnnewnodeasnewrootoftree.
Example:

100[20]25
/\\/\
50200502050
/insert(25)/\insert(25)/\
40======>30100========>30100
/1.Splay(25)\\2.insert25\\
304020040200
/

[20]
// This code is adopted from
http://algs4.cs.princeton.edu/33balanced/SplayBST.java.html
#include<stdio.h>
#include<stdlib.h>

// An AVL tree node


struct node
{
int key;
struct node *left, *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 = node->right = NULL;


return (node);
}

// A utility function to right rotate subtree rooted with y


// See the diagram given above.
struct node *rightRotate(struct node *x)
{
struct node *y = x->left;
x->left = y->right;
y->right = x;
return y;
}

// A utility function to left rotate subtree rooted with x


// See the diagram given above.
struct node *leftRotate(struct node *x)
{
struct node *y = x->right;
x->right = y->left;
y->left = x;
return y;
}

// This function brings the key at root if key is present in tree.


// If key is not present, then it brings the last accessed item at
// root. This function modifies the tree and returns the new root
struct node *splay(struct node *root, int key)
{
// Base cases: root is NULL or key is present at root
if (root == NULL || root->key == key)
return root;

// Key lies in left subtree


if (root->key > key)
{

// Key is not in tree, we are done


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

// Zig-Zig (Left Left)


if (root->left->key > key)
{
// First recursively bring the key as root of left-left
root->left->left = splay(root->left->left, key);

// Do first rotation for root, second rotation is done after else


root = rightRotate(root);
}
else if (root->left->key < key) // Zig-Zag (Left Right)
{
// First recursively bring the key as root of left-right
root->left->right = splay(root->left->right, key);

// Do first rotation for root->left


if (root->left->right != NULL)
root->left = leftRotate(root->left);
}

// Do second rotation for root


return (root->left == NULL)? root: rightRotate(root);
}
else // Key lies in right subtree
{
// Key is not in tree, we are done
if (root->right == NULL) return root;

// Zig-Zag (Right Left)


if (root->right->key > key)
{
// Bring the key as root of right-left
root->right->left = splay(root->right->left, key);

// Do first rotation for root->right

if (root->right->left != NULL)
root->right = rightRotate(root->right);
}
else if (root->right->key < key)// Zag-Zag (Right Right)
{
// Bring the key as root of right-right and do first rotation
root->right->right = splay(root->right->right, key);
root = leftRotate(root);
}

// Do second rotation for root


return (root->right == NULL)? root: leftRotate(root);
}
}

// Function to insert a new key k in splay tree with given root


struct node *insert(struct node *root, int k)
{
// Simple Case: If tree is empty
if (root == NULL) return newNode(k);

// Bring the closest leaf node to root


root = splay(root, k);

// If key is already present, then return


if (root->key == k) return root;

// Otherwise allocate memory for new node


struct node *newnode = newNode(k);

// If root's key is greater, make root as right child


// of newnode and copy the left child of root to newnode
if (root->key > k)
{
newnode->right = root;
newnode->left = root->left;
root->left = NULL;

// If root's key is smaller, make root as left child


// of newnode and copy the right child of root to newnode
else
{
newnode->left = root;
newnode->right = root->right;
root->right = NULL;
}

return newnode; // newnode becomes new 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);
}
}

/* Drier program to test above function*/


int main()
{
struct node *root = newNode(100);
root->left = newNode(50);
root->right = newNode(200);
root->left->left = newNode(40);
root->left->left->left = newNode(30);
root->left->left->left->left = newNode(20);
root = insert(root, 25);
printf("Preorder traversal of the modified Splay tree is \n");

preOrder(root);
return 0;
}
Output:

PreordertraversalofthemodifiedSplaytreeis
2520503040100200
=======================================================================

SplayTree|Set1(Search)
TheworstcasetimecomplexityofBinarySearchTree(BST)operationslikesearch,delete,insertisO(n).
Theworstcaseoccurswhenthetreeisskewed.WecangettheworstcasetimecomplexityasO(Logn)with
AVLandRedBlackTrees.
CanwedobetterthanAVLorRedBlacktreesinpracticalsituations?
LikeAVLandRedBlackTrees,SplaytreeisalsoselfbalancingBST.Themainideaofsplaytreeistobring
therecentlyaccesseditemtorootofthetree,thismakestherecentlysearcheditemtobeaccessibleinO(1)
timeifaccessedagain.Theideaistouselocalityofreference(Inatypicalapplication,80%oftheaccess
areto20%oftheitems).Imagineasituationwherewehavemillionsorbillionsofkeysandonlyfewofthem
areaccessedfrequently,whichisverylikelyinmanypracticalapplications.
AllsplaytreeoperationsruninO(logn)timeonaverage,wherenisthenumberofentriesinthetree.Any
singleoperationcantakeTheta(n)timeintheworstcase.
SearchOperation
ThesearchoperationinSplaytreedoesthestandardBSTsearch,inadditiontosearch,italsosplays(move
anodetotheroot).Ifthesearchissuccessful,thenthenodethatisfoundissplayedandbecomesthenew
root.ElsethelastnodeaccessedpriortoreachingtheNULLissplayedandbecomesthenewroot.
Therearefollowingcasesforthenodebeingaccessed.
1)NodeisrootWesimplyreturntheroot,dontdoanythingelseastheaccessednodeisalreadyroot.
2)Zig:Nodeischildofroot(thenodehasnograndparent).Nodeiseitheraleftchildofroot(wedoaright
rotation)ornodeisarightchildofitsparent(wedoaleftrotation).
T1,T2andT3aresubtreesofthetreerootedwithy(onleftside)orx(onrightside)

yx
/\Zig(RightRotation)/\
xT3>T1y
/\</\
T1T2Zag(LeftRotation)T2T3

3)Nodehasbothparentandgrandparent.Therecanbefollowingsubcases.
........3.a)ZigZigandZagZagNodeisleftchildofparentandparentisalsoleftchildofgrandparent(Two
rightrotations)ORnodeisrightchildofitsparentandparentisalsorightchildofgrandparent(TwoLeft
Rotations).

ZigZig(LeftLeftCase):
GPX

/\/\/\
PT4rightRotate(G)XGrightRotate(P)T1P
/\============>/\/\============>/\
XT3T1T2T3T4T2G
/\/\
T1T2T3T4

ZagZag(RightRightCase):
GPX

/\/\/\
T1PleftRotate(G)GXleftRotate(P)PT4
/\============>/\/\============>/\
T2XT1T2T3T4GT3
/\/\
T3T4T1T2

........3.b)ZigZagandZagZigNodeisleftchildofparentandparentisrightchildofgrandparent(Left
Rotationfollowedbyrightrotation)ORnodeisrightchildofitsparentandparentisleftchildofgrandparent
(RightRotationfollowedbyleftrotation).

ZigZag(LeftRightCase):
GGX

/\/\/\
PT4leftRotate(P)XT4rightRotate(G)PG
/\============>/\============>/\/\
T1XPT3T1T2T3T4
/\/\

T2T3T1T2

ZagZig(RightLeftCase):
GGX

/\/\/\

T1PrightRotate(P)T1XleftRotate(P)GP
/\=============>/\============>/\/\
XT4T2PT1T2T3T4
/\/\

T2T3T3T4
Example:

100100[20]
/\/\\
502005020050
/search(20)/search(20)/\
40======>[20]========>30100
/1.ZigZig\2.ZigZig\\
30at4030at10040200
/\
[20]40
Theimportantthingtonoteis,thesearchorsplayoperationnotonlybringsthesearchedkeytoroot,but
alsobalancestheBST.Forexampleinabovecase,heightofBSTisreducedby1.
Implementation:
// The code is adopted from http://goo.gl/SDH9hH
#include<stdio.h>
#include<stdlib.h>

// An AVL tree node


struct node
{
int key;
struct node *left, *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 = node->right = NULL;

return (node);
}

// A utility function to right rotate subtree rooted with y


// See the diagram given above.
struct node *rightRotate(struct node *x)
{
struct node *y = x->left;
x->left = y->right;
y->right = x;
return y;
}

// A utility function to left rotate subtree rooted with x


// See the diagram given above.
struct node *leftRotate(struct node *x)
{
struct node *y = x->right;
x->right = y->left;
y->left = x;
return y;
}

// This function brings the key at root if key is present in tree.


// If key is not present, then it brings the last accessed item at
// root. This function modifies the tree and returns the new root
struct node *splay(struct node *root, int key)
{
// Base cases: root is NULL or key is present at root
if (root == NULL || root->key == key)
return root;

// Key lies in left subtree


if (root->key > key)
{
// Key is not in tree, we are done
if (root->left == NULL) return root;

// Zig-Zig (Left Left)


if (root->left->key > key)
{
// First recursively bring the key as root of left-left
root->left->left = splay(root->left->left, key);

// Do first rotation for root, second rotation is done after else


root = rightRotate(root);
}
else if (root->left->key < key) // Zig-Zag (Left Right)
{
// First recursively bring the key as root of left-right
root->left->right = splay(root->left->right, key);

// Do first rotation for root->left


if (root->left->right != NULL)
root->left = leftRotate(root->left);
}

// Do second rotation for root


return (root->left == NULL)? root: rightRotate(root);
}
else // Key lies in right subtree
{
// Key is not in tree, we are done
if (root->right == NULL) return root;

// Zag-Zig (Right Left)


if (root->right->key > key)
{
// Bring the key as root of right-left
root->right->left = splay(root->right->left, key);

// Do first rotation for root->right


if (root->right->left != NULL)
root->right = rightRotate(root->right);

}
else if (root->right->key < key)// Zag-Zag (Right Right)
{
// Bring the key as root of right-right and do first rotation
root->right->right = splay(root->right->right, key);
root = leftRotate(root);
}

// Do second rotation for root


return (root->right == NULL)? root: leftRotate(root);
}
}

// The search function for Splay tree. Note that this function
// returns the new root of Splay Tree. If key is present in tree
// then, it is moved to root.
struct node *search(struct node *root, int key)
{
return splay(root, key);
}

// 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);
}
}

/* Drier program to test above function*/


int main()
{
struct node *root = newNode(100);

root->left = newNode(50);
root->right = newNode(200);
root->left->left = newNode(40);
root->left->left->left = newNode(30);
root->left->left->left->left = newNode(20);

root = search(root, 20);


printf("Preorder traversal of the modified Splay tree is \n");
preOrder(root);
return 0;
}
Output:

PreordertraversalofthemodifiedSplaytreeis
20503040100200
Summary
1)Splaytreeshaveexcellentlocalityproperties.Frequentlyaccesseditemsareeasytofind.Infrequent
itemsareoutofway.
2)AllsplaytreeoperationstakeO(Logn)timeonaverage.Splaytreescanberigorouslyshowntorunin
O(logn)averagetimeperoperation,overanysequenceofoperations(assumingwestartfromanempty
tree)
3)SplaytreesaresimplercomparedtoAVLandRedBlackTreesasnoextrafieldisrequiredineverytree
node.
4)UnlikeAVLtree,asplaytreecanchangeevenwithreadonlyoperationslikesearch.
ApplicationsofSplayTrees
Splaytreeshavebecomethemostwidelyusedbasicdatastructureinventedinthelast30years,because
they'rethefastesttypeofbalancedsearchtreeformanyapplications.
SplaytreesareusedinWindowsNT(inthevirtualmemory,networking,andfilesystemcode),thegcc
compilerandGNUC++library,thesedstringeditor,ForeSystemsnetworkrouters,themostpopular
implementationofUnixmalloc,Linuxloadablekernelmodules,andinmuchothersoftware(Source:
http://www.cs.berkeley.edu/~jrs/61b/lec/36)

=======================================================================

Findnextrightnodeofagivenkey
GivenaBinarytreeandakeyinthebinarytree,findthenoderighttothegivenkey.Ifthereisnonodeon
rightside,thenreturnNULL.ExpectedtimecomplexityisO(n)wherenisthenumberofnodesinthegiven
binarytree.
Forexample,considerthefollowingBinaryTree.Outputfor2is6,outputfor4is5.Outputfor10,6and5is
NULL.

10
/\
26
/\\
845
Westronglyrecommendyoutominimizethebrowserandtrythisyourselffirst.
Solution:TheideaistodolevelordertraversalofgivenBinaryTree.Whenwefindthegivenkey,wejust
checkifthenextnodeinlevelordertraversalisofsamelevel,ifyes,wereturnthenextnode,otherwise
returnNULL.
/* Program to find next right of a given key */
#include <iostream>
#include <queue>
using namespace std;

// A Binary Tree Node


struct node
{
struct node *left, *right;
int key;
};

// Method to find next right of given key k, it returns NULL if k is


// not present in tree or k is the rightmost node of its level
node* nextRight(node *root, int k)
{
// Base Case
if (root == NULL)
return 0;

// Create an empty queue for level order tarversal


queue<node *> qn; // A queue to store node addresses
queue<int> ql;

// Another queue to store node levels

int level = 0; // Initialize level as 0

// Enqueue Root and its level


qn.push(root);
ql.push(level);

// A standard BFS loop


while (qn.size())
{
// dequeue an node from qn and its level from ql
node *node = qn.front();
level = ql.front();
qn.pop();
ql.pop();

// If the dequeued node has the given key k


if (node->key == k)
{
// If there are no more items in queue or given node is
// the rightmost node of its level, then return NULL
if (ql.size() == 0 || ql.front() != level)
return NULL;

// Otherwise return next node from queue of nodes


return qn.front();
}

// Standard BFS steps: enqueue children of this node


if (node->left != NULL)
{
qn.push(node->left);
ql.push(level+1);
}

if (node->right != NULL)
{
qn.push(node->right);
ql.push(level+1);
}
}

// We reach here if given key x doesn't exist in tree


return NULL;
}

// Utility function to create a new tree node


node* newNode(int key)
{
node *temp = new node;
temp->key = key;
temp->left = temp->right = NULL;
return temp;
}

// A utility function to test above functions


void test(node *root, int k)
{
node *nr = nextRight(root, k);
if (nr != NULL)
cout << "Next Right of " << k << " is " << nr->key << endl;
else
cout << "No next right node found for " << k << endl;
}

// Driver program to test above functions


int main()
{
// Let us create binary tree given in the above example
node *root = newNode(10);
root->left = newNode(2);
root->right = newNode(6);

root->right->right = newNode(5);
root->left->left = newNode(8);
root->left->right = newNode(4);

test(root, 10);
test(root, 2);
test(root, 6);
test(root, 5);
test(root, 8);
test(root, 4);
return 0;
}
Output:

Nonextrightnodefoundfor10
NextRightof2is6
Nonextrightnodefoundfor6
Nonextrightnodefoundfor5
NextRightof8is4
NextRightof4is5
TimeComplexity:TheabovecodeisasimpleBFStraversalcodewhichvisitseveryenqueueand
dequeuesanodeatmostonce.Therefore,thetimecomplexityisO(n)wherenisthenumberofnodesin
thegivenbinarytree.

=======================================================================

Deepestleftleafnodeinabinarytree
GivenaBinaryTree,findthedeepestleafnodethatisleftchildofitsparent.Forexample,considerthe
followingtree.Thedeepestleftleafnodeisthenodewithvalue9.

1
/\
23
//\
456
\\
78

/\
910
Westronglyrecommendyoutominimizethebrowserandtrythisyourselffirst.
Theideaistorecursivelytraversethegivenbinarytreeandwhiletraversing,maintainlevelwhichwillstore
thecurrentnodeslevelinthetree.Ifcurrentnodeisleftleaf,thencheckifitslevelismorethanthelevelof
deepestleftleafseensofar.Iflevelismorethenupdatetheresult.Ifcurrentnodeisnotleaf,then
recursivelyfindmaximumdepthinleftandrightsubtrees,andreturnmaximumofthetwodepths.Thanksto
Coder011forsuggestingthisapproach.
// 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;
};

Node *newNode(int data)


{
Node *temp = new Node;
temp->val = data;
temp->left = temp->right = NULL;
return temp;
}

// A utility function to find deepest leaf node.


// lvl: level of current node.
// maxlvl: pointer to the deepest left leaf node found so far
// isLeft: A bool indicate that this node is left child of its parent
// resPtr: Pointer to the result
void deepestLeftLeafUtil(Node *root, int lvl, int *maxlvl,
bool isLeft, Node **resPtr)
{
// Base case
if (root == NULL)

return;

// 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;
}

// Recur for left and right subtrees


deepestLeftLeafUtil(root->left, lvl+1, maxlvl, true, resPtr);
deepestLeftLeafUtil(root->right, lvl+1, maxlvl, false, resPtr);
}

// A wrapper over deepestLeftLeafUtil().


Node* deepestLeftLeaf(Node *root)
{
int maxlevel = 0;
Node *result = NULL;
deepestLeftLeafUtil(root, 0, &maxlevel, false, &result);
return result;
}

// Driver program to test above function


int main()
{
Node* root = newNode(1);
root->left = newNode(2);
root->right = newNode(3);
root->left->left = newNode(4);
root->right->left = newNode(5);
root->right->right = newNode(6);
root->right->left->right = newNode(7);
root->right->right->right = newNode(8);
root->right->left->right->left = newNode(9);

root->right->right->right->right = newNode(10);

Node *result = deepestLeftLeaf(root);


if (result)
cout << "The deepest left child is " << result->val;
else
cout << "There is no left leaf in the given tree";

return 0;
}
Output:

Thedeepestleftchildis9
TimeComplexity:Thefunctiondoesasimpletraversalofthetree,sothecomplexityisO(n).

=======================================================================

ExtractLeavesofaBinaryTreeina
DoublyLinkedList
GivenaBinaryTree,extractallleavesofitinaDoublyLinkedList(DLL).NotethattheDLLneedtobe
createdinplace.AssumethatthenodestructureofDLLandBinaryTreeissame,onlythemeaningofleft
andrightpointersaredifferent.InDLL,leftmeanspreviouspointerandrightmeansnextpointer.

Letthefollowingbeinputbinarytree
1
/\
23
/\\
456
/\/\
78910

Output:
DoublyLinkedList
7<>8<>5<>9<>10

ModifiedTree:
1
/\
23
/\
46
Westronglyrecommendyoutominimizethebrowserandtrythisyourselffirst.
Weneedtotraverseallleavesandconnectthembychangingtheirleftandrightpointers.Wealsoneedto
removethemfromBinaryTreebychangingleftorrightpointersinparentnodes.Therecanbemanyways
tosolvethis.Inthefollowingimplementation,weaddleavesatthebeginningofcurrentlinkedlistand
updateheadofthelistusingpointertoheadpointer.Sinceweinsertatthebeginning,weneedtoprocess
leavesinreverseorder.Forreverseorder,wefirsttraversetherightsubtreethentheleftsubtree.Weuse
returnvaluestoupdateleftorrightpointersinparentnodes.
// C program to extract leaves of a Binary Tree in a Doubly Linked List
#include <stdio.h>
#include <stdlib.h>

// Structure for tree and linked list


struct Node
{
int data;
struct Node *left, *right;
};

// 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;

if (root->left == NULL && root->right == NULL)


{
// This node is going to be added to doubly linked list

// of leaves, set right pointer of this node as previous


// head of DLL. We don't need to set left pointer as left
// is already NULL
root->right = *head_ref;

// Change left pointer of previous head


if (*head_ref != NULL) (*head_ref)->left = root;

// Change head of linked list


*head_ref = root;

return NULL; // Return new root


}

// Recur for right and left subtrees


root->right = extractLeafList(root->right, head_ref);
root->left = extractLeafList(root->left, head_ref);

return root;
}

// Utility function for allocating node for Binary Tree.


struct Node* newNode(int data)
{
struct Node* node = (struct Node*)malloc(sizeof(struct Node));
node->data = data;
node->left = node->right = NULL;
return node;
}

// Utility function for printing tree in In-Order.


void print(struct Node *root)
{
if (root != NULL)
{
print(root->left);
printf("%d ",root->data);

print(root->right);
}
}

// Utility function for printing double linked list.


void printList(struct Node *head)
{
while (head)
{
printf("%d ", head->data);
head = head->right;
}
}

// Driver program to test above function


int main()
{
struct Node *head = NULL;
struct Node *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);
root->left->left->left = newNode(7);
root->left->left->right = newNode(8);
root->right->right->left = newNode(9);
root->right->right->right = newNode(10);

printf("Inorder Trvaersal of given Tree is:\n");


print(root);

root = extractLeafList(root, &head);

printf("\nExtracted Double Linked list is:\n");


printList(head);

printf("\nInorder traversal of modified tree is:\n");


print(root);
return 0;
}
Output:

InorderTrvaersalofgivenTreeis:
74825139610
ExtractedDoubleLinkedlistis:
785910
Inordertraversalofmodifiedtreeis:
42136
TimeComplexity:O(n),thesolutiondoesasingletraversalofgivenBinaryTree.

=======================================================================

Removeallnodeswhichdontliein
anypathwithsum>=k
Givenabinarytree,acompletepathisdefinedasapathfromroottoaleaf.Thesumofallnodesonthat
pathisdefinedasthesumofthatpath.GivenanumberK,youhavetoremove(prunethetree)allnodes
whichdontlieinanypathwithsum>=k.
Note:Anodecanbepartofmultiplepaths.Sowehavetodeleteitonlyincasewhenallpathsfromithave
sumlessthanK.

ConsiderthefollowingBinaryTree
1
/\
23
/\/\
4567
/\//
891210
/\\
131411
/
15

Forinputk=20,thetreeshouldbechangedtofollowing
(Nodeswithvalues6and8aredeleted)
1
/\
23
/\\
457
\//
91210
/\\
131411
/
15

Forinputk=45,thetreeshouldbechangedtofollowing.
1
/
2
/
4
\
9
\
14
/
15

Westronglyrecommendyoutominimizethebrowserandtrythisyourselffirst.
Theideaistotraversethetreeanddeletenodesinbottomupmanner.Whiletraversingthetree,recursively
calculatethesumofnodesfromroottoleafnodeofeachpath.Foreachvisitednode,checksthetotal
calculatedsumagainstgivensumk.Ifsumislessthank,thenfree(delete)thatnode(leafnode)and
returnthesumbacktothepreviousnode.Sincethepathisfromroottoleafandnodesaredeletedin
bottomupmanner,anodeisdeletedonlywhenallofitsdescendantsaredeleted.Therefore,whenanode
isdeleted,itmustbealeafinthecurrentBinaryTree.
FollowingisCimplementationoftheaboveapproach.

#include <stdio.h>
#include <stdlib.h>

// A utility function to get maximum of two integers


int max(int l, int r) { return (l > r ? l : r); }

// A Binary Tree Node


struct Node
{
int data;
struct Node *left, *right;
};

// 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;
}

// print the tree in LVR (Inorder traversal) way.


void print(struct Node *root)
{
if (root != NULL)
{
print(root->left);
printf("%d ",root->data);
print(root->right);
}
}

/* Main function which truncates the binary tree. */


struct Node *pruneUtil(struct Node *root, int k, int *sum)
{
// Base Case

if (root == NULL) return NULL;

// Initialize left and right sums as sum from root to


// this node (including this node)
int lsum = *sum + (root->data);
int rsum = lsum;

// Recursively prune left and right subtrees


root->left = pruneUtil(root->left, k, &lsum);
root->right = pruneUtil(root->right, k, &rsum);

// Get the maximum of left and right sums


*sum = max(lsum, rsum);

// If maximum is smaller than k, then this node


// must be deleted
if (*sum < k)
{
free(root);
root = NULL;
}

return root;
}

// A wrapper over pruneUtil()


struct Node *prune(struct Node *root, int k)
{
int sum = 0;
return pruneUtil(root, k, &sum);
}

// Driver program to test above function


int main()
{
int k = 45;
struct Node *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(12);
root->right->right->left = newNode(10);
root->right->right->left->right = newNode(11);
root->left->left->right->left = newNode(13);
root->left->left->right->right = newNode(14);
root->left->left->right->right->left = newNode(15);

printf("Tree before truncation\n");


print(root);

root = prune(root, k); // k is 45

printf("\n\nTree after truncation\n");


print(root);

return 0;
}
Output:

Treebeforetruncation
841391514212516310117

Treeaftertruncation
49151421
TimeComplexity:O(n),thesolutiondoesasingletraversalofgivenBinaryTree.

=======================================================================

Addallgreatervaluestoeverynode
inagivenBST
GivenaBinarySearchTree(BST),modifyitsothatallgreatervaluesinthegivenBSTareaddedtoevery
node.Forexample,considerthefollowingBST.

50
/\
3070
/\/\
20406080

Theabovetreeshouldbemodifiedtofollowing

260
/\
330150
/\/\
35030021080
Westronglyrecommendyoutominimizethebrowserandtrythisyourselffirst.
Asimplemethodforsolvingthisistofindsumofallgreatervaluesforeverynode.Thismethodwouldtake
O(n^2)time.
Wecandoitusingasingletraversal.TheideaistousefollowingBSTproperty.IfwedoreverseInorder
traversalofBST,wegetallnodesindecreasingorder.WedoreverseInordertraversalandkeeptrackof
thesumofallnodesvisitedsofar,weaddthissumtoeverynode.
// C program to add all greater values in every node of BST
#include<stdio.h>
#include<stdlib.h>

struct node
{
int data;
struct node *left, *right;
};

// A utility function to create a new BST node

struct node *newNode(int item)


{
struct node *temp = (struct node *)malloc(sizeof(struct node));
temp->data = item;
temp->left = temp->right = NULL;
return temp;
}

// Recursive function to add all greater values in every node


void modifyBSTUtil(struct node *root, int *sum)
{
// Base Case
if (root == NULL) return;

// Recur for right subtree


modifyBSTUtil(root->right, sum);

// Now *sum has sum of nodes in right subtree, add


// root->data to sum and update root->data
*sum = *sum + root->data;
root->data = *sum;

// Recur for left subtree


modifyBSTUtil(root->left, sum);
}

// A wrapper over modifyBSTUtil()


void modifyBST(struct node *root)
{
int sum = 0;
modifyBSTUtil(root, &sum);
}

// A utility function to do inorder traversal of BST


void inorder(struct node *root)
{
if (root != NULL)

{
inorder(root->left);
printf("%d ", root->data);
inorder(root->right);
}
}

/* A utility function to insert a new node with given data in BST */


struct node* insert(struct node* node, int data)
{
/* If the tree is empty, return a new node */
if (node == NULL) return newNode(data);

/* Otherwise, recur down the tree */


if (data <= node->data)
node->left = insert(node->left, data);
else
node->right = insert(node->right, data);

/* return the (unchanged) node pointer */


return node;
}

// Driver Program to test above functions


int main()
{
/* Let us create following BST
50
/\
30

70

/ \/ \
20

40 60

80 */

struct node *root = NULL;


root = insert(root, 50);
insert(root, 30);
insert(root, 20);
insert(root, 40);

insert(root, 70);
insert(root, 60);
insert(root, 80);

modifyBST(root);

// print inoder tarversal of the modified BST


inorder(root);

return 0;
}
Output

35033030026021015080
TimeComplexity:O(n)wherenisnumberofnodesinthegivenBST.
Asasidenote,wecanalsousereverseInordertraversaltofindkthlargestelementinaBST.

=======================================================================

BTree|Set3(Delete)
Itisrecommendedtoreferfollowingpostsasprerequisiteofthispost.
BTree|Set1(Introduction)
BTree|Set2(Insert)
BTreeisatypeofamultiwaysearchtree.So,ifyouarenotfamiliarwithmultiwaysearchtreesingeneral,
itisbettertotakealookatthisvideolecturefromIITDelhi,beforeproceedingfurther.Onceyougetthe
basicsofamultiwaysearchtreeclear,BTreeoperationswillbeeasiertounderstand.
SourceofthefollowingexplanationandalgorithmisIntroductiontoAlgorithms3rdEditionbyCliffordStein,
ThomasH.Cormen,CharlesE.Leiserson,RonaldL.Rivest
Deletionprocess:
DeletionfromaBtreeismorecomplicatedthaninsertion,becausewecandeleteakeyfromanynodenot
justaleafandwhenwedeleteakeyfromaninternalnode,wewillhavetorearrangethenodeschildren.
Asininsertion,wemustmakesurethedeletiondoesntviolatetheBtreeproperties.Justaswehadto
ensurethatanodedidntgettoobigduetoinsertion,wemustensurethatanodedoesntgettoosmall
duringdeletion(exceptthattherootisallowedtohavefewerthantheminimumnumbert1ofkeys).Justas
asimpleinsertionalgorithmmighthavetobackupifanodeonthepathtowherethekeywastobeinserted
wasfull,asimpleapproachtodeletionmighthavetobackupifanode(otherthantheroot)alongthepathto
wherethekeyistobedeletedhastheminimumnumberofkeys.

Thedeletionproceduredeletesthekeykfromthesubtreerootedatx.Thisprocedureguaranteesthat
wheneveritcallsitselfrecursivelyonanodex,thenumberofkeysinxisatleasttheminimumdegreet.
NotethatthisconditionrequiresonemorekeythantheminimumrequiredbytheusualBtreeconditions,so
thatsometimesakeymayhavetobemovedintoachildnodebeforerecursiondescendstothatchild.This
strengthenedconditionallowsustodeleteakeyfromthetreeinonedownwardpasswithouthavingtoback
up(withoneexception,whichwellexplain).Youshouldinterpretthefollowingspecificationfordeletion
fromaBtreewiththeunderstandingthatiftherootnodexeverbecomesaninternalnodehavingnokeys
(thissituationcanoccurincases2cand3bthenwedeletex,andxsonlychildx.c1becomesthenewroot
ofthetree,decreasingtheheightofthetreebyoneandpreservingthepropertythattherootofthetree
containsatleastonekey(unlessthetreeisempty).
WesketchhowdeletionworkswithvariouscasesofdeletingkeysfromaBtree.
1.

Ifthekeykisinnodexandxisaleaf,deletethekeykfromx.

2.

Ifthekeykisinnodexandxisaninternalnode,dothefollowing.

a)

Ifthechildythatprecedeskinnodexhasatleasttkeys,thenfindthepredecessork0ofkinthe

subtreerootedaty.Recursivelydeletek0,andreplacekbyk0inx.(Wecanfindk0anddeleteitinasingle
downwardpass.)
b)

Ifyhasfewerthantkeys,then,symmetrically,examinethechildzthatfollowskinnodex.Ifzhas

atleasttkeys,thenfindthesuccessork0ofkinthesubtreerootedatz.Recursivelydeletek0,andreplace
kbyk0inx.(Wecanfindk0anddeleteitinasingledownwardpass.)
c)Otherwise,ifbothyandzhaveonlyt1keys,mergekandallofzintoy,sothatxlosesbothkandthe
pointertoz,andynowcontains2t1keys.Thenfreezandrecursivelydeletekfromy.
3.

Ifthekeykisnotpresentininternalnodex,determinetherootx.c(i)oftheappropriatesubtreethat

mustcontaink,ifkisinthetreeatall.Ifx.c(i)hasonlyt1keys,executestep3aor3basnecessaryto
guaranteethatwedescendtoanodecontainingatleasttkeys.Thenfinishbyrecursingontheappropriate
childofx.
a)

Ifx.c(i)hasonlyt1keysbuthasanimmediatesiblingwithatleasttkeys,givex.c(i)anextrakeyby

movingakeyfromxdownintox.c(i),movingakeyfromx.c(i)simmediateleftorrightsiblingupintox,and
movingtheappropriatechildpointerfromthesiblingintox.c(i).
b)

Ifx.c(i)andbothofx.c(i)simmediatesiblingshavet1keys,mergex.c(i)withonesibling,which

involvesmovingakeyfromxdownintothenewmergednodetobecomethemediankeyforthatnode.
SincemostofthekeysinaBtreeareintheleaves,deletionoperationsaremostoftenusedtodeletekeys
fromleaves.Therecursivedeleteprocedurethenactsinonedownwardpassthroughthetree,without
havingtobackup.Whendeletingakeyinaninternalnode,however,theproceduremakesadownward
passthroughthetreebutmayhavetoreturntothenodefromwhichthekeywasdeletedtoreplacethekey
withitspredecessororsuccessor(cases2aand2b).
ThefollowingfiguresfromCLRSbookexplainthedeletionporcess.


Implementation:
FollowingisC++implementationofdeletionprocess.
/* The following program performs deletion on a B-Tree. It contains functions
specific for deletion along with all the other functions provided in the
previous articles on B-Trees. See
http://www.geeksforgeeks.org/b-tree-set-1-introduction-2/
for previous article.

The deletion function has been compartmentalized into 8 functions for ease
of understanding and clarity

The following functions are exclusive for deletion


In class BTreeNode:
1) remove
2) removeFromLeaf
3) removeFromNonLeaf

4) getPred
5) getSucc
6) borrowFromPrev
7) borrowFromNext
8) merge
9) findKey

In class BTree:
1) remove

The removal of a key from a B-Tree is a fairly complicated process. The program
handles
all the 6 different cases that might arise while removing a key.

Testing: The code has been tested using the B-Tree provided in the CLRS book(
included
in the main function ) along with other cases.

Reference: CLRS3 - Chapter 18 - (499-502)


It is advised to read the material in CLRS before taking a look at the code. */

#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 to traverse all nodes in a subtree rooted with this node


void traverse();

// A function to search a key in subtree rooted with this node.


BTreeNode *search(int k);

// returns NULL if k is not present.

// A function that returns the index of the first key that is greater
// or equal to k
int findKey(int k);

// A utility function to insert a new key in the subtree rooted with


// this node. The assumption is, the node must be non-full when this
// function is called
void insertNonFull(int k);

// A utility function to split the child y of this node. i is index


// of y in child array C[]. The Child y must be full when this
// function is called
void splitChild(int i, BTreeNode *y);

// A wrapper function to remove the key k in subtree rooted with


// this node.
void remove(int k);

// A function to remove the key present in idx-th position in


// this node which is a leaf
void removeFromLeaf(int idx);

// A function to remove the key present in idx-th position in


// this node which is a non-leaf node
void removeFromNonLeaf(int idx);

// A function to get the predecessor of the key- where the key


// is present in the idx-th position in the node
int getPred(int idx);

// A function to get the successor of the key- where the key

// is present in the idx-th position in the node


int getSucc(int idx);

// A function to fill up the child node present in the idx-th


// position in the C[] array if that child has less than t-1 keys
void fill(int idx);

// A function to borrow a key from the C[idx-1]-th node and place


// it in C[idx]th node
void borrowFromPrev(int idx);

// A function to borrow a key from the C[idx+1]-th node and place it


// in C[idx]th node
void borrowFromNext(int idx);

// A function to merge idx-th child of the node with (idx+1)th child of


// the node
void merge(int idx);

// Make BTree friend of this so that we can access private members of


// this class in BTree functions
friend class 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;
}

void traverse()
{
if (root != NULL) root->traverse();
}

// function to search a key in this tree


BTreeNode* search(int k)
{
return (root == NULL)? NULL : root->search(k);
}

// The main function that inserts a new key in this B-Tree


void insert(int k);

// The main function that removes a new key in thie B-Tree


void remove(int k);

};

BTreeNode::BTreeNode(int t1, bool leaf1)


{
// Copy the given minimum degree and leaf property
t = t1;
leaf = leaf1;

// Allocate memory for maximum number of possible keys


// and child pointers
keys = new int[2*t-1];
C = new BTreeNode *[2*t];

// Initialize the number of keys as 0


n = 0;
}

// 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);

// The key to be removed is present in this node


if (idx < n && keys[idx] == k)
{

// If the node is a leaf node - removeFromLeaf is called


// Otherwise, removeFromNonLeaf function is called
if (leaf)
removeFromLeaf(idx);
else
removeFromNonLeaf(idx);
}
else
{

// 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;
}

// The key to be removed is present in the sub-tree rooted with this node
// The flag indicates whether the key is present in the sub-tree rooted
// with the last child of this node
bool flag = ( (idx==n)? true : false );

// 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];

// Reduce the count of keys


n--;

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 the child that precedes k (C[idx]) has atleast t keys,


// find the predecessor 'pred' of k in the subtree rooted at
// C[idx]. Replace k by pred. Recursively delete pred
// in C[idx]
if (C[idx]->n >= t)
{
int pred = getPred(idx);
keys[idx] = pred;
C[idx]->remove(pred);
}

// If the child C[idx] has less that t keys, examine C[idx+1].


// If C[idx+1] has atleast t keys, find the successor 'succ' of k in
// the subtree rooted at C[idx+1]
// Replace k by succ
// Recursively delete succ in C[idx+1]
else if (C[idx+1]->n >= t)
{
int succ = getSucc(idx);
keys[idx] = succ;
C[idx+1]->remove(succ);
}

// 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;
}

// A function to get predecessor of keys[idx]


int BTreeNode::getPred(int idx)

{
// Keep moving to the right most node until we reach a leaf
BTreeNode *cur=C[idx];
while (!cur->leaf)
cur = cur->C[cur->n];

// Return the last key of the leaf


return cur->keys[cur->n-1];
}

int BTreeNode::getSucc(int idx)


{

// 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];

// Return the first key of the leaf


return cur->keys[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);

// Merge C[idx] with its sibling

// If C[idx] is the last child, merge it with with its previous sibling
// Otherwise merge it with its next sibling
else
{
if (idx != n)
merge(idx);
else
merge(idx-1);
}
return;
}

// A function to borrow a key from C[idx-1] and insert it


// into C[idx]
void BTreeNode::borrowFromPrev(int 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

// Moving all key in C[idx] one step ahead


for (int i=child->n-1; i>=0; --i)
child->keys[i+1] = child->keys[i];

// 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];

// Moving sibling's last child as C[idx]'s first child


if (!leaf)
child->C[0] = sibling->C[sibling->n];

// Moving the key from the sibling to the parent


// This reduces the number of keys in the sibling
keys[idx-1] = sibling->keys[sibling->n-1];

child->n += 1;
sibling->n -= 1;

return;
}

// A function to borrow a key from the C[idx+1] and place


// it in C[idx]
void BTreeNode::borrowFromNext(int idx)
{

BTreeNode *child=C[idx];
BTreeNode *sibling=C[idx+1];

// keys[idx] is inserted as the last key in C[idx]


child->keys[(child->n)] = keys[idx];

// Sibling's first child is inserted as the last child


// into C[idx]
if (!(child->leaf))
child->C[(child->n)+1] = sibling->C[0];

//The first key from sibling is inserted into keys[idx]


keys[idx] = sibling->keys[0];

// Moving all keys in sibling one step behind


for (int i=1; i<sibling->n; ++i)
sibling->keys[i-1] = sibling->keys[i];

// Moving the child pointers one step behind


if (!sibling->leaf)
{
for(int i=1; i<=sibling->n; ++i)
sibling->C[i-1] = sibling->C[i];
}

// Increasing and decreasing the key count of C[idx] and C[idx+1]


// respectively
child->n += 1;
sibling->n -= 1;

return;
}

// A function to merge C[idx] with C[idx+1]


// C[idx+1] is freed after merging
void BTreeNode::merge(int idx)
{
BTreeNode *child = C[idx];
BTreeNode *sibling = C[idx+1];

// Pulling a key from the current node and inserting it into (t-1)th
// position of C[idx]
child->keys[t-1] = keys[idx];

// Copying the keys from C[idx+1] to C[idx] at the end


for (int i=0; i<sibling->n; ++i)
child->keys[i+t] = sibling->keys[i];

// Copying the child pointers from C[idx+1] to C[idx]


if (!child->leaf)
{
for(int i=0; i<=sibling->n; ++i)
child->C[i+t] = sibling->C[i];
}

// 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];

// Updating the key count of child and the current node


child->n += sibling->n+1;
n--;

// Freeing the memory occupied by sibling


delete(sibling);
return;
}

// The main function that inserts a new key in this B-Tree


void BTree::insert(int k)
{
// If tree is empty
if (root == NULL)
{
// Allocate memory for root
root = new BTreeNode(t, true);
root->keys[0] = k; // Insert key
root->n = 1; // Update number of keys in root
}
else // If tree is not empty
{
// If root is full, then tree grows in height
if (root->n == 2*t-1)
{
// Allocate memory for new root

BTreeNode *s = new BTreeNode(t, false);

// Make old root as child of new root


s->C[0] = root;

// Split the old root and move 1 key to the new root
s->splitChild(0, root);

// New root has two children now. Decide which of the


// two children is going to have new key
int i = 0;
if (s->keys[0] < k)
i++;
s->C[i]->insertNonFull(k);

// Change root
root = s;
}
else // If root is not full, call insertNonFull for root
root->insertNonFull(k);
}
}

// A utility function to insert a new key in this node


// The assumption is, the node must be non-full when this
// function is called
void BTreeNode::insertNonFull(int k)
{
// Initialize index as index of rightmost element
int i = n-1;

// If this is a leaf node


if (leaf == true)
{
// The following loop does two things
// a) Finds the location of new key to be inserted
// b) Moves all greater keys to one place ahead

while (i >= 0 && keys[i] > k)


{
keys[i+1] = keys[i];
i--;
}

// Insert the new key at found location


keys[i+1] = k;
n = n+1;
}
else // If this node is not leaf
{
// Find the child which is going to have the new key
while (i >= 0 && keys[i] > k)
i--;

// See if the found child is full


if (C[i+1]->n == 2*t-1)
{
// If the child is full, then split it
splitChild(i+1, C[i+1]);

// After split, the middle key of C[i] goes up and


// C[i] is splitted into two. See which of the two
// is going to have the new key
if (keys[i+1] < k)
i++;
}
C[i+1]->insertNonFull(k);
}
}

// A utility function to split the child y of this node


// Note that y must be full when this function is called
void BTreeNode::splitChild(int i, BTreeNode *y)
{
// Create a new node which is going to store (t-1) keys

// of y
BTreeNode *z = new BTreeNode(y->t, y->leaf);
z->n = t - 1;

// Copy the last (t-1) keys of y to z


for (int j = 0; j < t-1; j++)
z->keys[j] = y->keys[j+t];

// Copy the last t children of y to z


if (y->leaf == false)
{
for (int j = 0; j < t; j++)
z->C[j] = y->C[j+t];
}

// Reduce the number of keys in y


y->n = t - 1;

// Since this node is going to have a new child,


// create space of new child
for (int j = n; j >= i+1; j--)
C[j+1] = C[j];

// Link the new child to this node


C[i+1] = z;

// A key of y will move to this node. Find location of


// new key and move all greater keys one space ahead
for (int j = n-1; j >= i; j--)
keys[j+1] = keys[j];

// Copy the middle key of y to this node


keys[i] = y->keys[t-1];

// Increment count of keys in this node


n = n + 1;
}

// Function to traverse all nodes in a subtree rooted with this node


void BTreeNode::traverse()
{
// There are n keys and n+1 children, travers through n keys
// and first n children
int i;
for (i = 0; i < n; i++)
{
// If this is not leaf, then before printing key[i],
// traverse the subtree rooted with child C[i].
if (leaf == false)
C[i]->traverse();
cout << " " << keys[i];
}

// Print the subtree rooted with last child


if (leaf == false)
C[i]->traverse();
}

// Function to search key k in subtree rooted with this node


BTreeNode *BTreeNode::search(int k)
{
// Find the first key greater than or equal to k
int i = 0;
while (i < n && k > keys[i])
i++;

// If the found key is equal to k, return this node


if (keys[i] == k)
return this;

// If key is not found here and this is a leaf node


if (leaf == true)
return NULL;

// Go to the appropriate child


return C[i]->search(k);
}

void BTree::remove(int k)
{
if (!root)
{
cout << "The tree is empty\n";
return;
}

// Call the remove function for root


root->remove(k);

// 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];

// Free the old root


delete tmp;
}
return;
}

// Driver program to test above functions


int main()
{
BTree t(3); // A B-Tree with minium degree 3

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);

cout << "Traversal of tree constructed is\n";


t.traverse();
cout << endl;

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:

Traversaloftreeconstructedis
123456710111213141516171819202122242526
Traversaloftreeafterremoving6
12345710111213141516171819202122242526
Traversaloftreeafterremoving13
123457101112141516171819202122242526
Traversaloftreeafterremoving7
12345101112141516171819202122242526
Traversaloftreeafterremoving4
1235101112141516171819202122242526
Traversaloftreeafterremoving2
135101112141516171819202122242526
Traversaloftreeafterremoving16
1351011121415171819202122242526

=======================================================================

PrintLeftViewofaBinaryTree
GivenaBinaryTree,printleftviewofit.LeftviewofaBinaryTreeissetofnodesvisiblewhentreeisvisited
fromleftside.Leftviewoffollowingtreeis12,10,25.

12
/\
1030
/\
2540
Theleftviewcontainsallnodesthatarefirstnodesintheirlevels.Asimplesolutionistodolevelorder
traversalandprintthefirstnodeineverylevel.
Theproblemcanalsobesolvedusingsimplerecursivetraversal.Wecankeeptrackoflevelofanodeby
passingaparametertoallrecursivecalls.Theideaistokeeptrackofmaximumlevelalso.Wheneverwe
seeanodewhoselevelismorethanmaximumlevelsofar,weprintthenodebecausethisisthefirstnode
initslevel(Notethatwetraversetheleftsubtreebeforerightsubtree).FollowingisCimplementationofthis
approach.
// C program to print left view of Binary Tree
#include<stdio.h>
#include<stdlib.h>

struct node
{
int data;
struct node *left, *right;
};

// A utility function to create a new Binary Tree node


struct node *newNode(int item)
{
struct node *temp = (struct node *)malloc(sizeof(struct node));
temp->data = item;
temp->left = temp->right = NULL;
return temp;
}

// Recursive function to print left view of a binary tree.


void leftViewUtil(struct node *root, int level, int *max_level)
{
// Base Case
if (root==NULL) return;

// If this is the first node of its level


if (*max_level < level)
{
printf("%d\t", root->data);
*max_level = level;
}

// Recur for left and right subtrees


leftViewUtil(root->left, level+1, max_level);
leftViewUtil(root->right, level+1, max_level);
}

// A wrapper over leftViewUtil()


void leftView(struct node *root)
{
int max_level = 0;
leftViewUtil(root, 1, &max_level);
}

// Driver Program to test above functions


int main()
{
struct node *root = newNode(12);
root->left = newNode(10);
root->right = newNode(30);
root->right->left = newNode(25);
root->right->right = newNode(40);

leftView(root);

return 0;
}
Output:

121025
TimeComplexity:Thefunctiondoesasimpletraversalofthetree,sothecomplexityisO(n).

=======================================================================

Checkifallleavesareatsamelevel
GivenaBinaryTree,checkifallleavesareatsamelevelornot.

12
/\
57

/\
31
Leavesareatsamelevel

12
/\
57

LeavesareNotatsamelevel

12
/
5

/\

39
//
12
Leavesareatsamelevel

Westronglyrecommendyoutominimizethebrowserandtrythisyourselffirst.

TheideaistofirstfindleveloftheleftmostleafandstoreitinavariableleafLevel.Thencomparelevelofall
otherleaveswithleafLevel,ifsame,returntrue,elsereturnfalse.WetraversethegivenBinaryTreein
Preorderfashion.Anargumentleaflevelispassedtoallcalls.ThevalueofleafLevelisinitializedas0to
indicatethatthefirstleafisnotyetseenyet.Thevalueisupdatedwhenwefindfirstleaf.Levelof
subsequentleaves(inpreorder)iscomparedwithleafLevel.
// C program to check if all leaves are at same level
#include <stdio.h>
#include <stdlib.h>

// A binary tree node


struct Node
{
int data;
struct Node *left, *right;
};

// A utility function to allocate a new tree node


struct Node* newNode(int data)
{
struct Node* node = (struct Node*) malloc(sizeof(struct Node));
node->data = data;
node->left = node->right = NULL;
return node;
}

/* 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 a leaf node is encountered


if (root->left == NULL && root->right == NULL)
{
// When a leaf node is found first time
if (*leafLevel == 0)
{

*leafLevel = level; // Set first found leaf's level


return true;
}

// If this is not first leaf node, compare its level with


// first leaf's level
return (level == *leafLevel);
}

// 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);
}

// Driver program to test above function


int main()
{
// Let us create tree shown in thirdt example
struct Node *root = newNode(12);
root->left = newNode(5);
root->left->left = newNode(3);
root->left->right = newNode(9);
root->left->left->left = newNode(1);
root->left->right->left = newNode(1);
if (check(root))
printf("Leaves are at same level\n");
else
printf("Leaves are not at same level\n");
getchar();

return 0;
}
Output:

Leavesareatsamelevel
TimeComplexity:Thefunctiondoesasimpletraversalofthetree,sothecomplexityisO(n).

=======================================================================

Finddepthofthedeepestoddlevel
leafnode
WriteaCcodetogetthedepthofthedeepestoddlevelleafnodeinabinarytree.Considerthatlevelstarts
with1.Depthofaleafnodeisnumberofnodesonthepathfromroottoleaf(includingbothleafandroot).
Forexample,considerthefollowingtree.Thedeepestoddlevelnodeisthenodewithvalue9anddepthof
thisnodeis5.

1
/\
23
//\
456
\\
78
/\
910
/
11
Westronglyrecommendyoutominimizethebrowserandtrythisyourselffirst.
Theideaistorecursivelytraversethegivenbinarytreeandwhiletraversing,maintainavariablelevel
whichwillstorethecurrentnodeslevelinthetree.Ifcurrentnodeisleafthenchecklevelisoddornot.If
levelisoddthenreturnit.Ifcurrentnodeisnotleaf,thenrecursivelyfindmaximumdepthinleftandright
subtrees,andreturnmaximumofthetwodepths.
// C program to find depth of the deepest odd level leaf node
#include <stdio.h>
#include <stdlib.h>

// A utility function to find maximum of two integers

int max(int x, int y) { return (x > y)? x : y; }

// A Binary Tree node


struct Node
{
int data;
struct Node *left, *right;
};

// A utility function to allocate a new tree node


struct Node* newNode(int data)
{
struct Node* node = (struct Node*) malloc(sizeof(struct Node));
node->data = data;
node->left = node->right = NULL;
return node;
}

// A recursive function to find depth of the deepest odd level leaf


int depthOfOddLeafUtil(Node *root,int level)
{
// Base Case
if (root == NULL)
return 0;

// 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);
}

// Driver program to test above functions


int main()
{
struct Node* root = newNode(1);
root->left = newNode(2);
root->right = newNode(3);
root->left->left = newNode(4);
root->right->left = newNode(5);
root->right->right = newNode(6);
root->right->left->right = newNode(7);
root->right->right->right = newNode(8);
root->right->left->right->left = newNode(9);
root->right->right->right->right = newNode(10);
root->right->right->right->right->left = newNode(11);

printf("%d is the required depth\n", depthOfOddLeaf(root));


getchar();
return 0;
}
Output:

5istherequireddepth
TimeComplexity:Thefunctiondoesasimpletraversalofthetree,sothecomplexityisO(n).

=======================================================================

PrintPostordertraversalfromgiven
InorderandPreordertraversals
GivenInorderandPreordertraversalsofabinarytree,printPostordertraversal.
Example:

Input:
Inordertraversalin[]={4,2,5,1,3,6}
Preordertraversalpre[]={1,2,4,5,3,6}

Output:
Postordertraversalis{4,5,2,6,3,1}
Trversalsintheaboveexamplerepresentsfollowingtree

1
/\
23
/\\
456

Anaivemethodistofirstconstructthetree,thenusesimplerecursivemethodtoprintpostordertraversalof
theconstructedtree.
Wecanprintpostordertraversalwithoutconstructingthetree.Theideais,rootisalwaysthefirstitem
inpreordertraversalanditmustbethelastiteminpostordertraversal.Wefirstrecursivelyprintleftsubtree,
thenrecursivelyprintrightsubtree.Finally,printroot.Tofindboundariesofleftandrightsubtreesinpre[]
andin[],wesearchrootinin[],allelementsbeforerootinin[]areelementsofleftsubtreeandallelements
afterrootareelementsofrightsubtree.Inpre[],allelementsafterindexofrootinin[]areelementsofright
subtree.Andelementsbeforeindex(includingtheelementatindexandexcludingthefirstelement)are
elementsofleftsubtree.
// C++ program to print postorder traversal from preorder and inorder traversals
#include <iostream>
using namespace std;

// A utility function to search x in arr[] of size n


int search(int arr[], int x, int n)
{
for (int i = 0; i < n; i++)
if (arr[i] == x)
return i;
return -1;
}

// Prints postorder traversal from given inorder and preorder traversals


void printPostOrder(int in[], int pre[], int n)

{
// The first element in pre[] is always root, search it
// in in[] to find left and right subtrees
int root = search(in, pre[0], n);

// If left subtree is not empty, print left subtree


if (root != 0)
printPostOrder(in, pre+1, root);

// If right subtree is not empty, print right subtree


if (root != n-1)
printPostOrder(in+root+1, pre+root+1, n-root-1);

// 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

Postordertraversal
452631
TimeComplexity:Theabovefunctionvisitseverynodeinarray.Foreveryvisit,itcallssearchwhichtakes
O(n)time.Therefore,overalltimecomplexityofthefunctionisO(n2)

=======================================================================

Differencebetweensumsofoddlevel
andevenlevelnodesofaBinaryTree
GivenaaBinaryTree,findthedifferencebetweenthesumofnodesatoddlevelandthesumofnodesat
evenlevel.Considerrootaslevel1,leftandrightchildrenofrootaslevel2andsoon.
Forexample,inthefollowingtree,sumofnodesatoddlevelis(5+1+4+8)whichis18.Andsumof
nodesatevenlevelis(2+6+3+7+9)whichis27.Theoutputforfollowingtreeshouldbe1827which
is9.

5
/\
26
/\\
148
//\
379
Astraightforwardmethodistouselevelordertraversal.Inthetraversal,checklevelofcurrentnode,ifitis
odd,incrementoddsumbydataofcurrentnode,otherwiseincrementevensum.Finallyreturndifference
betweenoddsumandevensum.Seefollowingforimplementationofthisapproach.
Cimplementationoflevelordertraversalbasedapproachtofindthedifference.
Theproblemcanalsobesolvedusingsimplerecursivetraversal.Wecanrecursivelycalculatethe
requireddifferenceas,valueofrootsdatasubtractedbythedifferenceforsubtreeunderleftchildandthe
differenceforsubtreeunderrightchild.FollowingisCimplementationofthisapproach.
// A recursive program to find difference between sum of nodes at
// odd level and sum at even level
#include <stdio.h>
#include <stdlib.h>

// Binary Tree node


struct node
{
int data;
struct node* left, *right;
};

// A utility function to allocate a new 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);
}

// The main function that return difference between odd and even level
// nodes
int getLevelDiff(struct node *root)
{
// Base case
if (root == NULL)
return 0;

// Difference for root is root's data - difference for left subtree


// - difference for right subtree
return root->data - getLevelDiff(root->left) - getLevelDiff(root->right);
}

// Driver program to test above functions


int main()
{
struct node *root = newNode(5);
root->left = newNode(2);
root->right = newNode(6);
root->left->left = newNode(1);
root->left->right = newNode(4);
root->left->right->left = newNode(3);
root->right->right = newNode(8);
root->right->right->right = newNode(9);
root->right->right->left = newNode(7);
printf("%d is the required difference\n", getLevelDiff(root));
getchar();
return 0;
}

Output:

9istherequireddifference
TimecomplexityofbothmethodsisO(n),butthesecondmethodissimpleandeasytoimplement.

=======================================================================

Printancestorsofagivenbinarytree
nodewithoutrecursion
GivenaBinaryTreeandakey,writeafunctionthatprintsalltheancestorsofthekeyinthegivenbinary
tree.
Forexample,considerthefollowingBinaryTree

1
/\
23
/\/\
4567
/\/
8910
Followingaredifferentinputkeysandtheirancestorsintheabovetree

InputKeyListofAncestors

21
31
421
521
631
731
8421
9521
10731

Recursivesolutionforthisproblemisdiscussedhere.

ItisclearthatweneedtouseastackbasediterativetraversaloftheBinaryTree.Theideaistohaveall
ancestorsinstackwhenwereachthenodewithgivenkey.Oncewereachthekey,allwehavetodois,
printcontentsofstack.
Howtogetallancestorsinstackwhenwereachthegivennode?WecantraverseallnodesinPostorder
way.Ifwetakeacloserlookattherecursivepostordertraversal,wecaneasilyobservethat,whenrecursive
functioniscalledforanode,therecursioncallstackcontainsancestorsofthenode.Soideaisdoiterative
Postordertraversalandstopthetraversalwhenwereachthedesirednode.
FollowingisCimplementationoftheaboveapproach.
// C program to print all ancestors of a given key
#include <stdio.h>
#include <stdlib.h>

// Maximum stack size


#define MAX_SIZE 100

// Structure for a tree node


struct Node
{
int data;
struct Node *left, *right;
};

// Structure for Stack


struct Stack
{
int size;
int top;
struct Node* *array;
};

// A utility function to create a new tree node


struct Node* newNode(int data)
{
struct Node* node = (struct Node*) malloc(sizeof(struct Node));
node->data = data;
node->left = node->right = NULL;
return node;

// A utility function to create a stack of given size


struct Stack* createStack(int size)
{
struct Stack* stack = (struct Stack*) malloc(sizeof(struct Stack));
stack->size = size;
stack->top = -1;
stack->array = (struct Node**) malloc(stack->size * sizeof(struct Node*));
return stack;
}

// BASIC OPERATIONS OF STACK


int isFull(struct Stack* stack)
{
return ((stack->top + 1) == stack->size);
}
int isEmpty(struct Stack* stack)
{
return stack->top == -1;
}
void push(struct Stack* stack, struct Node* node)
{
if (isFull(stack))
return;
stack->array[++stack->top] = node;
}
struct Node* pop(struct Stack* stack)
{
if (isEmpty(stack))
return NULL;
return stack->array[stack->top--];
}
struct Node* peek(struct Stack* stack)
{
if (isEmpty(stack))
return NULL;

return stack->array[stack->top];
}

// Iterative Function to print all ancestors of a given key


void printAncestors(struct Node *root, int key)
{
if (root == NULL) return;

// Create a stack to hold ancestors


struct Stack* stack = createStack(MAX_SIZE);

// 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 node whose ancestors are to be printed is found,


// then break the while loop.
if (root && root->data == key)
break;

// Check if right sub-tree exists for the node at top


// If not then pop that node because we don't need this
// node any more.
if (peek(stack)->right == NULL)
{
root = pop(stack);

// 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.
//

//

//

//

\
3

//

//

//

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;
}

// If stack is not empty, print contents of stack


// Here assumption is that the key is there in tree
while (!isEmpty(stack))
printf("%d ", pop(stack)->data);
}

// Driver program to test above functions


int main()
{
// Let us construct a binary tree
struct Node* 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->right->right = newNode(9);

root->right->right->left = newNode(10);

printf("Following are all keys and their ancestors\n");


for (int key = 1; key <= 10; key++)
{
printf("%d: ", key);
printAncestors(root, key);
printf("\n");
}

getchar();
return 0;
}
Output:

Followingareallkeysandtheirancestors
1:
2:1
3:1
4:21
5:21
6:31
7:31
8:421
9:521
10:731
Exercise
NotethattheabovesolutionassumesthatthegivenkeyispresentinthegivenBinaryTree.Itmaygoin
infiniteloopifkeyisnotpresent.Extendtheabovesolutiontoworkevenwhenthekeyisnotpresentintree.

=======================================================================

ConvertagivenBinaryTreeto
DoublyLinkedList|Set2
GivenaBinaryTree(BT),convertittoaDoublyLinkedList(DLL).Theleftandrightpointersinnodesareto
beusedaspreviousandnextpointersrespectivelyinconvertedDLL.TheorderofnodesinDLLmustbe

sameasInorderofthegivenBinaryTree.ThefirstnodeofInordertraversal(leftmostnodeinBT)mustbe
headnodeoftheDLL.

Asolutiontothisproblemisdiscussedinthispost.
Inthispost,anothersimpleandefficientsolutionisdiscussed.Thesolutiondiscussedherehastwosimple
steps.
1)FixLeftPointers:Inthisstep,wechangeleftpointerstopointtopreviousnodesinDLL.Theideais
simple,wedoinordertraversaloftree.Ininordertraversal,wekeeptrackofpreviousvisitednodeand
changeleftpointertothepreviousnode.SeefixPrevPtr()inbelowimplementation.
2)FixRightPointers:Theaboveisintuitiveandsimple.Howtochangerightpointerstopointtonextnode
inDLL?Theideaistouseleftpointersfixedinstep1.WestartfromtherightmostnodeinBinaryTree(BT).
TherightmostnodeisthelastnodeinDLL.SinceleftpointersarechangedtopointtopreviousnodeinDLL,
wecanlinearlytraversethecompleteDLLusingthesepointers.Thetraversalwouldbefromlasttofirst
node.WhiletraversingtheDLL,wekeeptrackofthepreviouslyvisitednodeandchangetherightpointerto
thepreviousnode.SeefixNextPtr()inbelowimplementation.
// A simple inorder traversal based program to convert a Binary Tree to DLL
#include<stdio.h>
#include<stdlib.h>

// A tree node
struct node
{
int data;

struct node *left, *right;


};

// A utility function to create a new tree node


struct node *newNode(int data)
{
struct node *node = (struct node *)malloc(sizeof(struct node));
node->data = data;
node->left = node->right = NULL;
return(node);
}

// Standard Inorder traversal of tree


void inorder(struct node *root)
{
if (root != NULL)
{
inorder(root->left);
printf("\t%d",root->data);
inorder(root->right);
}
}

// Changes left pointers to work as previous pointers in converted DLL


// The function simply does inorder traversal of Binary Tree and updates
// left pointer using previously visited node
void fixPrevPtr(struct node *root)
{
static struct node *pre = NULL;

if (root != NULL)
{
fixPrevPtr(root->left);
root->left = pre;
pre = root;
fixPrevPtr(root->right);
}

// Changes right pointers to work as next pointers in converted DLL


struct node *fixNextPtr(struct node *root)
{
struct node *prev = NULL;

// Find the right most node in BT or last node in DLL


while (root && root->right != NULL)
root = 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 leftmost node is head of linked list, return it


return (root);
}

// 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);

// Set the next pointer and return head of DLL


return fixNextPtr(root);
}

// Traverses the DLL from left tor right


void printList(struct node *root)
{

while (root != NULL)


{
printf("\t%d", root->data);
root = root->right;
}
}

// Driver program to test above functions


int main(void)
{
// Let us create the tree shown in above diagram
struct node *root = newNode(10);
root->left

= newNode(12);

root->right

= newNode(15);

root->left->left = newNode(25);
root->left->right = newNode(30);
root->right->left = newNode(36);

printf("\n\t\tInorder Tree Traversal\n\n");


inorder(root);

struct node *head = BTToDLL(root);

printf("\n\n\t\tDLL Traversal\n\n");
printList(head);
return 0;
}
Output:

InorderTreeTraversal

251230103615

DLLTraversal

251230103615
TimeComplexity:O(n)wherenisthenumberofnodesingivenBinaryTree.Thesolutionsimplydoestwo
traversalsofallBinaryTreenodes.

=======================================================================

CheckforIdenticalBSTswithout
buildingthetrees
Giventwoarrayswhichrepresentasequenceofkeys.ImaginewemakeaBinarySearchTree(BST)from
eacharray.WeneedtotellwhethertwoBSTswillbeidenticalornotwithoutactuallyconstructingthetree.
Examples
Forexample,theinputarraysare{2,4,3,1}and{2,1,4,3}willconstructthesametree

Lettheinputarraysbea[]andb[]

Example1:
a[]={2,4,1,3}willconstructfollowingtree.
2
/\
14
/
3
b[]={2,4,3,1}willalsoalsoconstructthesametree.
2
/\
14
/
3
Sotheoutputis"True"

Example2:
a[]={8,3,6,1,4,7,10,14,13}
b[]={8,10,14,3,6,4,1,7,13}

TheybothconstructthesamefollowingBST,sooutputis"True"
8
/\
310
/\\

1614
/\/
4713

Solution:
AccordingtoBSTproperty,elementsofleftsubtreemustbesmallerandelementsofrightsubtreemustbe
greaterthanroot.
TwoarraysrepresentsaneBSTifforeveryelementx,theelementsinleftandrightsubtreesofxappear
afteritinbotharrays.Andsameistrueforrootsofleftandrightsubtrees.
Theideaistocheckofifnextsmallerandgreaterelementsaresameinbotharrays.Samepropertiesare
recursivelycheckedforleftandrightsubtrees.Theidealookssimple,butimplementationrequireschecking
allconditionsforallelements.Followingisaninterestingrecursiveimplementationoftheidea.
// A C program to check for Identical BSTs without building the trees
#include<stdio.h>
#include<limits.h>
#include<stdbool.h>

/* 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;

/* If the parent element is leaf in both arrays */


if (j==n && k==n)
return true;

/* Return false if any of the following is true


a) If the parent element is leaf in one array, but non-leaf in other.
b) The elements satisfying constraints are not same. We either search
for left child or right child of the parent element (decinded by min
and max values). The child found must be same in both arrays */
if (((j==n)^(k==n)) || a[j]!=b[k])
return false;

/* 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]);
}

// A wrapper over isSameBSTUtil()


bool isSameBST(int a[], int b[], int n)
{
return isSameBSTUtil(a, b, n, 0, 0, INT_MIN, INT_MAX);
}

// Driver program to test above functions


int main()
{
int a[] = {8, 3, 6, 1, 4, 7, 10, 14, 13};
int b[] = {8, 10, 14, 3, 6, 4, 1, 7, 13};
int n=sizeof(a)/sizeof(a[0]);
printf("%s\n", isSameBST(a, b, n)?
"BSTs are same":"BSTs not same");
return 0;
}
Output:

// Left Subtree

BSTsaresame
=======================================================================

CustomTreeProblem
Youaregivenasetoflinks,e.g.

a>b
b>c
b>d
a>e
Printthetreethatwouldformwheneachpairoftheselinksthathasthesamecharacterasstartandend
pointisjoinedtogether.Youhavetomaintainfidelityw.r.t.theheightofnodes,i.e.nodesatheightnfrom
rootshouldbeprintedatsameroworcolumn.Forsetoflinksgivenabove,treeprintedshouldbe

>a
|>b
||>c
||>d
|>e
Notethattheselinksneednotformasingletreetheycouldform,ahem,aforest.Considerthefollowing
links

a>b
a>g
b>c
c>d
d>e
c>f
z>y
y>x
x>w
Theoutputwouldbefollowingforest.

>a
|>b
||>c
|||>d
||||>e
|||>f

|>g

>z
|>y
||>x
|||>w

Youcanassumethatgivenlinkscanformatreeorforestoftreesonly,andtherearenoduplicatesamong
links.
Solution:Theideaistomaintaintwoarrays,onearrayfortreenodesandotherfortreesthemselves(we
callthisarrayforest).AnelementofthenodearraycontainstheTreeNodeobjectthatcorrespondsto
respectivecharacter.AnelementoftheforestarraycontainsTreeobjectthatcorrespondstorespectiveroot
oftree.
Itshouldbeobviousthatthecrucialpartiscreatingtheforesthere,onceitiscreated,printingitoutin
requiredformatisstraightforward.Tocreatetheforest,followingprocedureisused

Dofollowingforeachinputlink,
1.Ifstartoflinkisnotpresentinnodearray
CreateTreeNodeobjectsforstartcharacter
Addentriesofstartinbotharrays.
2.Ifendoflinkisnotpresentinnodearray
CreateTreeNodeobjectsforstartcharacter
Addentryofendinnodearray.
3.Ifendoflinkispresentinnodearray.
Ifendoflinkispresentinforestarray,thenremoveit
fromthere.
4.Addanedge(intree)betweenstartandendnodesoflink.

Itshouldbeclearthatthisprocedurerunsinlineartimeinnumberofnodesaswellasoflinksitmakes
onlyonepassoverthelinks.Italsorequireslinearspaceintermsofalphabetsize.
FollowingisJavaimplementationofabovealgorithm.Inthefollowingimplementationcharactersare
assumedtobeonlylowercasecharactersfromatoz.
// Java program to create a custom tree from a given set of links.

// The main class that represents tree and has main method
public class Tree {

private TreeNode root;

/* Returns an array of trees from links input. Links are assumed to


be Strings of the form "<s> <e>" where <s> and <e> are starting
and ending points for the link. The returned array is of size 26
and has non-null values at indexes corresponding to roots of trees
in output */
public Tree[] buildFromLinks(String [] links) {

// Create two arrays for nodes and forest


TreeNode[] nodes = new TreeNode[26];
Tree[] forest = new Tree[26];

// Process each link


for (String link : links) {

// Find the two ends of current link


String[] ends = link.split(" ");
int start = (int) (ends[0].charAt(0) - 'a'); // Start node
int end

= (int) (ends[1].charAt(0) - 'a'); // End node

// If start of link not seen before, add it two both arrays


if (nodes[start] == null)
{
nodes[start] = new TreeNode((char) (start + 'a'));

// Note that it may be removed later when this character is


// last character of a link. For example, let we first see
// a--->b, then c--->a. We first add 'a' to array of trees
// and when we see link c--->a, we remove it from trees array.
forest[start] = new Tree(nodes[start]);

// If end of link is not seen before, add it to the nodes array


if (nodes[end] == null)
nodes[end] = new TreeNode((char) (end + 'a'));

// If end of link is seen before, remove it from forest if


// it exists there.
else forest[end] = null;

// Establish Parent-Child Relationship between Start and End


nodes[start].addChild(nodes[end], end);
}
return forest;
}

// Constructor
public Tree(TreeNode root) { this.root = root; }

public static void printForest(String[] links)


{
Tree t = new Tree(new TreeNode('\0'));
for (Tree t1 : t.buildFromLinks(links)) {
if (t1 != null)
{
t1.root.printTreeIdented("");
System.out.println("");
}
}
}

// Driver method to test


public static void main(String[] args) {
String [] links1 = {"a b", "b c", "b d", "a e"};
System.out.println("------------ Forest 1 ----------------");
printForest(links1);

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);
}

// Class to represent a tree node


class TreeNode {
TreeNode []children;
char c;

// Adds a child 'n' to this node


public void addChild(TreeNode n, int index) { this.children[index] = n;}

// Constructor
public TreeNode(char c) { this.c = c; this.children = new TreeNode[26];}

// Recursive method to print indented tree rooted with this node.


public void printTreeIdented(String indent) {
System.out.println(indent + "-->" + c);
for (TreeNode child : children) {
if (child != null)
child.printTreeIdented(indent + "
}
}
}
Output:

Forest1
>a
|>b
||>c
||>d
|>e

Forest2
>a
|>b
||>c
|||>d
||||>e
|||>f

|");

|>g

>z
|>y
||>x
|||>w

=======================================================================

IterativeMethodtofindHeightof
BinaryTree
TherearetwoconventionstodefineheightofBinaryTree
1)Numberofnodesonlongestpathfromroottothedeepestnode.
2)Numberofedgesonlongestpathfromroottothedeepestnode.
Inthispost,thefirstconventionisfollowed.Forexample,heightofthebelowtreeis3.

ExampleTree

RecursivemethodtofindheightofBinaryTreeisdiscussedhere.Howtofindheightwithoutrecursion?We
canuselevelordertraversaltofindheightwithoutrecursion.Theideaistotraverselevelbylevel.Whenever
movedowntoalevel,incrementheightby1(heightisinitializedas0).Countnumberofnodesateachlevel,
stoptraversingwhencountofnodesatnextlevelis0.
Followingisdetailedalgorithmtofindlevelordertraversalusingqueue.

Createaqueue.
Pushrootintothequeue.
height=0
Loop
nodeCount=sizeofqueue

//Ifnumberofnodesatthislevelis0,returnheight
ifnodeCountis0
returnHeight
else
increaseHeight

//Removenodesofthislevelandaddnodesof
//nextlevel
while(nodeCount>0)
popnodefromfront
pushitschildrentoqueue
decreasenodeCount
//Atthispoint,queuehasnodesofnextlevel

FollowingisC++implementationofabovealgorithm.
/* Program to find height of the tree by Iterative Method */
#include <iostream>
#include <queue>
using namespace std;

// A Binary Tree Node


struct node
{
struct node *left;
int data;
struct node *right;
};

// Iterative method to find height of Bianry Tree


int treeHeight(node *root)
{

// Base Case
if (root == NULL)
return 0;

// Create an empty queue for level order tarversal


queue<node *> q;

// Enqueue Root and initialize height


q.push(root);
int height = 0;

while (1)
{
// nodeCount (queue size) indicates number of nodes
// at current lelvel.
int nodeCount = q.size();
if (nodeCount == 0)
return height;

height++;

// Dequeue all nodes of current level and Enqueue all


// nodes of next level
while (nodeCount > 0)
{
node *node = q.front();
q.pop();
if (node->left != NULL)
q.push(node->left);
if (node->right != NULL)
q.push(node->right);
nodeCount--;
}
}
}

// Utility function to create a new tree node

node* newNode(int data)


{
node *temp = new node;
temp->data = data;
temp->left = NULL;
temp->right = NULL;
return temp;
}

// Driver program to test above functions


int main()
{
// Let us create binary tree shown in above diagram
node *root = newNode(1);
root->left = newNode(2);
root->right = newNode(3);
root->left->left = newNode(4);
root->left->right = newNode(5);

cout << "Height of tree is " << treeHeight(root);


return 0;
}
Output:

Heightoftreeis3
TimeComplexity:O(n)wherenisnumberofnodesingivenbinarytree.

=======================================================================

Findallpossibleinterpretationsofan
arrayofdigits
Consideracodingsystemforalphabetstointegerswhereaisrepresentedas1,bas2,..zas26.Given
anarrayofdigits(1to9)asinput,writeafunctionthatprintsallvalidinterpretationsofinputarray.
Examples

Input:{1,1}
Output:("aa",'k")

[2interpretations:aa(1,1),k(11)]

Input:{1,2,1}
Output:("aba","au","la")
[3interpretations:aba(1,2,1),au(1,21),la(12,1)]

Input:{9,1,8}
Output:{"iah","ir"}
[2interpretations:iah(9,1,8),ir(9,18)]
Pleasenotewecannotchangeorderofarray.Thatmeans{1,2,1}cannotbecome{2,1,1}
Onfirstlookitlookslikeaproblemofpermutation/combination.Butoncloserlookyouwillfigureoutthatthis
isaninterestingtreeproblem.
Theideahereisstringcantakeatmosttwopaths:
1.Processingledigit
2.Processtwodigits
Thatmeanswecanusebinarytreehere.Processingwithsingledigitwillbeleftchildandtwodigitswillbe
rightchild.Ifvaluetwodigitsisgreaterthan26thenourrightchildwillbenullaswedonthavealphabetfor
greaterthan26.
Letsunderstandwithanexample.Arraya={1,2,1}.Belowdiagramshowsthathowourtreegrows.

{1,2,1}Codesusedintree
/\"a">1
/\"b">2
"a"{2,1}"l"{1}"l">12
/\/\
/\/\
"ab"{1}"au""la"null
/\
/\
"aba"null
Braces{}containarraystillpendingforprocessing.Notethatwitheverylevel,ourarraysizedecreases.If
youwillseecarefully,itisnothardtofindthattreeheightisalwaysn(arraysize)
Howtoprintallstrings(interpretations)?Outputstringsareleafnodeoftree.i.efor{1,2,1},outputis{abaau
la}.
Wecanconcludethattherearemainlytwostepstoprintallinterpretationsofgivenintegerarray.
Step1:Createabinarytreewithallpossibleinterpretationsinleafnodes.
Step2:Printallleafnodesfromthebinarytreecreatedinstep1.
FollowingisJavaimplementationofabovealgorithm.

// A Java program to print all interpretations of an integer array


import java.util.Arrays;

// A Binary Tree node


class Node {

String dataString;
Node left;
Node right;

Node(String dataString) {
this.dataString = dataString;
//Be default left and right child are null.
}

public String getDataString() {


return dataString;
}
}

public class arrayToAllInterpretations {

// Method to create a binary tree which stores all interpretations


// of arr[] in lead nodes
public static Node createTree(int data, String pString, int[] arr) {

// Invalid input as alphabets maps from 1 to 26


if (data > 26)
return null;

// Parent String + String for this node


String dataToStr = pString + alphabet[data];

Node root = new Node(dataToStr);

// if arr.length is 0 means we are done


if (arr.length != 0) {

data = arr[0];

// new array will be from index 1 to end as we are consuming


// first index with this node
int newArr[] = Arrays.copyOfRange(arr, 1, arr.length);

// left child
root.left = createTree(data, dataToStr, newArr);

// right child will be null if size of array is 0 or 1


if (arr.length > 1) {

data = arr[0] * 10 + arr[1];

// new array will be from index 2 to end as we


// are consuming first two index with this node
newArr = Arrays.copyOfRange(arr, 2, arr.length);

root.right = createTree(data, dataToStr, newArr);


}
}
return root;
}

// To print out leaf nodes


public static void printleaf(Node root) {
if (root == null)
return;

if (root.left == null && root.right == null)


System.out.print(root.getDataString() + " ");

printleaf(root.left);
printleaf(root.right);
}

// The main function that prints all interpretations of array

static void printAllInterpretations(int[] arr) {

// Step 1: Create Tree


Node root = createTree(0, "", arr);

// Step 2: Print Leaf nodes


printleaf(root);

System.out.println(); // Print new line


}

// For simplicity I am taking it as string array. Char Array will save space
private static final String[] alphabet = {"", "a", "b", "c", "d", "e",
"f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r",
"s", "t", "u", "v", "w", "x", "v", "z"};

// Driver method to test above methods


public static void main(String args[]) {

// aacd(1,1,3,4) amd(1,13,4) kcd(11,3,4)


// Note : 1,1,34 is not valid as we don't have values corresponding
// to 34 in alphabet
int[] arr = {1, 1, 3, 4};
printAllInterpretations(arr);

// aaa(1,1,1) ak(1,11) ka(11,1)


int[] arr2 = {1, 1, 1};
printAllInterpretations(arr2);

// 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);

// "" empty string output as array is empty


int[] arr6 = {};
printAllInterpretations(arr6);

// abba abu ava lba lu


int[] arr7 = {1, 2, 2, 1};
printAllInterpretations(arr7);
}
}
Output:

aacdamdkcd
aaaakka
bfz
abl
aj

abbaabuavalbalu
=======================================================================

TreeIsomorphismProblem
Writeafunctiontodetectiftwotreesareisomorphic.Twotreesarecalledisomorphicifoneofthemcanbe
obtainedfromotherbyaseriesofflips,i.e.byswappingleftandrightchildrenofanumberofnodes.Any
numberofnodesatanylevelcanhavetheirchildrenswapped.Twoemptytreesareisomorphic.
Forexample,followingtwotreesareisomorphicwithfollowingsubtreesflipped:2and3,NULLand6,7and
8.


Wesimultaneouslytraversebothtrees.Letthecurrentinternalnodesoftwotreesbeingtraversedben1and
n2respectively.Therearefollowingtwoconditionsforsubtreesrootedwithn1andn2tobeisomorphic.
1)Dataofn1andn2issame.
2)Oneofthefollowingtwoistrueforchildrenofn1andn2
a)Leftchildofn1isisomorphictoleftchildofn2andrightchildofn1isisomorphictorightchildofn2.
b)Leftchildofn1isisomorphictorightchildofn2andrightchildofn1isisomorphictoleftchildofn2.
// A C++ program to check if two given trees are isomorphic
#include <iostream>
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;
};

/* Given a binary tree, print its nodes in reverse level order */


bool isIsomorphic(node* n1, node *n2)
{
// Both roots are NULL, trees isomorphic by definition
if (n1 == NULL && n2 == NULL)
return true;

// Exactly one of the n1 and n2 is NULL, trees not isomorphic


if (n1 == NULL || n2 == NULL)
return false;

if (n1->data != n2->data)
return false;

// There are two possible cases for n1 and n2 to be isomorphic


// Case 1: The subtrees rooted at these nodes have NOT been "Flipped".
// Both of these subtrees have to be isomorphic, hence the &&
// Case 2: The subtrees rooted at these nodes have been "Flipped"
return
(isIsomorphic(n1->left,n2->left) && isIsomorphic(n1->right,n2->right))||
(isIsomorphic(n1->left,n2->right) && isIsomorphic(n1->right,n2->left));
}

/* Helper function that allocates a new node with the


given data and NULL left and right pointers. */
node* newNode(int data)
{
node* temp = new node;
temp->data = data;
temp->left = NULL;
temp->right = NULL;

return (temp);
}

/* Driver program to test above functions*/


int main()
{
// Let us create trees shown in above diagram
struct node *n1 = newNode(1);
n1->left

= newNode(2);

n1->right

= newNode(3);

n1->left->left = newNode(4);
n1->left->right = newNode(5);

n1->right->left = newNode(6);
n1->left->right->left = newNode(7);
n1->left->right->right = newNode(8);

struct node *n2 = newNode(1);


n2->left

= newNode(3);

n2->right

= newNode(2);

n2->right->left
n2->right->right
n2->left->right

= newNode(4);
= newNode(5);
= newNode(6);

n2->right->right->left = newNode(8);
n2->right->right->right = newNode(7);

if (isIsomorphic(n1, n2) == true)


cout << "Yes";
else
cout << "No";

return 0;
}
Output:

Yes
TimeComplexity:Theabovesolutiondoesatraversalofbothtrees.SotimecomplexityisO(m+n)where
mandnarenumberofnodesingiventrees.

=======================================================================

LongestprefixmatchingATrie
basedsolutioninJava
Givenadictionaryofwordsandaninputstring,findthelongestprefixofthestringwhichisalsoawordin
dictionary.
Examples:

Letthedictionarycontainsthefollowingwords:
{are,area,base,cat,cater,children,basement}

Belowaresomeinput/outputexamples:

InputStringOutput

caterercater
basemexybase
child<Empty>
Solution
WebuildaTrieofalldictionarywords.OncetheTrieisbuilt,traversethroughitusingcharactersofinput
string.Ifprefixmatchesadictionaryword,storecurrentlengthandlookforalongermatch.Finally,return
thelongestmatch.
FollowingisJavaimplementationoftheabovesolutionbased.
import java.util.HashMap;

// Trie Node, which stores a character and the children in a HashMap


class TrieNode {
public TrieNode(char ch) {
value = ch;
children = new HashMap<>();
bIsEnd = false;
}
public HashMap<Character,TrieNode> getChildren() {

return children; }

public char getValue()

return value;

public void setIsEnd(boolean val)

bIsEnd = val;

public boolean isEnd()

return bIsEnd; }

private char value;


private HashMap<Character,TrieNode> children;
private boolean bIsEnd;
}

// Implements the actual Trie


class Trie {
// Constructor
public Trie()

root = new TrieNode((char)0);

// Method to insert a new word to Trie

public void insert(String word) {

// Find length of the given word


int length = word.length();
TrieNode crawl = root;

// Traverse through all characters of given word


for( int level = 0; level < length; level++)
{
HashMap<Character,TrieNode> child = crawl.getChildren();
char ch = word.charAt(level);

// If there is already a child for current character of given word


if( child.containsKey(ch))
crawl = child.get(ch);
else

// Else create a child

{
TrieNode temp = new TrieNode(ch);
child.put( ch, temp );
crawl = temp;
}
}

// Set bIsEnd true for last character


crawl.setIsEnd(true);
}

// 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

// Initialize reference to traverse through Trie


TrieNode crawl = root;

// Iterate through all characters of input string 'str' and traverse


// down the Trie

int level, prevMatch = 0;


for( level = 0 ; level < length; level++ )
{
// Find current character of str
char ch = input.charAt(level);

// HashMap of current Trie node to traverse down


HashMap<Character,TrieNode> child = crawl.getChildren();

// See if there is a Trie edge for the current character


if( child.containsKey(ch) )
{
result += ch;

//Update result

crawl = child.get(ch); //Update crawl to move down in Trie

// If this is end of a word, then update prevMatch


if( crawl.isEnd() )
prevMatch = level + 1;
}
else break;
}

// If the last processed character did not match end of a word,


// return the previously matching prefix
if( !crawl.isEnd() )
return result.substring(0, prevMatch);

else return result;


}

private TrieNode root;


}

// 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");

String input = "caterer";


System.out.print(input + ":

");

System.out.println(dict.getMatchingPrefix(input));

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:

TimeComplexity:TimecomplexityoffindingthelongestprefixisO(n)wherenislengthoftheinputstring.
ReferthisfortimecomplexityofbuildingtheTrie.

=======================================================================

BTree|Set2(Insert)
Inthepreviouspost,weintroducedBTree.Wealsodiscussedsearch()andtraverse()functions.
Inthispost,insert()operationisdiscussed.Anewkeyisalwaysinsertedatleafnode.Letthekeytobe
insertedbek.LikeBST,westartfromrootandtraversedowntillwereachaleafnode.Oncewereachaleaf
node,weinsertthekeyinthatleafnode.UnlikeBSTs,wehaveapredefinedrangeonnumberofkeysthata
nodecancontain.Sobeforeinsertingakeytonode,wemakesurethatthenodehasextraspace.
Howtomakesurethatanodehasspaceavailableforkeybeforethekeyisinserted?Weuseanoperation
calledsplitChild()thatisusedtosplitachildofanode.Seethefollowingdiagramtounderstandsplit.Inthe
followingdiagram,childyofxisbeingsplitintotwonodesyandz.NotethatthesplitChildoperationmoves
akeyupandthisisthereasonBTreesgrowupunlikeBSTswhichgrowdown.

Asdiscussedabove,toinsertanewkey,wegodownfromroottoleaf.Beforetraversingdowntoanode,
wefirstcheckifthenodeisfull.Ifthenodeisfull,wesplitittocreatespace.Followingiscompletealgorithm.
Insertion
1)Initializexasroot.
2)Whilexisnotleaf,dofollowing
..a)Findthechildofxthatisgoingtotobetraversednext.Letthechildbey.
..b)Ifyisnotfull,changextopointtoy.

..c)Ifyisfull,splititandchangextopointtooneofthetwopartsofy.Ifkissmallerthanmidkeyiny,then
setxasfirstpartofy.Elsesecondpartofy.Whenwesplity,wemoveakeyfromytoitsparentx.
3)Theloopinstep2stopswhenxisleaf.xmusthavespacefor1extrakeyaswehavebeensplittingall
nodesinadvance.Sosimplyinsertktox.
NotethatthealgorithmfollowstheCormenbook.Itisactuallyaproactiveinsertionalgorithmwherebefore
goingdowntoanode,wesplititifitisfull.Theadvantageofsplittingbeforeis,wenevertraverseanode
twice.Ifwedontsplitanodebeforegoingdowntoitandsplititonlyifnewkeyisinserted(reactive),we
mayenduptraversingallnodesagainfromleaftoroot.Thishappensincaseswhenallnodesonthepath
fromroottoleafarefull.Sowhenwecometotheleafnode,wesplititandmoveakeyup.Movingakeyup
willcauseasplitinparentnode(becauseparentwasalreadyfull).Thiscascadingeffectneverhappensin
thisproactiveinsertionalgorithm.Thereisadisadvantageofthisproactiveinsertionthough,wemaydo
unnecessarysplits.
Letusunderstandthealgorithmwithanexampletreeofminimumdegreetas3andasequenceofintegers
10,20,30,40,50,60,70,80and90inaninitiallyemptyBTree.
InitiallyrootisNULL.Letusfirstinsert10.

Letusnowinsert20,30,40and50.Theyallwillbeinsertedinrootbecausemaximumnumberofkeysa
nodecanaccommodateis2*t1whichis5.

Letusnowinsert60.Sincerootnodeisfull,itwillfirstsplitintotwo,then60willbeinsertedintothe
appropriatechild.


Letusnowinsert70and80.Thesenewkeyswillbeinsertedintotheappropriateleafwithoutanysplit.

Letusnowinsert90.Thisinsertionwillcauseasplit.Themiddlekeywillgouptotheparent.

Seethisformoreexamples.
FollowingisC++implementationoftheaboveproactivealgorithm.
// C++ program for B-Tree insertion
#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 utility function to insert a new key in the subtree rooted with


// this node. The assumption is, the node must be non-full when this
// function is called
void insertNonFull(int k);

// A utility function to split the child y of this node. i is index of y in


// child array C[]. The Child y must be full when this function is called
void splitChild(int i, BTreeNode *y);

// A function to traverse all nodes in a subtree rooted with this node


void traverse();

// A function to search a key in subtree rooted with this node.


BTreeNode *search(int k);

// returns NULL if k is not present.

// 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; }

// function to traverse the tree


void traverse()
{ if (root != NULL) root->traverse(); }

// function to search a key in this tree


BTreeNode* search(int k)
{ return (root == NULL)? NULL : root->search(k); }

// The main function that inserts a new key in this B-Tree


void insert(int k);
};

// Constructor for BTreeNode class


BTreeNode::BTreeNode(int t1, bool leaf1)
{
// Copy the given minimum degree and leaf property
t = t1;
leaf = leaf1;

// Allocate memory for maximum number of possible keys


// and child pointers
keys = new int[2*t-1];
C = new BTreeNode *[2*t];

// Initialize the number of keys as 0


n = 0;
}

// Function to traverse all nodes in a subtree rooted with this node


void BTreeNode::traverse()
{
// There are n keys and n+1 children, travers through n keys
// and first n children
int i;
for (i = 0; i < n; i++)
{
// If this is not leaf, then before printing key[i],

// traverse the subtree rooted with child C[i].


if (leaf == false)
C[i]->traverse();
cout << " " << keys[i];
}

// Print the subtree rooted with last child


if (leaf == false)
C[i]->traverse();
}

// Function to search key k in subtree rooted with this node


BTreeNode *BTreeNode::search(int k)
{
// Find the first key greater than or equal to k
int i = 0;
while (i < n && k > keys[i])
i++;

// If the found key is equal to k, return this node


if (keys[i] == k)
return this;

// If key is not found here and this is a leaf node


if (leaf == true)
return NULL;

// Go to the appropriate child


return C[i]->search(k);
}

// The main function that inserts a new key in this B-Tree


void BTree::insert(int k)
{
// If tree is empty
if (root == NULL)
{

// Allocate memory for root


root = new BTreeNode(t, true);
root->keys[0] = k; // Insert key
root->n = 1; // Update number of keys in root
}
else // If tree is not empty
{
// If root is full, then tree grows in height
if (root->n == 2*t-1)
{
// Allocate memory for new root
BTreeNode *s = new BTreeNode(t, false);

// Make old root as child of new root


s->C[0] = root;

// Split the old root and move 1 key to the new root
s->splitChild(0, root);

// New root has two children now. Decide which of the


// two children is going to have new key
int i = 0;
if (s->keys[0] < k)
i++;
s->C[i]->insertNonFull(k);

// Change root
root = s;
}
else // If root is not full, call insertNonFull for root
root->insertNonFull(k);
}
}

// A utility function to insert a new key in this node


// The assumption is, the node must be non-full when this
// function is called

void BTreeNode::insertNonFull(int k)
{
// Initialize index as index of rightmost element
int i = n-1;

// If this is a leaf node


if (leaf == true)
{
// The following loop does two things
// a) Finds the location of new key to be inserted
// b) Moves all greater keys to one place ahead
while (i >= 0 && keys[i] > k)
{
keys[i+1] = keys[i];
i--;
}

// Insert the new key at found location


keys[i+1] = k;
n = n+1;
}
else // If this node is not leaf
{
// Find the child which is going to have the new key
while (i >= 0 && keys[i] > k)
i--;

// See if the found child is full


if (C[i+1]->n == 2*t-1)
{
// If the child is full, then split it
splitChild(i+1, C[i+1]);

// After split, the middle key of C[i] goes up and


// C[i] is splitted into two. See which of the two
// is going to have the new key
if (keys[i+1] < k)

i++;
}
C[i+1]->insertNonFull(k);
}
}

// A utility function to split the child y of this node


// Note that y must be full when this function is called
void BTreeNode::splitChild(int i, BTreeNode *y)
{
// Create a new node which is going to store (t-1) keys
// of y
BTreeNode *z = new BTreeNode(y->t, y->leaf);
z->n = t - 1;

// Copy the last (t-1) keys of y to z


for (int j = 0; j < t-1; j++)
z->keys[j] = y->keys[j+t];

// Copy the last t children of y to z


if (y->leaf == false)
{
for (int j = 0; j < t; j++)
z->C[j] = y->C[j+t];
}

// Reduce the number of keys in y


y->n = t - 1;

// Since this node is going to have a new child,


// create space of new child
for (int j = n; j >= i+1; j--)
C[j+1] = C[j];

// Link the new child to this node


C[i+1] = z;

// A key of y will move to this node. Find location of


// new key and move all greater keys one space ahead
for (int j = n-1; j >= i; j--)
keys[j+1] = keys[j];

// Copy the middle key of y to this node


keys[i] = y->keys[t-1];

// Increment count of keys in this node


n = n + 1;
}

// Driver program to test above functions


int main()
{
BTree t(3); // A B-Tree with minium degree 3
t.insert(10);
t.insert(20);
t.insert(5);
t.insert(6);
t.insert(12);
t.insert(30);
t.insert(7);
t.insert(17);

cout << "Traversal of the constucted tree is ";


t.traverse();

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:

Traversaloftheconstuctedtreeis5671012172030
Present
NotPresent

=======================================================================

BTree|Set1(Introduction)
BTreeisaselfbalancingsearchtree.Inmostoftheotherselfbalancingsearchtrees(likeAVLandRed
BlackTrees),itisassumedthateverythingisinmainmemory.TounderstanduseofBTrees,wemustthink
ofhugeamountofdatathatcannotfitinmainmemory.Whenthenumberofkeysishigh,thedataisread
fromdiskintheformofblocks.Diskaccesstimeisveryhighcomparedtomainmemoryaccesstime.The
mainideaofusingBTreesistoreducethenumberofdiskaccesses.Mostofthetreeoperations(search,
insert,delete,max,min,..etc)requireO(h)diskaccesseswherehisheightofthetree.Btreeisafattree.
HeightofBTreesiskeptlowbyputtingmaximumpossiblekeysinaBTreenode.Generally,aBTreenode
sizeiskeptequaltothediskblocksize.SincehislowforBTree,totaldiskaccessesformostofthe
operationsarereducedsignificantlycomparedtobalancedBinarySearchTreeslikeAVLTree,RedBlack
Tree,..etc.
PropertiesofBTree
1)Allleavesareatsamelevel.
2)ABTreeisdefinedbythetermminimumdegreet.Thevalueoftdependsupondiskblocksize.
3)Everynodeexceptrootmustcontainatleastt1keys.Rootmaycontainminimum1key.
4)Allnodes(includingroot)maycontainatmost2t1keys.
5)Numberofchildrenofanodeisequaltothenumberofkeysinitplus1.
6)Allkeysofanodearesortedinincreasingorder.Thechildbetweentwokeysk1andk2containsallkeys
inrangefromk1andk2.
7)BTreegrowsandshrinksfromrootwhichisunlikeBinarySearchTree.BinarySearchTreesgrow
downwardandalsoshrinkfromdownward.
8)LikeotherbalancedBinarySearchTrees,timecomplexitytosearch,insertanddeleteisO(Logn).
FollowingisanexampleBTreeofminimumdegree3.NotethatinpracticalBTrees,thevalueofminimum
degreeismuchmorethan3.


Search
SearchissimilartosearchinBinarySearchTree.Letthekeytobesearchedbek.Westartfromrootand
recursivelytraversedown.Foreveryvisitednonleafnode,ifthenodehaskey,wesimplyreturnthenode.
Otherwisewerecurdowntotheappropriatechild(Thechildwhichisjustbeforethefirstgreaterkey)ofthe
node.Ifwereachaleafnodeanddontfindkintheleafnode,wereturnNULL.
Traverse
TraversalisalsosimilartoInordertraversalofBinaryTree.Westartfromtheleftmostchild,recursivelyprint
theleftmostchild,thenrepeatthesameprocessforremainingchildrenandkeys.Intheend,recursively
printtherightmostchild.
// C++ implemntation of search() and traverse() methods
#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 to traverse all nodes in a subtree rooted with this node


void traverse();

// A function to search a key in subtree rooted with this node.


BTreeNode *search(int k);

// returns NULL if k is not present.

// 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; }

// function to traverse the tree


void traverse()
{ if (root != NULL) root->traverse(); }

// function to search a key in this tree


BTreeNode* search(int k)
{ return (root == NULL)? NULL : root->search(k); }
};

// Constructor for BTreeNode class


BTreeNode::BTreeNode(int _t, bool _leaf)
{
// Copy the given minimum degree and leaf property
t = _t;
leaf = _leaf;

// Allocate memory for maximum number of possible keys


// and child pointers
keys = new int[2*t-1];

C = new BTreeNode *[2*t];

// Initialize the number of keys as 0


n = 0;
}

// Function to traverse all nodes in a subtree rooted with this node


void BTreeNode::traverse()
{
// There are n keys and n+1 children, travers through n keys
// and first n children
int i;
for (i = 0; i < n; i++)
{
// If this is not leaf, then before printing key[i],
// traverse the subtree rooted with child C[i].
if (leaf == false)
C[i]->traverse();
cout << " " << keys[i];
}

// Print the subtree rooted with last child


if (leaf == false)
C[i]->traverse();
}

// Function to search key k in subtree rooted with this node


BTreeNode *BTreeNode::search(int k)
{
// Find the first key greater than or equal to k
int i = 0;
while (i < n && k > keys[i])
i++;

// If the found key is equal to k, return this node


if (keys[i] == k)
return this;

// If key is not found here and this is a leaf node


if (leaf == true)
return NULL;

// Go to the appropriate child


return C[i]->search(k);
}
Theabovecodedoesntcontaindriverprogram.Wewillbecoveringthecompleteprograminournextpost
onBTreeInsertion.
TherearetwoconventionstodefineaBTree,oneistodefinebyminimumdegree(followedinCormen
book),secondisdefinebyorder.Wehavefollowedtheminimumdegreeconventionandwillbefollowing
sameincomingpostsonBTree.Thevariablenamesusedintheaboveprogramarealsokeptsameas
Cormenbookforbetterreadability.
InsertionandDeletion
BTrerInsertion
BTreeDeletion

=======================================================================

ConvertagivenBinaryTreeto
DoublyLinkedList|Set1
GivenaBinaryTree(Bt),convertittoaDoublyLinkedList(DLL).Theleftandrightpointersinnodesareto
beusedaspreviousandnextpointersrespectivelyinconvertedDLL.TheorderofnodesinDLLmustbe
sameasInorderofthegivenBinaryTree.ThefirstnodeofInordertraversal(leftmostnodeinBT)mustbe
headnodeoftheDLL.


Icameacrossthisinterviewduringoneofmyinterviews.Asimilarproblemisdiscussedinthispost.The
problemhereissimpleraswedontneedtocreatecircularDLL,butasimpleDLL.Theideabehindits
solutionisquitesimpleandstraight.
1.Ifleftsubtreeexists,processtheleftsubtree
..1.a)RecursivelyconverttheleftsubtreetoDLL.
..1.b)Thenfindinorderpredecessorofrootinleftsubtree(inorderpredecessorisrightmostnodeinleft
subtree).
..1.c)Makeinorderpredecessoraspreviousofrootandrootasnextofinorderpredecessor.
2.Ifrightsubtreeexists,processtherightsubtree(Below3stepsaresimilartoleftsubtree).
..2.a)RecursivelyconverttherightsubtreetoDLL.
..2.b)Thenfindinordersuccessorofrootinrightsubtree(inordersuccessorisleftmostnodeinright
subtree).
..2.c)Makeinordersuccessorasnextofrootandrootaspreviousofinordersuccessor.
3.Findtheleftmostnodeandreturnit(theleftmostnodeisalwaysheadofconvertedDLL).
Belowisthesourcecodeforabovealgorithm.
// A C++ program for in-place conversion of Binary Tree to DLL
#include <stdio.h>

/* 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;

// Convert the left subtree and link to root


if (root->left != NULL)
{
// Convert the left subtree
node* left = bintree2listUtil(root->left);

// Find inorder predecessor. After this loop, left


// will point to the inorder predecessor
for (; left->right!=NULL; left=left->right);

// Make root as next of the predecessor


left->right = root;

// Make predecssor as previous of root


root->left = left;
}

// Convert the right subtree and link to root


if (root->right!=NULL)
{
// Convert the right subtree
node* right = bintree2listUtil(root->right);

// Find inorder successor. After this loop, right


// will point to the inorder successor

for (; right->left!=NULL; right = right->left);

// Make root as previous of successor


right->left = root;

// Make successor as next of root


root->right = right;
}

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;

// Convert to DLL using bintree2listUtil()


root = bintree2listUtil(root);

// bintree2listUtil() returns root node of the converted


// DLL. We need pointer to the leftmost node which is
// head of the constructed DLL, so move to the leftmost node
while (root->left != NULL)
root = root->left;

return (root);
}

/* Helper function that allocates a new node with the


given data and NULL left and right pointers. */
node* newNode(int data)
{
node* new_node = new node;

new_node->data = data;
new_node->left = new_node->right = NULL;
return (new_node);
}

/* Function to print nodes in a given doubly linked list */


void printList(node *node)
{
while (node!=NULL)
{
printf("%d ", node->data);
node = node->right;
}
}

/* Driver program to test above functions*/


int main()
{
// Let us create the tree shown in above diagram
node *root

= newNode(10);

root->left

= newNode(12);

root->right

= newNode(15);

root->left->left = newNode(25);
root->left->right = newNode(30);
root->right->left = newNode(36);

// Convert to DLL
node *head = bintree2list(root);

// Print the converted list


printList(head);

return 0;
}
Output:

251230103615
=======================================================================

RemoveBSTkeysoutsidethegiven
range
GivenaBinarySearchTree(BST)andarange[min,max],removeallkeyswhichareoutsidethegiven
range.ThemodifiedtreeshouldalsobeBST.Forexample,considerthefollowingBSTandrange[10,13].

Thegiventreeshouldbechangedtofollowing.Notethatallkeysoutsidetherange[10,13]areremoved
andmodifiedtreeisBST.

Therearetwopossiblecasesforeverynode.

1)Nodeskeyisoutsidethegivenrange.Thiscasehastwosubcases.
.a)Nodeskeyissmallerthantheminvalue.
.b)Nodeskeyisgreaterthatthemaxvalue.
2)Nodeskeyisinrange.
Wedontneedtodoanythingforcase2.Incase1,weneedtoremovethenodeandchangerootof
subtreerootedwiththisnode.
TheideaistofixthetreeinPostorderfashion.Whenwevisitanode,wemakesurethatitsleftandright
subtreesarealreadyfixed.Incase1.a),wesimplyremoverootandreturnrightsubtreeasnewroot.In
case1.b),weremoverootandreturnleftsubtreeasnewroot.
FollowingisC++implementationoftheaboveapproach.
// A C++ program to remove BST keys outside the given range
#include<stdio.h>
#include <iostream>

using namespace std;

// A BST node has key, and left and right pointers


struct node
{
int key;
struct node *left;
struct node *right;
};

// 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;

// First fix the left and right subtrees of root


root->left = removeOutsideRange(root->left, min, max);
root->right = removeOutsideRange(root->right, min, max);

// 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;
}

// A utility function to insert a given key to BST


node* insert(node* root, int key)
{
if (root == NULL)
return newNode(key);
if (root->key > key)
root->left = insert(root->left, key);
else
root->right = insert(root->right, key);
return root;

// Utility function to traverse the binary tree after conversion


void inorderTraversal(node* root)
{
if (root)
{
inorderTraversal( root->left );
cout << root->key << " ";
inorderTraversal( root->right );
}
}

// Driver program to test above functions


int main()
{
node* root = NULL;
root = insert(root, 6);
root = insert(root, -13);
root = insert(root, 14);
root = insert(root, -8);
root = insert(root, 15);
root = insert(root, 13);
root = insert(root, 7);

cout << "Inorder traversal of the given tree is: ";


inorderTraversal(root);

root = removeOutsideRange(root, -10, 13);

cout << "\nInorder traversal of the modified tree is: ";


inorderTraversal(root);

return 0;
}
Output:

Inordertraversalofthegiventreeis:13867131415
Inordertraversalofthemodifiedtreeis:86713
TimeComplexity:O(n)wherenisthenumberofnodesingivenBST.

=======================================================================

ConstructCompleteBinaryTree
fromitsLinkedListRepresentation
GivenLinkedListRepresentationofCompleteBinaryTree,constructtheBinarytree.Acompletebinarytree
canberepresentedinanarrayinthefollowingapproach.
Ifrootnodeisstoredatindexi,itsleft,andrightchildrenarestoredatindices2*i+1,2*i+2respectively.
Supposetreeisrepresentedbyalinkedlistinsameway,howdoweconvertthisintonormallinked
representationofbinarytreewhereeverynodehasdata,leftandrightpointers?Inthelinkedlist
representation,wecannotdirectlyaccessthechildrenofthecurrentnodeunlesswetraversethelist.

Wearemainlygivenlevelordertraversalinsequentialaccessform.Weknowheadoflinkedlistisalwaysis
rootofthetree.Wetakethefirstnodeasrootandwealsoknowthatthenexttwonodesareleftandright
childrenofroot.SoweknowpartialBinaryTree.TheideaistodoLevelordertraversalofthepartiallybuilt
BinaryTreeusingqueueandtraversethelinkedlistatthesametime.Ateverystep,wetaketheparent
nodefromqueue,makenexttwonodesoflinkedlistaschildrenoftheparentnode,andenqueuethenext
twonodestoqueue.
1.Createanemptyqueue.

2.Makethefirstnodeofthelistasroot,andenqueueittothequeue.
3.Untilwereachtheendofthelist,dothefollowing.
a.Dequeueonenodefromthequeue.Thisisthecurrentparent.
b.Traversetwonodesinthelist,addthemaschildrenofthecurrentparent.
c.Enqueuethetwonodesintothequeue.
BelowisthecodewhichimplementsthesameinC++.
// C++ program to create a Complete Binary tree from its Linked List
// Representation
#include <iostream>
#include <string>
#include <queue>
using namespace std;

// Linked list node


struct ListNode
{
int data;
ListNode* next;
};

// Binary tree node structure


struct BinaryTreeNode
{
int data;
BinaryTreeNode *left, *right;
};

// Function to insert a node at the beginning of the Linked List


void push(struct ListNode** head_ref, int new_data)
{
// allocate node and assign data
struct ListNode* new_node = new ListNode;
new_node->data = new_data;

// link the old list off the new node


new_node->next = (*head_ref);

// move the head to point to the new node


(*head_ref)

= new_node;

// 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);

// advance the pointer to the next node


head = head->next;

// until the end of linked list is reached, do the following steps


while (head)
{

// 2.a) take the parent node from the q and remove it from q
BinaryTreeNode* parent = q.front();
q.pop();

// 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;
}

// 2.b) assign the left and right children of parent


parent->left = leftChild;
parent->right = rightChild;
}
}

// Utility function to traverse the binary tree after conversion


void inorderTraversal(BinaryTreeNode* root)
{
if (root)
{
inorderTraversal( root->left );
cout << root->data << " ";
inorderTraversal( root->right );
}
}

// Driver program to test above functions


int main()

{
// create a linked list shown in above diagram
struct ListNode* head = NULL;
push(&head, 36); /* Last node of Linked List */
push(&head, 30);
push(&head, 25);
push(&head, 15);
push(&head, 12);
push(&head, 10); /* First node of Linked List */

BinaryTreeNode *root;
convertList2Binary(head, root);

cout << "Inorder Traversal of the constructed Binary Tree is: \n";
inorderTraversal(root);
return 0;
}
Output:

InorderTraversaloftheconstructedBinaryTreeis:
251230103615
TimeComplexity:TimecomplexityoftheabovesolutionisO(n)wherenisthenumberofnodes

=======================================================================

ReverseLevelOrderTraversal
Wehavediscussedlevelordertraversalofapostinpreviouspost.Theideaistoprintlastlevelfirst,then
secondlastlevel,andsoon.LikeLevelordertraversal,everylevelisprintedfromlefttoright.


ExampleTree

ReverseLevelordertraversaloftheabovetreeis45231.
Bothmethodsfornormallevelordertraversalcanbeeasilymodifiedtodoreverselevelordertraversal.
METHOD1(Recursivefunctiontoprintagivenlevel)
Wecaneasilymodifythemethod1ofthenormallevelordertraversal.Inmethod1,wehaveamethod
printGivenLevel()whichprintsagivenlevelnumber.Theonlythingweneedtochangeis,insteadofcalling
printGivenLevel()fromfirstleveltolastlevel,wecallitfromlastleveltofirstlevel.
// 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);

/* Function to print REVERSE level order traversal a tree*/


void reverseLevelOrder(struct node* root)

{
int h = height(root);
int i;
for (i=h; i>=1; i--) //THE ONLY LINE DIFFERENT FROM NORMAL LEVEL ORDER
printGivenLevel(root, i);
}

/* Print nodes at a given level */


void printGivenLevel(struct node* root, int level)
{
if (root == NULL)
return;
if (level == 1)
printf("%d ", root->data);
else if (level > 1)
{
printGivenLevel(root->left, level-1);
printGivenLevel(root->right, level-1);
}
}

/* 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 */


if (lheight > rheight)
return(lheight+1);

else return(rheight+1);
}
}

/* 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);
}

/* Driver program to test above functions*/


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);

printf("Level Order traversal of binary tree is \n");


reverseLevelOrder(root);

return 0;
}
Output:

LevelOrdertraversalofbinarytreeis
45231
TimeComplexity:TheworstcasetimecomplexityofthismethodisO(n^2).Foraskewedtree,
printGivenLevel()takesO(n)timewherenisthenumberofnodesintheskewedtree.Sotimecomplexityof
printLevelOrder()isO(n)+O(n1)+O(n2)+..+O(1)whichisO(n^2).

METHOD2(UsingQueueandStack)
Themethod2ofnormallevelordertraversalcanalsobeeasilymodifiedtoprintlevelordertraversalin
reverseorder.Theideaistouseastacktogetthereverselevelorder.Ifwedonormallevelordertraversal
andinsteadofprintinganode,pushthenodetoastackandthenprintcontentsofstack,weget54321
foraboveexampletree,butoutputshouldbe45231.Sotogetthecorrectsequence(lefttorightatevery
level),weprocesschildrenofanodeinreverseorder,wefirstpushtherightsubtreetostack,thenleft
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;
};

/* Given a binary tree, print its nodes in reverse level order */


void reverseLevelOrder(node* root)
{
stack <node *> S;
queue <node *> Q;
Q.push(root);

// Do something like normal level order traversal order. Following are the
// differences with normal level order traversal
// 1) Instead of printing a node, we push the node to stack
// 2) Right subtree is visited before left subtree
while (Q.empty() == false)

{
/* Dequeue node and make it root */
root = Q.front();
Q.pop();
S.push(root);

/* Enqueue right child */


if (root->right)
Q.push(root->right); // NOTE: RIGHT CHILD IS ENQUEUED BEFORE LEFT

/* Enqueue left child */


if (root->left)
Q.push(root->left);
}

// Now pop all items from stack one by one and print them
while (S.empty() == false)
{
root = S.top();
cout << root->data << " ";
S.pop();
}
}

/* Helper function that allocates a new node with the


given data and NULL left and right pointers. */
node* newNode(int data)
{
node* temp = new node;
temp->data = data;
temp->left = NULL;
temp->right = NULL;

return (temp);
}

/* Driver program to test above functions*/

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->right->left = newNode(6);
root->right->right = newNode(7);

cout << "Level Order traversal of binary tree is \n";


reverseLevelOrder(root);

return 0;
}
Output:

LevelOrdertraversalofbinarytreeis
4567231
TimeComplexity:O(n)wherenisnumberofnodesinthebinarytree.

=======================================================================

Findapairwithgivensumina
BalancedBST
GivenaBalancedBinarySearchTreeandatargetsum,writeafunctionthatreturnstrueifthereisapair
withsumequalstotargetsum,otherwisereturnfalse.ExpectedtimecomplexityisO(n)andonlyO(Logn)
extraspacecanbeused.AnymodificationtoBinarySearchTreeisnotallowed.Notethatheightofa
BalancedBSTisalwaysO(Logn).


Thisproblemismainlyextensionofthepreviouspost.HerewearenotallowedtomodifytheBST.
TheBruteForceSolutionistoconsidereachpairinBSTandcheckwhetherthesumequalstoX.Thetime
complexityofthissolutionwillbeO(n^2).
ABetterSolutionistocreateanauxiliaryarrayandstoreInordertraversalofBSTinthearray.Thearray
willbesortedasInordertraversalofBSTalwaysproducessorteddata.OncewehavetheInordertraversal,
wecanpairinO(n)time(Seethisfordetails).ThissolutionworksinO(n)time,butrequiresO(n)auxiliary
space.
Aspaceoptimizedsolutionisdiscussedinpreviouspost.TheideawastofirstinplaceconvertBSTto
DoublyLinkedList(DLL),thenfindpairinsortedDLLinO(n)time.ThissolutiontakesO(n)timeand
O(Logn)extraspace,butitmodifiesthegivenBST.
ThesolutiondiscussedbelowtakesO(n)time,O(Logn)spaceanddoesntmodifyBST.Theideais
sameasfindingthepairinsortedarray(Seemethod1ofthisfordetails).WetraverseBSTinNormal
InorderandReverseInordersimultaneously.Inreverseinorder,westartfromtherightmostnodewhichis
themaximumvaluenode.Innormalinorder,westartfromtheleftmostnodewhichisminimumvaluenode.
Weaddsumofcurrentnodesinbothtraversalsandcomparethissumwithgiventargetsum.Ifthesumis
sameastargetsum,wereturntrue.Ifthesumismorethantargetsum,wemovetonextnodeinreverse
inordertraversal,otherwisewemovetonextnodeinnormalinordertraversal.Ifanyofthetraversalsis
finishedwithoutfindingapair,wereturnfalse.FollowingisC++implementationofthisapproach.
/* 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;
};

// A utility function to create a stack of given size


struct Stack* createStack(int size)
{
struct Stack* stack =
(struct Stack*) malloc(sizeof(struct Stack));
stack->size = size;
stack->top = -1;
stack->array =
(struct node**) malloc(stack->size * sizeof(struct node*));
return stack;
}

// BASIC OPERATIONS OF STACK


int isFull(struct Stack* stack)
{

return stack->top - 1 == stack->size; }

int isEmpty(struct Stack* stack)


{

return stack->top == -1;

void push(struct Stack* stack, struct node* node)


{
if (isFull(stack))
return;
stack->array[++stack->top] = node;

struct node* pop(struct Stack* stack)


{
if (isEmpty(stack))
return NULL;
return stack->array[stack->top--];
}

// 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;
}
}
}

// Find next node in REVERSE Inorder traversal. The only


// difference between above and below loop is, in below loop
// right subtree is traversed before left subtree
while (done2 == false)
{
if (curr2 != NULL)
{
push(s2, curr2);
curr2 = curr2->right;
}
else
{
if (isEmpty(s2))
done2 = 1;
else
{
curr2 = pop(s2);
val2 = curr2->val;
curr2 = curr2->left;
done2 = 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;
}

// If sum of current values is smaller, then move to next node in


// normal inorder traversal
else if ((val1 + val2) < target)
done1 = false;

// If sum of current values is greater, then move to next node in


// reverse inorder traversal
else if ((val1 + val2) > target)
done2 = false;

// If any of the inorder traversals is over, then there is no pair


// so return false
if (val1 >= val2)
return false;
}
}

// A utility function to create BST node


struct node * NewNode(int val)
{
struct node *tmp = (struct node *)malloc(sizeof(struct node));
tmp->val = val;
tmp->right = tmp->left =NULL;
return tmp;
}

// Driver program to test above functions


int main()
{
/*
15
/
10
/\
8 12

\
20
/ \
16 25*/

struct node *root = NewNode(15);


root->left = NewNode(10);
root->right = NewNode(20);
root->left->left = NewNode(8);
root->left->right = NewNode(12);
root->right->left = NewNode(16);
root->right->right = NewNode(25);

int target = 33;


if (isPairPresent(root, target) == false)
printf("\n No such values are found\n");

getchar();
return 0;
}
Output:

PairFound:8+25=33
=======================================================================

FindifthereisatripletinaBalanced
BSTthataddstozero
GivenaBalancedBinarySearchTree(BST),writeafunctionisTripletPresent()thatreturnstrueifthereisa
tripletingivenBSTwithsumequalsto0,otherwisereturnsfalse.ExpectedtimecomplexityisO(n^2)and

onlyO(Logn)extraspacecanbeused.YoucanmodifygivenBinarySearchTree.Notethatheightofa
BalancedBSTisalwaysO(Logn)
Forexample,isTripletPresent()shouldreturntrueforfollowingBSTbecausethereisatripletwithsum0,the
tripletis{13,6,7}.

TheBruteForceSolutionistoconsidereachtripletinBSTandcheckwhetherthesumaddsuptozero.
ThetimecomplexityofthissolutionwillbeO(n^3).
ABetterSolutionistocreateanauxiliaryarrayandstoreInordertraversalofBSTinthearray.Thearray
willbesortedasInordertraversalofBSTalwaysproducessorteddata.OncewehavetheInordertraversal,
wecanusemethod2ofthisposttofindthetripletwithsumequalsto0.ThissolutionworksinO(n^2)time,
butrequiresO(n)auxiliaryspace.
FollowingisthesolutionthatworksinO(n^2)timeandusesO(Logn)extraspace:
1)ConvertgivenBSTtoDoublyLinkedList(DLL)
2)NowiteratethrougheverynodeofDLLandifthekeyofnodeisnegative,thenfindapairinDLLwithsum
equaltokeyofcurrentnodemultipliedby1.Tofindthepair,wecanusetheapproachusedin
hasArrayTwoCandidates()inmethod1ofthispost.
// A C++ program to check if there is a triplet with sum equal to 0 in
// a given BST
#include<stdio.h>

// A BST node has key, and left and right pointers


struct node

{
int key;
struct node *left;
struct node *right;
};

// A function to convert given BST to Doubly Linked List. left pointer is used
// as previous pointer and right pointer is used as next pointer. The function
// sets *head to point to first and *tail to point to last node of converted DLL
void convertBSTtoDLL(node* root, node** head, node** tail)
{
// Base case
if (root == NULL)
return;

// First convert the left subtree


if (root->left)
convertBSTtoDLL(root->left, head, tail);

// Then change left of current root as last node of left subtree


root->left = *tail;

// 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;

// Finally, convert right subtree


if (root->right)
convertBSTtoDLL(root->right, head, tail);
}

// 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;
}

// The main function that returns true if there is a 0 sum triplet in


// BST otherwise returns false
bool isTripletPresent(node *root)
{
// Check if the given BST is empty
if (root == NULL)
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;
}

// If we reach here, then there was no 0 sum triplet


return false;
}

// 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;
}

// A utility function to insert a given key to BST


node* insert(node* root, int key)
{
if (root == NULL)
return newNode(key);
if (root->key > key)
root->left = insert(root->left, key);
else
root->right = insert(root->right, key);
return root;
}

// Driver program to test above functions


int main()
{
node* root = NULL;
root = insert(root, 6);

root = insert(root, -13);


root = insert(root, 14);
root = insert(root, -8);
root = insert(root, 15);
root = insert(root, 13);
root = insert(root, 7);
if (isTripletPresent(root))
printf("Present");
else
printf("Not Present");
return 0;
}
Output:

Present
NotethattheabovesolutionmodifiesgivenBST.
TimeComplexity:TimetakentoconvertBSTtoDLLisO(n)andtimetakentofindtripletinDLLisO(n^2).
AuxiliarySpace:Theauxiliaryspaceisneededonlyforfunctioncallstackinrecursivefunction
convertBSTtoDLL().Sincegiventreeisbalanced(heightisO(Logn)),thenumberoffunctionsincallstack
willneverbemorethanO(Logn).

=======================================================================

IterativePostorderTraversal|Set2
(UsingOneStack)
Wehavediscussedasimpleiterativepostordertraversalusingtwostacksinthepreviouspost.Inthispost,
anapproachwithonlyonestackisdiscussed.
Theideaistomovedowntoleftmostnodeusingleftpointer.Whilemovingdown,pushrootandrootsright
childtostack.Oncewereachleftmostnode,printitifitdoesnthavearightchild.Ifithasarightchild,then
changerootsothattherightchildisprocessedbefore.
Followingisdetailedalgorithm.

1.1Createanemptystack
2.1DofollowingwhilerootisnotNULL
a)Pushroot'srightchildandthenroottostack.
b)Setrootasroot'sleftchild.
2.2Popanitemfromstackandsetitasroot.

a)Ifthepoppeditemhasarightchildandtherightchild
isattopofstack,thenremovetherightchildfromstack,
pushtherootbackandsetrootasroot'srightchild.
b)Elseprintroot'sdataandsetrootasNULL.
2.3Repeatsteps2.1and2.2whilestackisnotempty.
Letusconsiderthefollowingtree

Followingarethestepstoprintpostordertraversaloftheabovetreeusingonestack.

1.Rightchildof1exists.
Push3tostack.Push1tostack.Movetoleftchild.
Stack:3,1

2.Rightchildof2exists.
Push5tostack.Push2tostack.Movetoleftchild.
Stack:3,1,5,2

3.Rightchildof4doesn'texist.'
Push4tostack.Movetoleftchild.
Stack:3,1,5,2,4

4.CurrentnodeisNULL.
Pop4fromstack.Rightchildof4doesn'texist.
Print4.SetcurrentnodetoNULL.
Stack:3,1,5,2

5.CurrentnodeisNULL.

Pop2fromstack.Sincerightchildof2equalsstacktopelement,
pop5fromstack.Nowpush2tostack.
Movecurrentnodetorightchildof2i.e.5
Stack:3,1,2

6.Rightchildof5doesn'texist.Push5tostack.Movetoleftchild.
Stack:3,1,2,5

7.CurrentnodeisNULL.Pop5fromstack.Rightchildof5doesn'texist.
Print5.SetcurrentnodetoNULL.
Stack:3,1,2

8.CurrentnodeisNULL.Pop2fromstack.
Rightchildof2isnotequaltostacktopelement.
Print2.SetcurrentnodetoNULL.
Stack:3,1

9.CurrentnodeisNULL.Pop1fromstack.
Sincerightchildof1equalsstacktopelement,pop3fromstack.
Nowpush1tostack.Movecurrentnodetorightchildof1i.e.3
Stack:1

10.RepeatthesameasabovestepsandPrint6,7and3.
Pop1andPrint1.
// C program for iterative postorder traversal using one stack
#include <stdio.h>
#include <stdlib.h>

// Maximum stack size


#define MAX_SIZE 100

// A tree node
struct Node
{
int data;
struct Node *left, *right;
};

// Stack type
struct Stack
{
int size;
int top;
struct Node* *array;
};

// A utility function to create a new tree node


struct Node* newNode(int data)
{
struct Node* node = (struct Node*) malloc(sizeof(struct Node));
node->data = data;
node->left = node->right = NULL;
return node;
}

// A utility function to create a stack of given size


struct Stack* createStack(int size)
{
struct Stack* stack = (struct Stack*) malloc(sizeof(struct Stack));
stack->size = size;
stack->top = -1;
stack->array = (struct Node**) malloc(stack->size * sizeof(struct Node*));
return stack;
}

// BASIC OPERATIONS OF STACK


int isFull(struct Stack* stack)
{ return stack->top - 1 == stack->size; }

int isEmpty(struct Stack* stack)


{ return stack->top == -1; }

void push(struct Stack* stack, struct Node* node)


{

if (isFull(stack))
return;
stack->array[++stack->top] = node;
}

struct Node* pop(struct Stack* stack)


{
if (isEmpty(stack))
return NULL;
return stack->array[stack->top--];
}

struct Node* peek(struct Stack* stack)


{
if (isEmpty(stack))
return NULL;
return stack->array[stack->top];
}

// An iterative function to do postorder traversal of a given binary tree


void postOrderIterative(struct Node* root)
{
// Check for empty tree
if (root == NULL)
return;

struct Stack* stack = createStack(MAX_SIZE);


do
{
// Move to leftmost node
while (root)
{
// Push root's right child and then root to stack.
if (root->right)
push(stack, root->right);
push(stack, root);

// Set root as root's left child


root = root->left;
}

// Pop an item from stack and set it as root


root = pop(stack);

// 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));
}

// Driver program to test above functions


int main()
{
// Let us construct the tree shown in above figure
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->left = newNode(6);
root->right->right = newNode(7);

postOrderIterative(root);

return 0;
}
Output:

4526731

=======================================================================

IterativePostorderTraversal|Set1
(UsingTwoStacks)
Wehavediscussediterativeinorderanditerativepreordertraversals.Inthispost,iterativepostorder
traversalisdiscussedwhichismorecomplexthantheothertwotraversals(duetoitsnatureofnontail
recursion,thereisanextrastatementafterthefinalrecursivecalltoitself).Thepostordertraversalcan
easilybedoneusingtwostacksthough.Theideaistopushreversepostordertraversaltoastack.Oncewe
havereversepostordertraversalinastack,wecanjustpopallitemsonebyonefromthestackandprint
them,thisorderofprintingwillbeinpostorderbecauseofLIFOpropertyofstacks.Nowthequestionis,how
togetreversepostorderelementsinastacktheotherstackisusedforthispurpose.Forexample,inthe
followingtree,weneedtoget1,3,7,6,2,5,4inastack.Iftakeacloserlookatthissequence,wecan
observethatthissequenceisverysimilartopreordertraversal.Theonlydifferenceisrightchildisvisited
beforeleftchildandthereforesequenceisrootrightleftinsteadofrootleftright.Sowecandosomething
likeiterativepreordertraversalwithfollowingdifferences.
a)Insteadofprintinganitem,wepushittoastack.
b)Wepushleftsubtreebeforerightsubtree.
Followingisthecompletealgorithm.Afterstep2,wegetreversepostordertraversalinsecondstack.We
usefirststacktogetthisorder.

1.Pushroottofirststack.
2.Loopwhilefirststackisnotempty
2.1Popanodefromfirststackandpushittosecondstack
2.2Pushleftandrightchildrenofthepoppednodetofirststack
3.Printcontentsofsecondstack
Letusconsiderthefollowingtree


Followingarethestepstoprintpostordertraversaloftheabovetreeusingtwostacks.

1.Push1tofirststack.
Firststack:1
Secondstack:Empty

2.Pop1fromfirststackandpushittosecondstack.
Pushleftandrightchildrenof1tofirststack
Firststack:2,3
Secondstack:1

3.Pop3fromfirststackandpushittosecondstack.
Pushleftandrightchildrenof3tofirststack
Firststack:2,6,7
Secondstack:1,3

4.Pop7fromfirststackandpushittosecondstack.
Firststack:2,6
Secondstack:1,3,7

5.Pop6fromfirststackandpushittosecondstack.
Firststack:2
Secondstack:1,3,7,6

6.Pop2fromfirststackandpushittosecondstack.
Pushleftandrightchildrenof2tofirststack

Firststack:4,5
Secondstack:1,3,7,6,2

7.Pop5fromfirststackandpushittosecondstack.
Firststack:4
Secondstack:1,3,7,6,2,5

8.Pop4fromfirststackandpushittosecondstack.
Firststack:Empty
Secondstack:1,3,7,6,2,5,4

Thealgorithmstopssincethereisnomoreiteminfirststack.
Observethatcontentofsecondstackisinpostorderfashion.Printthem.
FollowingisCimplementationofiterativepostordertraversalusingtwostacks.
#include <stdio.h>
#include <stdlib.h>

// Maximum stack size


#define MAX_SIZE 100

// A tree node
struct Node
{
int data;
struct Node *left, *right;
};

// Stack type
struct Stack
{
int size;
int top;
struct Node* *array;
};

// A utility function to create a new tree node


struct Node* newNode(int data)

{
struct Node* node = (struct Node*) malloc(sizeof(struct Node));
node->data = data;
node->left = node->right = NULL;
return node;
}

// A utility function to create a stack of given size


struct Stack* createStack(int size)
{
struct Stack* stack =
(struct Stack*) malloc(sizeof(struct Stack));
stack->size = size;
stack->top = -1;
stack->array =
(struct Node**) malloc(stack->size * sizeof(struct Node*));
return stack;
}

// BASIC OPERATIONS OF STACK


int isFull(struct Stack* stack)
{ return stack->top - 1 == stack->size; }

int isEmpty(struct Stack* stack)


{ return stack->top == -1; }

void push(struct Stack* stack, struct Node* node)


{
if (isFull(stack))
return;
stack->array[++stack->top] = node;
}

struct Node* pop(struct Stack* stack)


{
if (isEmpty(stack))
return NULL;

return stack->array[stack->top--];
}

// An iterative function to do post order traversal of a given binary tree


void postOrderIterative(struct Node* root)
{
// Create two stacks
struct Stack* s1 = createStack(MAX_SIZE);
struct Stack* s2 = createStack(MAX_SIZE);

// push root to first stack


push(s1, root);
struct Node* node;

// Run while first stack is not empty


while (!isEmpty(s1))
{
// Pop an item from s1 and push it to s2
node = pop(s1);
push(s2, node);

// Push left and right children of removed item to s1


if (node->left)
push(s1, node->left);
if (node->right)
push(s1, node->right);
}

// Print all elements of second stack


while (!isEmpty(s2))
{
node = pop(s2);
printf("%d ", node->data);
}
}

// Driver program to test above functions

int main()
{
// Let us construct the tree shown in above figure
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->left = newNode(6);
root->right->right = newNode(7);

postOrderIterative(root);

return 0;
}
Output:

4526731
=======================================================================

DynamicProgramming|Set26
(LargestIndependentSetProblem)
GivenaBinaryTree,findsizeoftheLargestIndependentSet(LIS)init.Asubsetofalltreenodesisan
independentsetifthereisnoedgebetweenanytwonodesofthesubset.
Forexample,considerthefollowingbinarytree.Thelargestindependentset(LIS)is{10,40,60,70,80}and
sizeoftheLISis5.


ADynamicProgrammingsolutionsolvesagivenproblemusingsolutionsofsubproblemsinbottomup
manner.Canthegivenproblembesolvedusingsolutionstosubproblems?Ifyes,thenwhatarethe
subproblems?Canwefindlargestindependentsetsize(LISS)foranodeXifweknowLISSforall
descendantsofX?IfanodeisconsideredaspartofLIS,thenitschildrencannotbepartofLIS,butits
grandchildrencanbe.Followingisoptimalsubstructureproperty.
1)OptimalSubstructure:
LetLISS(X)indicatessizeoflargestindependentsetofatreewithrootX.

LISS(X)=MAX{(1+sumofLISSforallgrandchildrenofX),
(sumofLISSforallchildrenofX)}

Theideaissimple,therearetwopossibilitiesforeverynodeX,eitherXisamemberofthesetornota
member.IfXisamember,thenthevalueofLISS(X)is1plusLISSofallgrandchildren.IfXisnota
member,thenthevalueissumofLISSofallchildren.
2)OverlappingSubproblems
Followingisrecursiveimplementationthatsimplyfollowstherecursivestructurementionedabove.
// A naive recursive implementation of Largest Independent Set problem
#include <stdio.h>
#include <stdlib.h>

// A utility function to find max of two integers


int max(int x, int y) { return (x > y)? x: y; }

/* A binary tree node has data, pointer to left child and a pointer to
right child */

struct node
{
int data;
struct node *left, *right;
};

// The function returns size of the largest independent set in a given


// binary tree
int LISS(struct node *root)
{
if (root == NULL)
return 0;

// Caculate size excluding the current node


int size_excl = LISS(root->left) + LISS(root->right);

// Calculate size including the current node


int size_incl = 1;
if (root->left)
size_incl += LISS(root->left->left) + LISS(root->left->right);
if (root->right)
size_incl += LISS(root->right->left) + LISS(root->right->right);

// Return the maximum of two sizes


return max(size_incl, size_excl);
}

// A utility function to create a node


struct node* newNode( int data )
{
struct node* temp = (struct node *) malloc( sizeof(struct node) );
temp->data = data;
temp->left = temp->right = NULL;
return temp;
}

// Driver program to test above functions


int main()
{
// Let us construct the tree given in the above diagram
struct node *root

= newNode(20);

root->left

= newNode(8);

root->left->left

= newNode(4);

root->left->right

= newNode(12);

root->left->right->left

= newNode(10);

root->left->right->right = newNode(14);
root->right

= newNode(22);

root->right->right

= newNode(25);

printf ("Size of the Largest Independent Set is %d ", LISS(root));

return 0;
}
Output:

SizeoftheLargestIndependentSetis5
Timecomplexityoftheabovenaiverecursiveapproachisexponential.Itshouldbenotedthattheabove
functioncomputesthesamesubproblemsagainandagain.Forexample,LISSofnodewithvalue50is
evaluatedfornodewithvalues10and20as50isgrandchildof10andchildof20.
Sincesamesuproblemsarecalledagain,thisproblemhasOverlappingSubprolemsproperty.SoLISS
problemhasbothproperties(seethisandthis)ofadynamicprogrammingproblem.Likeothertypical
DynamicProgramming(DP)problems,recomputationsofsamesubproblemscanbeavoidedbystoringthe
solutionstosubproblemsandsolvingproblemsinbottomupmanner.
FollowingisCimplementationofDynamicProgrammingbasedsolution.Inthefollowingsolution,an
additionalfieldlissisaddedtotreenodes.Theinitialvalueoflississetas0forallnodes.Therecursive
functionLISS()calculateslissforanodeonlyifitisnotalreadyset.
/* Dynamic programming based program for Largest Independent Set problem */
#include <stdio.h>
#include <stdlib.h>

// A utility function to find max of two integers


int max(int x, int y) { return (x > y)? x: y; }

/* 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;
};

// A memoization function returns size of the largest independent set in


// a given binary tree
int LISS(struct node *root)
{
if (root == NULL)
return 0;

if (root->liss)
return root->liss;

if (root->left == NULL && root->right == NULL)


return (root->liss = 1);

// Caculate size excluding the current node


int liss_excl = LISS(root->left) + LISS(root->right);

// Calculate size including the current node


int liss_incl = 1;
if (root->left)
liss_incl += LISS(root->left->left) + LISS(root->left->right);
if (root->right)
liss_incl += LISS(root->right->left) + LISS(root->right->right);

// Return the maximum of two sizes


root->liss = max(liss_incl, liss_excl);

return root->liss;
}

// A utility function to create a node


struct node* newNode(int data)
{
struct node* temp = (struct node *) malloc( sizeof(struct node) );
temp->data = data;
temp->left = temp->right = NULL;
temp->liss = 0;
return temp;
}

// Driver program to test above functions


int main()
{
// Let us construct the tree given in the above diagram
struct node *root

= newNode(20);

root->left

= newNode(8);

root->left->left

= newNode(4);

root->left->right

= newNode(12);

root->left->right->left

= newNode(10);

root->left->right->right = newNode(14);
root->right

= newNode(22);

root->right->right

= newNode(25);

printf ("Size of the Largest Independent Set is %d ", LISS(root));

return 0;
}
Output

SizeoftheLargestIndependentSetis5
TimeComplexity:O(n)wherenisthenumberofnodesingivenBinarytree.
Followingextensionstoabovesolutioncanbetriedasanexercise.
1)Extendtheabovesolutionfornarytree.
2)Theabovesolutionmodifiesthegiventreestructurebyaddinganadditionalfieldlisstotreenodes.
Extendthesolutionsothatitdoesntmodifythetreestructure.
3)TheabovesolutiononlyreturnssizeofLIS,itdoesntprintelementsofLIS.Extendthesolutiontoprintall
nodesthatarepartofLIS.

=======================================================================

SegmentTree|Set2(Range
MinimumQuery)
Wehaveintroducedsegmenttreewithasimpleexampleinthepreviouspost.Inthispost,RangeMinimum
QueryproblemisdiscussedasanotherexamplewhereSegmentTreecanbeused.Followingisproblem
statement.
Wehaveanarrayarr[0...n1].Weshouldbeabletoefficientlyfindtheminimumvaluefromindexqs
(querystart)toqe(queryend)where0<=qs<=qe<=n1.Thearrayisstatic(elementsarenotdeletedand
insertedduringtheseriesofqueries).
Asimplesolutionistorunaloopfromqstoqeandfindminimumelementingivenrange.Thissolution
takesO(n)timeinworstcase.
Anothersolutionistocreatea2Darraywhereanentry[i,j]storestheminimumvalueinrangearr[i..j].
MinimumofagivenrangecannowbecalculatedinO(1)time,butpreprocessingtakesO(n^2)time.Also,
thisapproachneedsO(n^2)extraspacewhichmaybecomehugeforlargeinputarrays.
Segmenttreecanbeusedtodopreprocessingandqueryinmoderatetime.Withsegmenttree,
preprocessingtimeisO(n)andtimetoforrangeminimumqueryisO(Logn).Theextraspacerequiredis
O(n)tostorethesegmenttree.
RepresentationofSegmenttrees
1.LeafNodesaretheelementsoftheinputarray.
2.Eachinternalnoderepresentsminimumofallleavesunderit.
AnarrayrepresentationoftreeisusedtorepresentSegmentTrees.Foreachnodeatindexi,theleftchildis
atindex2*i+1,rightchildat2*i+2andtheparentisat


ConstructionofSegmentTreefromgivenarray
Westartwithasegmentarr[0...n1].andeverytimewedividethecurrentsegmentintotwohalves(ifithas
notyetbecomeasegmentoflength1),andthencallthesameprocedureonbothhalves,andforeachsuch
segment,westoretheminimumvalueinasegmenttreenode.
Alllevelsoftheconstructedsegmenttreewillbecompletelyfilledexceptthelastlevel.Also,thetreewillbe
aFullBinaryTreebecausewealwaysdividesegmentsintwohalvesateverylevel.Sincetheconstructed
treeisalwaysfullbinarytreewithnleaves,therewillben1internalnodes.Sototalnumberofnodeswillbe
2*n1.
Heightofthesegmenttreewillbe

.Sincethetreeisrepresentedusingarrayandrelation

betweenparentandchildindexesmustbemaintained,sizeofmemoryallocatedforsegmenttreewillbe
.
Queryforminimumvalueofgivenrange
Oncethetreeisconstructed,howtodorangeminimumqueryusingtheconstructedsegmenttree.
Followingisalgorithmtogettheminimum.

//qs>querystartindex,qe>queryendindex
intRMQ(node,qs,qe)
{

ifrangeofnodeiswithinqsandqe
returnvalueinnode
elseifrangeofnodeiscompletelyoutsideqsandqe
returnINFINITE
else
returnmin(RMQ(node'sleftchild,qs,qe),RMQ(node'srightchild,qs,qe))
}
Implementation:
// Program for range minimum query using segment tree
#include <stdio.h>
#include <math.h>
#include <limits.h>

// A utility function to get minimum of two numbers


int minVal(int x, int y) { return (x < y)? x: y; }

// A utility function to get the middle index from corner indexes.


int getMid(int s, int e) { return s + (e -s)/2; }

/* A recursive function to get the minimum value in a given range of array


indexes. The following are parameters for this function.

st--> Pointer to segment tree


index --> Index of current node in the segment tree. Initially 0 is
passed as root is always at index 0
ss & se --> Starting and ending indexes of the segment represented by
current node, i.e., st[index]
qs & qe --> Starting and ending indexes of query range */
int RMQUtil(int *st, int ss, int se, int qs, int qe, int index)
{
// If segment of this node is a part of given range, then return the
// min of the segment
if (qs <= ss && qe >= se)
return st[index];

// If segment of this node is outside the given range


if (se < qs || ss > qe)

return INT_MAX;

// If a part of this segment overlaps with the given range


int mid = getMid(ss, se);
return minVal(RMQUtil(st, ss, mid, qs, qe, 2*index+1),
RMQUtil(st, mid+1, se, qs, qe, 2*index+2));
}

// Return minimum of elements in range from index qs (quey start) to


// qe (query end). It mainly uses RMQUtil()
int RMQ(int *st, int n, int qs, int qe)
{
// Check for erroneous input values
if (qs < 0 || qe > n-1 || qs > qe)
{
printf("Invalid Input");
return -1;
}

return RMQUtil(st, 0, n-1, qs, qe, 0);


}

// A recursive function that constructs Segment Tree for array[ss..se].


// si is index of current node in segment tree st
int constructSTUtil(int arr[], int ss, int se, int *st, int si)
{
// If there is one element in array, store it in current node of
// segment tree and return
if (ss == se)
{
st[si] = arr[ss];
return arr[ss];
}

// 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];

// Fill the allocated memory st


constructSTUtil(arr, 0, n-1, st, 0);

// Return the constructed segment tree


return st;
}

// Driver program to test above functions


int main()
{
int arr[] = {1, 3, 2, 7, 9, 11};
int n = sizeof(arr)/sizeof(arr[0]);

// Build segment tree from given array


int *st = constructST(arr, n);

int qs = 1; // Starting index of query range


int qe = 5; // Ending index of query range

// Print minimum value in arr[qs..qe]


printf("Minimum of values in range [%d, %d] is = %d\n",
qs, qe, RMQ(st, n, qs, qe));

return 0;
}
Output:

Minimumofvaluesinrange[1,5]is=2
TimeComplexity:
TimeComplexityfortreeconstructionisO(n).Therearetotal2n1nodes,andvalueofeverynodeis
calculatedonlyonceintreeconstruction.
TimecomplexitytoqueryisO(Logn).Toqueryarangeminimum,weprocessatmosttwonodesatevery
levelandnumberoflevelsisO(Logn).

=======================================================================

SegmentTree|Set1(Sumofgiven
range)
LetusconsiderthefollowingproblemtounderstandSegmentTrees.
Wehaveanarrayarr[0...n1].Weshouldbeableto
1Findthesumofelementsfromindexltorwhere0<=l<=r<=n1
2Changevalueofaspecifiedelementofthearrayarr[i]=xwhere0<=i<=n1.
Asimplesolutionistorunaloopfromltorandcalculatesumofelementsingivenrange.Toupdatea
value,simplydoarr[i]=x.ThefirstoperationtakesO(n)timeandsecondoperationtakesO(1)time.
Anothersolutionistocreateanotherarrayandstoresumfromstarttoiattheithindexinthisarray.Sum
ofagivenrangecannowbecalculatedinO(1)time,butupdateoperationtakesO(n)timenow.Thisworks
wellifthenumberofqueryoperationsarelargeandveryfewupdates.
Whatifthenumberofqueryandupdatesareequal?CanweperformboththeoperationsinO(logn)
timeoncegiventhearray?WecanuseaSegmentTreetodobothoperationsinO(Logn)time.
RepresentationofSegmenttrees
1.LeafNodesaretheelementsoftheinputarray.
2.Eachinternalnoderepresentssomemergingoftheleafnodes.Themergingmaybedifferentfordifferent
problems.Forthisproblem,mergingissumofleavesunderanode.

AnarrayrepresentationoftreeisusedtorepresentSegmentTrees.Foreachnodeatindexi,theleftchildis
atindex2*i+1,rightchildat2*i+2andtheparentisat

ConstructionofSegmentTreefromgivenarray
Westartwithasegmentarr[0...n1].andeverytimewedividethecurrentsegmentintotwohalves(ifithas
notyetbecomeasegmentoflength1),andthencallthesameprocedureonbothhalves,andforeachsuch
segmentwestorethesumincorrespondingnode.
Alllevelsoftheconstructedsegmenttreewillbecompletelyfilledexceptthelastlevel.Also,thetreewillbe
aFullBinaryTreebecausewealwaysdividesegmentsintwohalvesateverylevel.Sincetheconstructed
treeisalwaysfullbinarytreewithnleaves,therewillben1internalnodes.Sototalnumberofnodeswillbe
2*n1.
Heightofthesegmenttreewillbe

.Sincethetreeisrepresentedusingarrayandrelation

betweenparentandchildindexesmustbemaintained,sizeofmemoryallocatedforsegmenttreewillbe
.
QueryforSumofgivenrange
Oncethetreeisconstructed,howtogetthesumusingtheconstructedsegmenttree.Followingisalgorithm
togetthesumofelements.

intgetSum(node,l,r)
{
ifrangeofnodeiswithinlandr
returnvalueinnode
elseifrangeofnodeiscompletelyoutsidelandr
return0
else
returngetSum(node'sleftchild,l,r)+
getSum(node'srightchild,l,r)
}
Updateavalue
Liketreeconstructionandqueryoperations,updatecanalsobedonerecursively.Wearegivenanindex
whichneedstoupdated.Letdiffbethevaluetobeadded.Westartfromrootofthesegmenttree,andadd
difftoallnodeswhichhavegivenindexintheirrange.Ifanodedoesnthavegivenindexinitsrange,we
dontmakeanychangestothatnode.
Implementation:
Followingisimplementationofsegmenttree.Theprogramimplementsconstructionofsegmenttreeforany
givenarray.Italsoimplementsqueryandupdateoperations.
// Program to show segment tree operations like construction, query and update
#include <stdio.h>
#include <math.h>

// A utility function to get the middle index from corner indexes.


int getMid(int s, int e) { return s + (e -s)/2; }

/* A recursive function to get the sum of values in given range of the array.
The following are parameters for this function.

st--> Pointer to segment tree


index --> Index of current node in the segment tree. Initially 0 is
passed as root is always at index 0
ss & se --> Starting and ending indexes of the segment represented by
current node, i.e., st[index]
qs & qe --> Starting and ending indexes of query range */
int getSumUtil(int *st, int ss, int se, int qs, int qe, int index)
{
// If segment of this node is a part of given range, then return the

// sum of the segment


if (qs <= ss && qe >= se)
return st[index];

// If segment of this node is outside the given range


if (se < qs || ss > qe)
return 0;

// If a part of this segment overlaps with the given range


int mid = getMid(ss, se);
return getSumUtil(st, ss, mid, qs, qe, 2*index+1) +
getSumUtil(st, mid+1, se, qs, qe, 2*index+2);
}

/* A recursive function to update the nodes which have the given index in
their range. The following are parameters
st, index, 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 index)
{
// 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[index] = st[index] + diff;
if (se != ss)
{
int mid = getMid(ss, se);
updateValueUtil(st, ss, mid, i, diff, 2*index + 1);
updateValueUtil(st, mid+1, se, i, diff, 2*index + 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;
}

// Get the difference between new value and old value


int diff = new_val - arr[i];

// Update the value in array


arr[i] = new_val;

// Update the values of nodes in segment tree


updateValueUtil(st, 0, n-1, i, diff, 0);
}

// Return sum of elements in range from index qs (quey start) to


// qe (query end). It mainly uses getSumUtil()
int getSum(int *st, int n, int qs, int qe)
{
// Check for erroneous input values
if (qs < 0 || qe > n-1 || qs > qe)
{
printf("Invalid Input");
return -1;
}

return getSumUtil(st, 0, n-1, qs, qe, 0);


}

// A recursive function that constructs Segment Tree for array[ss..se].


// si is index of current node in segment tree st
int constructSTUtil(int arr[], int ss, int se, int *st, int si)

{
// If there is one element in array, store it in current node of
// segment tree and return
if (ss == se)
{
st[si] = arr[ss];
return arr[ss];
}

// 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];
}

/* 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];

// Fill the allocated memory st


constructSTUtil(arr, 0, n-1, st, 0);

// Return the constructed segment tree


return st;
}

// Driver program to test above functions


int main()
{

int arr[] = {1, 3, 5, 7, 9, 11};


int n = sizeof(arr)/sizeof(arr[0]);

// Build segment tree from given array


int *st = constructST(arr, n);

// Print sum of values in array from index 1 to 3


printf("Sum of values in given range = %d\n", getSum(st, n, 1, 3));

// Update: set arr[1] = 10 and update corresponding segment


// tree nodes
updateValue(arr, st, n, 1, 10);

// Find sum after the value is updated


printf("Updated sum of values in given range = %d\n",
getSum(st, n, 1, 3));

return 0;
}
Output:

Sumofvaluesingivenrange=15
Updatedsumofvaluesingivenrange=22
TimeComplexity:
TimeComplexityfortreeconstructionisO(n).Therearetotal2n1nodes,andvalueofeverynodeis
calculatedonlyonceintreeconstruction.
TimecomplexitytoqueryisO(Logn).Toqueryasum,weprocessatmostfournodesateveryleveland
numberoflevelsisO(Logn).
ThetimecomplexityofupdateisalsoO(Logn).Toupdatealeafvalue,weprocessonenodeateverylevel
andnumberoflevelsisO(Logn).

=======================================================================

TernarySearchTree
Aternarysearchtreeisaspecialtriedatastructurewherethechildnodesofastandardtrieareorderedas
abinarysearchtree.

Representationofternarysearchtrees:
Unliketrie(standard)datastructurewhereeachnodecontains26pointersforitschildren,eachnodeina
ternarysearchtreecontainsonly3pointers:
1.Theleftpointerpointstothenodewhosevalueislessthanthevalueinthecurrentnode.
2.Theequalpointerpointstothenodewhosevalueisequaltothevalueinthecurrentnode.
3.Therightpointerpointstothenodewhosevalueisgreaterthanthevalueinthecurrentnode.
Apartfromabovethreepointers,eachnodehasafieldtoindicatedata(characterincaseofdictionary)and
anotherfieldtomarkendofastring.
So,moreorlessitissimilartoBSTwhichstoresdatabasedonsomeorder.However,datainaternary
searchtreeisdistributedoverthenodes.e.g.Itneeds4nodestostorethewordGeek.
Belowfigureshowshowexactlythewordsinaternarysearchtreearestored?

Oneoftheadvantageofusingternarysearchtreesovertriesisthatternarysearchtreesareamorespace
efficient(involveonlythreepointerspernodeascomparedto26instandardtries).Further,ternarysearch
treescanbeusedanytimeahashtablewouldbeusedtostorestrings.
Triesaresuitablewhenthereisaproperdistributionofwordsoverthealphabetssothatspacesareutilized
mostefficiently.Otherwiseternarysearchtreesarebetter.Ternarysearchtreesareefficienttouse(interms
ofspace)whenthestringstobestoredshareacommonprefix.
Applicationsofternarysearchtrees:
1.TernarysearchtreesareefficientforquerieslikeGivenaword,findthenextwordin
dictionary(nearneighborlookups)orFindalltelephonenumbersstartingwith9342ortypingfewstarting
charactersinawebbrowserdisplaysallwebsitenameswiththisprefix(Autocompletefeature).

2.Usedinspellchecks:Ternarysearchtreescanbeusedasadictionarytostoreallthewords.Oncethe
wordistypedinaneditor,thewordcanbeparallelysearchedintheternarysearchtreetocheckforcorrect
spelling.
Implementation:
FollowingisCimplementationofternarysearchtree.Theoperationsimplementedare,search,insertand
traversal.
// C program to demonstrate Ternary Search Tree (TST) insert, travese
// and search operations
#include <stdio.h>
#include <stdlib.h>
#define MAX 50

// A node of ternary search tree


struct Node
{
char data;

// True if this character is last character of one of the words


unsigned isEndOfString: 1;

struct Node *left, *eq, *right;


};

// A utility function to create a new ternary search tree node


struct Node* newNode(char data)
{
struct Node* temp = (struct Node*) malloc(sizeof( struct Node ));
temp->data = data;
temp->isEndOfString = 0;
temp->left = temp->eq = temp->right = NULL;
return temp;
}

// Function to insert a new word in a Ternary Search Tree


void insert(struct Node** root, char *word)
{
// Base Case: Tree is empty

if (!(*root))
*root = newNode(*word);

// If current character of word is smaller than root's character,


// then insert this word in left subtree of root
if ((*word) < (*root)->data)
insert(&( (*root)->left ), word);

// If current character of word is greate than root's character,


// then insert this word in right subtree of root
else if ((*word) > (*root)->data)
insert(&( (*root)->right ), word);

// If current character of word is same as root's character,


else
{
if (*(word+1))
insert(&( (*root)->eq ), word+1);

// the last character of the word


else
(*root)->isEndOfString = 1;
}
}

// A recursive function to traverse Ternary Search Tree


void traverseTSTUtil(struct Node* root, char* buffer, int depth)
{
if (root)
{
// First traverse the left subtree
traverseTSTUtil(root->left, buffer, depth);

// Store the character of this node


buffer[depth] = root->data;
if (root->isEndOfString)
{

buffer[depth+1] = '\0';
printf( "%s\n", buffer);
}

// Traverse the subtree using equal pointer (middle subtree)


traverseTSTUtil(root->eq, buffer, depth + 1);

// Finally Traverse the right subtree


traverseTSTUtil(root->right, buffer, depth);
}
}

// The main function to traverse a Ternary Search Tree.


// It mainly uses traverseTSTUtil()
void traverseTST(struct Node* root)
{
char buffer[MAX];
traverseTSTUtil(root, buffer, 0);
}

// Function to search a given word in TST


int searchTST(struct Node *root, char *word)
{
if (!root)
return 0;

if (*word < (root)->data)


return searchTST(root->left, word);

else if (*word > (root)->data)


return searchTST(root->right, word);

else
{
if (*(word+1) == '\0')
return root->isEndOfString;

return searchTST(root->eq, word+1);


}
}

// Driver program to test above functions


int main()
{
struct Node *root = NULL;

insert(&root, "cat");
insert(&root, "cats");
insert(&root, "up");
insert(&root, "bug");

printf("Following is traversal of ternary search tree\n");


traverseTST(root);

printf("\nFollowing are search results for cats, bu and cat respectively\n");


searchTST(root, "cats")? printf("Found\n"): printf("Not Found\n");
searchTST(root, "bu")?

printf("Found\n"): printf("Not Found\n");

searchTST(root, "cat")? printf("Found\n"): printf("Not Found\n");

return 0;
}
Output:

Followingistraversalofternarysearchtree
bug
cat
cats
up

Followingaresearchresultsforcats,buandcatrespectively
Found
NotFound
Found

TimeComplexity:Thetimecomplexityoftheternarysearchtreeoperationsissimilartothatofbinary
searchtree.i.e.theinsertion,deletionandsearchoperationstaketimeproportionaltotheheightofthe
ternarysearchtree.Thespaceisproportionaltothelengthofthestringtobestored.

=======================================================================

Linkedcompletebinarytree&its
creation
Acompletebinarytreeisabinarytreewhereeachlevellexceptthelasthas2^lnodesandthenodesat
thelastlevelareallleftaligned.Completebinarytreesaremainlyusedinheapbaseddatastructures.
Thenodesinthecompletebinarytreeareinsertedfromlefttorightinonelevelatatime.Ifalevelisfull,the
nodeisinsertedinanewlevel.
Belowaresomeofthecompletebinarytrees.

1
/\
23

1
/\
23
/\/
456

Belowbinarytreesarenotcomplete:

1
/\
23
//
45

1
/\
23
/\/

456
/
7

Completebinarytreesaregenerallyrepresentedusingarrays.Thearrayrepresentationisbetterbecauseit
doesntcontainanyemptyslot.Givenparentindexi,itsleftchildisgivenby2*i+1anditsrightchildis
givenby2*i+2.Sonoextraspaceiswastedandspacetostoreleftandrightpointersissaved.However,
itmaybeaninterestingprogrammingquestiontocreatedaCompleteBinaryTreeusinglinked
representation.HereLinkedmeananonarrayrepresentationwhereleftandrightpointers(orreferences)
areusedtoreferleftandrightchildrenrespectively.Howtowriteaninsertfunctionthatalwaysaddsanew
nodeinthelastlevelandattheleftmostavailableposition?
Tocreatealinkedcompletebinarytree,weneedtokeeptrackofthenodesinalevelorderfashionsuch
thatthenextnodetobeinsertedliesintheleftmostposition.Aqueuedatastructurecanbeusedtokeep
trackoftheinsertednodes.
FollowingarestepstoinsertanewnodeinCompleteBinaryTree.
1.Ifthetreeisempty,initializetherootwithnewnode.
2.Else,getthefrontnodeofthequeue.
.Iftheleftchildofthisfrontnodedoesntexist,settheleftchildasthenewnode.
.elseiftherightchildofthisfrontnodedoesntexist,settherightchildasthenewnode.
3.Ifthefrontnodehasboththeleftchildandrightchild,Dequeue()it.
4.Enqueue()thenewnode.
Belowistheimplementation:
// Program for linked implementation of complete binary tree
#include <stdio.h>
#include <stdlib.h>

// For Queue Size


#define SIZE 50

// A tree node
struct node
{
int data;
struct node *right,*left;
};

// A queue node

struct Queue
{
int front, rear;
int size;
struct node* *array;
};

// A utility function to create a new tree node


struct node* newNode(int data)
{
struct node* temp = (struct node*) malloc(sizeof( struct node ));
temp->data = data;
temp->left = temp->right = NULL;
return temp;
}

// A utility function to create a new Queue


struct Queue* createQueue(int size)
{
struct Queue* queue = (struct Queue*) malloc(sizeof( struct Queue ));

queue->front = queue->rear = -1;


queue->size = size;

queue->array = (struct node**) malloc(queue->size * sizeof( struct node* ));

int i;
for (i = 0; i < size; ++i)
queue->array[i] = NULL;

return queue;
}

// Standard Queue Functions


int isEmpty(struct Queue* queue)
{
return queue->front == -1;

int isFull(struct Queue* queue)


{ return queue->rear == queue->size - 1; }

int hasOnlyOneItem(struct Queue* queue)


{ return queue->front == queue->rear; }

void Enqueue(struct node *root, struct Queue* queue)


{
if (isFull(queue))
return;

queue->array[++queue->rear] = root;

if (isEmpty(queue))
++queue->front;
}

struct node* Dequeue(struct Queue* queue)


{
if (isEmpty(queue))
return NULL;

struct node* temp = queue->array[queue->front];

if (hasOnlyOneItem(queue))
queue->front = queue->rear = -1;
else
++queue->front;

return temp;
}

struct node* getFront(struct Queue* queue)


{ return queue->array[queue->front]; }

// A utility function to check if a tree node has both left and right children
int hasBothChild(struct node* temp)
{
return temp && temp->left && temp->right;
}

// Function to insert a new node in complete binary tree


void insert(struct node **root, int data, struct Queue* queue)
{
// Create a new node for given data
struct node *temp = newNode(data);

// If the tree is empty, initialize the root with new node.


if (!*root)
*root = 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() the new node for later insertions


Enqueue(temp, queue);
}

// Standard level order traversal to test above function


void levelOrder(struct node* root)
{
struct Queue* queue = createQueue(SIZE);

Enqueue(root, queue);

while (!isEmpty(queue))
{
struct node* temp = Dequeue(queue);

printf("%d ", temp->data);

if (temp->left)
Enqueue(temp->left, queue);

if (temp->right)
Enqueue(temp->right, queue);
}
}

// Driver program to test above functions


int main()
{
struct node* root = NULL;
struct Queue* queue = createQueue(SIZE);
int i;

for(i = 1; i <= 12; ++i)


insert(&root, i, queue);

levelOrder(root);

return 0;
}
Output:

123456789101112
=======================================================================

MorristraversalforPreorder
UsingMorrisTraversal,wecantraversethetreewithoutusingstackandrecursion.Thealgorithmfor
PreorderisalmostsimilartoMorristraversalforInorder.
1...Ifleftchildisnull,printthecurrentnodedata.Movetorightchild.
.Else,Maketherightchildoftheinorderpredecessorpointtothecurrentnode.Twocasesarise:
a)Therightchildoftheinorderpredecessoralreadypointstothecurrentnode.Setrightchildto
NULL.Movetorightchildofcurrentnode.
b)TherightchildisNULL.Setittocurrentnode.Printcurrentnodesdataandmovetoleftchildof
currentnode.
2...IterateuntilcurrentnodeisnotNULL.
FollowingisCimplementationoftheabovealgorithm.
// C program for Morris Preorder traversal
#include <stdio.h>
#include <stdlib.h>

struct node
{
int data;
struct node *left, *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* temp = (struct node*) malloc(sizeof(struct node));
temp->data = data;
temp->left = temp->right = NULL;
return temp;

// Preorder traversal without recursion and without stack


void morrisTraversalPreorder(struct node* root)
{
while (root)
{
// If left child is null, print the current node data. Move to
// right child.
if (root->left == NULL)
{
printf( "%d ", root->data );
root = root->right;
}
else
{
// Find inorder predecessor
struct node* current = root->left;
while (current->right && current->right != root)
current = current->right;

// If the right child of inorder predecessor already points to


// this node
if (current->right == root)
{
current->right = NULL;
root = root->right;
}

// If right child doesn't point to this node, then print this


// node and make right child point to this node
else
{
printf("%d ", root->data);
current->right = root;
root = root->left;
}

}
}
}

// Function for sStandard preorder traversal


void preorder(struct node* root)
{
if (root)
{
printf( "%d ", root->data);
preorder(root->left);
preorder(root->right);
}
}

/* Driver program to test above functions*/


int main()
{
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->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:

1248951011367
1248951011367
Limitations:
Morristraversalmodifiesthetreeduringtheprocess.Itestablishestherightlinkswhilemovingdownthe
treeandresetstherightlinkswhilemovingupthetree.Sothealgorithmcannotbeappliedifwrite
operationsarenotallowed.

=======================================================================

ConvertaBSTtoaBinaryTreesuch
thatsumofallgreaterkeysisadded
toeverykey
GivenaBinarySearchTree(BST),convertittoaBinaryTreesuchthateverykeyoftheoriginalBSTis
changedtokeyplussumofallgreaterkeysinBST.
Examples:

Input:RootoffollowingBST
5
/\
213

Output:ThegivenBSTisconvertedtofollowingBinaryTree
18
/\
2013

Source:ConvertaBST

Solution:DoreverseInoordertraversal.Keeptrackofthesumofnodesvisitedsofar.Letthissumbesum.
Foreverynodecurrentlybeingvisited,firstaddthekeyofthisnodetosum,i.e.sum=sum+node>key.
Thenchangethekeyofcurrentnodetosum,i.e.,node>key=sum.
WhenaBSTisbeingtraversedinreverseInorder,foreverykeycurrentlybeingvisited,allkeysthatare
alreadyvisitedareallgreaterkeys.
// 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 BST 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);
}

// 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;

// Recur for right subtree first so that sum of all greater


// nodes is stored at sum_ptr
addGreaterUtil(root->right, sum_ptr);

// Update the value at sum_ptr


*sum_ptr = *sum_ptr + root->key;

// Update key of this node


root->key = *sum_ptr;

// Recur for left subtree so that the updated sum is added


// to smaller nodes
addGreaterUtil(root->left, sum_ptr);
}

// A wrapper over addGreaterUtil(). It initializes sum and calls


// addGreaterUtil() to recursivel upodate and use value of sum
void addGreater(struct node *root)
{
int sum = 0;
addGreaterUtil(root, &sum);
}

// A utility function to print inorder traversal of Binary Tree


void printInorder(struct node* node)
{
if (node == NULL)
return;
printInorder(node->left);
printf("%d ", node->key);
printInorder(node->right);
}

// Driver program to test above function


int main()
{
/* Create following BST

5
/

2 13 */
node *root = newNode(5);
root->left = newNode(2);
root->right = newNode(13);

printf(" Inorder traversal of the given tree\n");


printInorder(root);

addGreater(root);

printf("\n Inorder traversal of the modified tree\n");


printInorder(root);

return 0;
}
Output:

Inordertraversalofthegiventree
2513
Inordertraversalofthemodifiedtree
201813
TimeComplexity:O(n)wherenisthenumberofnodesingivenBinarySearchTree.

=======================================================================

IterativePreorderTraversal
GivenaBinaryTree,writeaniterativefunctiontoprintPreordertraversalofthegivenbinarytree.
ReferthisforrecursivepreordertraversalofBinaryTree.Toconvertaninherentlyrecursiveproceduresto
iterative,weneedanexplicitstack.FollowingisasimplestackbasediterativeprocesstoprintPreorder
traversal.
1)CreateanemptystacknodeStackandpushrootnodetostack.
2)DofollowingwhilenodeStackisnotempty.
.a)Popanitemfromstackandprintit.
.b)Pushrightchildofpoppeditemtostack

.c)Pushleftchildofpoppeditemtostack
Rightchildispushedbeforeleftchildtomakesurethatleftsubtreeisprocessedfirst.
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <stack>

using namespace std;

/* 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);
}

// An iterative process to print preorder traversal of Binary tree


void iterativePreorder(node *root)
{
// Base Case
if (root == NULL)
return;

// Create an empty stack and push root to it


stack<node *> nodeStack;

nodeStack.push(root);

/* 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();

// Push right and left children of the popped node to stack


if (node->right)
nodeStack.push(node->right);
if (node->left)
nodeStack.push(node->left);
}
}

// Driver program to test above functions


int main()
{
/* Constructed binary tree is
10
/

/ \

3 5 2
*/
struct node *root = newNode(10);
root->left

= newNode(8);

root->right

= newNode(2);

root->left->left = newNode(3);
root->left->right = newNode(5);

root->right->left = newNode(2);
iterativePreorder(root);
return 0;
}
Output:

1083522

=======================================================================

FloorandCeilfromaBST
Therearenumerousapplicationsweneedtofindfloor(ceil)valueofakeyinabinarysearchtreeorsorted
array.Forexample,considerdesigningmemorymanagementsysteminwhichfreenodesarearrangedin
BST.Findbestfitfortheinputrequest.
CeilValueNode:Nodewithsmallestdatalargerthanorequaltokeyvalue.
Imaginewearemovingdownthetree,andassumewearerootnode.Thecomparisonyieldsthree
possibilities,
A)Rootdataisequaltokey.Wearedone,rootdataisceilvalue.
B)Rootdata<keyvalue,certainlytheceilvaluecantbeinleftsubtree.Proceedtosearchonrightsubtree
asreducedprobleminstance.
C)Rootdata>keyvalue,theceilvaluemaybeinleftsubtree.Wemayfindanodewithislargerdatathan
keyvalueinleftsubtree,ifnottherootitselfwillbeceilnode.
HereiscodeinCforceilvalue.
// Program to find ceil of a given value in BST
#include <stdio.h>
#include <stdlib.h>

/* 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);
}

// Function to find ceil of a given input in BST. If input is more


// than the max key in BST, return -1
int Ceil(node *root, int input)
{
// Base case
if( root == NULL )
return -1;

// We found equal key


if( root->key == input )
return root->key;

// If root's key is smaller, ceil must be in right subtree


if( root->key < input )
return Ceil(root->right, input);

// Else, either left subtree or root has the ceil value


int ceil = Ceil(root->left, input);
return (ceil >= input) ? ceil : root->key;
}

// Driver program to test above function


int main()
{
node *root = newNode(8);

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);

for(int i = 0; i < 16; i++)


printf("%d %d\n", i, Ceil(root, i));

return 0;
}
Output:

02
12
22
34
44
56
66
78
88
910
1010
1112
1212
1314
1414
151

=======================================================================

ConstructBSTfromgivenpreorder
traversal|Set2
Givenpreordertraversalofabinarysearchtree,constructtheBST.
Forexample,ifthegiventraversalis{10,5,1,7,40,50},thentheoutputshouldberootoffollowingtree.

10
/\
540
/\\
1750
WehavediscussedO(n^2)andO(n)recursivesolutionsinthepreviouspost.Followingisastackbased
iterativesolutionthatworksinO(n)time.
1.Createanemptystack.
2.Makethefirstvalueasroot.Pushittothestack.
3.Keeponpoppingwhilethestackisnotemptyandthenextvalueisgreaterthanstackstopvalue.Make
thisvalueastherightchildofthelastpoppednode.Pushthenewnodetothestack.
4.Ifthenextvalueislessthanthestackstopvalue,makethisvalueastheleftchildofthestackstopnode.
Pushthenewnodetothestack.
5.Repeatsteps2and3untilthereareitemsremaininginpre[].
/* A O(n) iterative program for construction of BST from preorder traversal */
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>

/* A binary tree node has data, pointer to left child


and a pointer to right child */
typedef struct Node
{
int data;
struct Node *left, *right;
} Node;

// A Stack has array of Nodes, capacity, and top


typedef struct Stack
{

int top;
int capacity;
Node* *array;
} Stack;

// A utility function to create a new tree node


Node* newNode( int data )
{
Node* temp = (Node *)malloc( sizeof( Node ) );
temp->data = data;
temp->left = temp->right = NULL;
return temp;
}

// A utility function to create a stack of given capacity


Stack* createStack( int capacity )
{
Stack* stack = (Stack *)malloc( sizeof( Stack ) );
stack->top = -1;
stack->capacity = capacity;
stack->array = (Node **)malloc( stack->capacity * sizeof( Node* ) );
return stack;
}

// A utility function to check if stack is full


int isFull( Stack* stack )
{
return stack->top == stack->capacity - 1;
}

// A utility function to check if stack is empty


int isEmpty( Stack* stack )
{
return stack->top == -1;
}

// A utility function to push an item to stack

void push( Stack* stack, Node* item )


{
if( isFull( stack ) )
return;
stack->array[ ++stack->top ] = item;
}

// A utility function to remove an item from stack


Node* pop( Stack* stack )
{
if( isEmpty( stack ) )
return NULL;
return stack->array[ stack->top-- ];
}

// A utility function to get top node of stack


Node* peek( Stack* stack )
{
return stack->array[ stack->top ];
}

// The main function that constructs BST from pre[]


Node* constructTree ( int pre[], int size )
{
// Create a stack of capacity equal to size
Stack* stack = createStack( size );

// The first element of pre[] is always root


Node* root = newNode( pre[0] );

// Push root
push( stack, root );

int i;
Node* temp;

// Iterate through rest of the size-1 items of given preorder array

for ( i = 1; i < size; ++i )


{
temp = NULL;

/* Keep on popping while the next value is greater than


stack's top value. */
while ( !isEmpty( stack ) && pre[i] > peek( stack )->data )
temp = pop( stack );

// 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;
}

// A utility function to print inorder traversal of a Binary Tree


void printInorder (Node* node)
{
if (node == NULL)
return;
printInorder(node->left);
printf("%d ", node->data);
printInorder(node->right);

// Driver program to test above functions


int main ()
{
int pre[] = {10, 5, 1, 7, 40, 50};
int size = sizeof( pre ) / sizeof( pre[0] );

Node *root = constructTree(pre, size);

printf("Inorder traversal of the constructed tree: \n");


printInorder(root);

return 0;
}
Output:

157104050
TimeComplexity:O(n).Thecomplexitylooksmorefromfirstlook.Ifwetakeacloserlook,wecanobserve
thateveryitemispushedandpoppedonlyonce.Soatmost2npush/popoperationsareperformedinthe
mainloopsofconstructTree().Therefore,timecomplexityisO(n).

=======================================================================

ConstructFullBinaryTreefrom
givenpreorderandpostorder
traversals
Giventwoarraysthatrepresentpreorderandpostordertraversalsofafullbinarytree,constructthebinary
tree.
AFullBinaryTreeisabinarytreewhereeverynodehaseither0or2children
FollowingareexamplesofFullTrees.

1
/\
23

/\/\
4567

1
/\
23
/\
45
/\
67

1
/\
23
/\/\
4567
/\
89

ItisnotpossibletoconstructageneralBinaryTreefrompreorderandpostordertraversals(Seethis).Butif
knowthattheBinaryTreeisFull,wecanconstructthetreewithoutambiguity.Letusunderstandthiswith
thehelpoffollowingexample.
Letusconsiderthetwogivenarraysaspre[]={1,2,4,8,9,5,3,6,7}andpost[]={8,9,4,5,2,6,7,3,1}
Inpre[],theleftmostelementisrootoftree.Sincethetreeisfullandarraysizeismorethan1.Thevalue
nextto1inpre[],mustbeleftchildofroot.Soweknow1isrootand2isleftchild.Howtofindtheallnodes
inleftsubtree?Weknow2isrootofallnodesinleftsubtree.Allnodesbefore2inpost[]mustbeinleft
subtree.Nowweknow1isroot,elements{8,9,4,5,2}areinleftsubtree,andtheelements{6,7,3}arein
rightsubtree.

1
/\
/\
{8,9,4,5,2}{6,7,3}
Werecursivelyfollowtheaboveapproachandgetthefollowingtree.

1
/\
23
/\/\
4567
/\
89

/* program for construction of full binary 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;
struct node *right;
};

// A utility function to create a node


struct node* newNode (int data)
{
struct node* temp = (struct node *) malloc( sizeof(struct node) );

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

return temp;
}

// A recursive function to construct Full from pre[] and post[].


// preIndex is used to keep track of index in pre[].
// l is low index and h is high index for the current subarray in post[]
struct node* constructTreeUtil (int pre[], int post[], int* preIndex,

int l, int h, int size)


{
// Base case
if (*preIndex >= size || l > h)
return NULL;

// The first node in preorder traversal is root. So take the node at


// preIndex from preorder and make it root, and increment preIndex
struct node* root = newNode ( pre[*preIndex] );
++*preIndex;

// If the current subarry has only one element, no need to recur


if (l == h)
return root;

// Search the next element of pre[] in post[]


int i;
for (i = l; i <= h; ++i)
if (pre[*preIndex] == post[i])
break;

// Use the index of element found in postorder to divide postorder array in


// two parts. Left subtree and right subtree
if (i <= h)
{
root->left = constructTreeUtil (pre, post, preIndex, l, i, size);
root->right = constructTreeUtil (pre, post, preIndex, i + 1, h, size);
}

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);


}

// A utility function to print inorder traversal of a Binary Tree


void printInorder (struct node* node)
{
if (node == NULL)
return;
printInorder(node->left);
printf("%d ", node->data);
printInorder(node->right);
}

// Driver program to test above functions


int main ()
{
int pre[] = {1, 2, 4, 8, 9, 5, 3, 6, 7};
int post[] = {8, 9, 4, 5, 2, 6, 7, 3, 1};
int size = sizeof( pre ) / sizeof( pre[0] );

struct node *root = constructTree(pre, post, size);

printf("Inorder traversal of the constructed tree: \n");


printInorder(root);

return 0;
}
Output:

Inordertraversaloftheconstructedtree:
849251637

=======================================================================

TwonodesofaBSTareswapped,
correcttheBST
TwoofthenodesofaBinarySearchTree(BST)areswapped.Fix(orcorrect)theBST.

InputTree:
10
/\
58
/\
220

Intheabovetree,nodes20and8mustbeswappedtofixthetree.
Followingistheoutputtree
10
/\
520
/\
28

TheinordertraversalofaBSTproducesasortedarray.Soasimplemethodistostoreinordertraversalof
theinputtreeinanauxiliaryarray.Sorttheauxiliaryarray.Finally,inserttheauxiilaryarrayelementsbackto
theBST,keepingthestructureoftheBSTsame.TimecomplexityofthismethodisO(nLogn)andauxiliary
spaceneededisO(n).
WecansolvethisinO(n)timeandwithasingletraversalofthegivenBST.Sinceinordertraversalof
BSTisalwaysasortedarray,theproblemcanbereducedtoaproblemwheretwoelementsofasorted
arrayareswapped.Therearetwocasesthatweneedtohandle:
1.TheswappednodesarenotadjacentintheinordertraversaloftheBST.

Forexample,Nodes5and25areswappedin{357810152025}.
Theinordertraversalofthegiventreeis325781015205

Ifweobservecarefully,duringinordertraversal,wefindnode7issmallerthanthepreviousvisitednode25.
Heresavethecontextofnode25(previousnode).Again,wefindthatnode5issmallerthantheprevious
node20.Thistime,wesavethecontextofnode5(currentnode).Finallyswapthetwonodesvalues.
2.TheswappednodesareadjacentintheinordertraversalofBST.

Forexample,Nodes7and8areswappedin{357810152025}.
Theinordertraversalofthegiventreeis358710152025
Unlikecase#1,hereonlyonepointexistswhereanodevalueissmallerthanpreviousnodevalue.e.g.
node7issmallerthannode8.
HowtoSolve?Wewillmaintainthreepointers,first,middleandlast.Whenwefindthefirstpointwhere
currentnodevalueissmallerthanpreviousnodevalue,weupdatethefirstwiththepreviousnode&middle
withthecurrentnode.Whenwefindthesecondpointwherecurrentnodevalueissmallerthanprevious
nodevalue,weupdatethelastwiththecurrentnode.Incase#2,wewillneverfindthesecondpoint.So,
lastpointerwillnotbeupdated.Afterprocessing,ifthelastnodevalueisnull,thentwoswappednodesof
BSTareadjacent.
FollowingisCimplementationofthegivencode.
// Two nodes in the BST's swapped, correct the BST.
#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;
};

// A utility function to swap two integers


void swap( int* a, int* b )
{
int t = *a;
*a = *b;
*b = t;
}

/* 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);
}

// 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 );

// If this node is smaller than the previous node, it's violating


// the BST rule.
if (*prev && root->data < (*prev)->data)
{
// If this is first violation, mark these two nodes as
// 'first' and 'middle'
if ( !*first )
{
*first = *prev;
*middle = root;
}

// If this is second violation, mark this node as last


else
*last = root;
}

// Mark this node as previous


*prev = root;

// Recur for the right subtree


correctBSTUtil( root->right, 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;

// Set the poiters to find out two nodes


correctBSTUtil( root, &first, &middle, &last, &prev );

// Fix (or correct) the tree


if( first && last )
swap( &(first->data), &(last->data) );
else if( first && middle ) // Adjacent nodes swapped
swap( &(first->data), &(middle->data) );

// else nodes have not been swapped, passed tree is really BST.
}

/* A utility function to print Inoder traversal */


void printInorder(struct node* node)
{
if (node == NULL)
return;
printInorder(node->left);
printf("%d ", node->data);
printInorder(node->right);
}

/* Driver program to test above functions*/


int main()
{
/*

6
/ \
10

/\

/\

3 7 12

10 and 2 are swapped


*/

struct node *root = newNode(6);


root->left

= newNode(10);

root->right

= newNode(2);

root->left->left = newNode(1);
root->left->right = newNode(3);
root->right->right = newNode(12);
root->right->left = newNode(7);

printf("Inorder Traversal of the original tree \n");


printInorder(root);

correctBST(root);

printf("\nInorder Traversal of the fixed tree \n");


printInorder(root);

return 0;
}
Output:

InorderTraversaloftheoriginaltree
110367212
InorderTraversalofthefixedtree
123671012
TimeComplexity:O(n)

=======================================================================

BoundaryTraversalofbinarytree
Givenabinarytree,printboundarynodesofthebinarytreeAntiClockwisestartingfromtheroot.For
example,boundarytraversalofthefollowingtreeis208410142522

Webreaktheproblemin3parts:
1.Printtheleftboundaryintopdownmanner.
2.Printallleafnodesfromlefttoright,whichcanagainbesubdividedintotwosubparts:
..2.1Printallleafnodesofleftsubtreefromlefttoright.
..2.2Printallleafnodesofrightsubtreefromlefttoright.
3.Printtherightboundaryinbottomupmanner.
Weneedtotakecareofonethingthatnodesarenotprintedagain.e.g.Theleftmostnodeisalsotheleaf
nodeofthetree.
Basedontheabovecases,belowistheimplementation:
/* program for boundary traversal of a binary 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;
};

// A simple function to print leaf nodes of a binary tree


void printLeaves(struct node* root)
{
if ( root )
{
printLeaves(root->left);

// Print it if it is a leaf node


if ( !(root->left) && !(root->right) )
printf("%d ", root->data);

printLeaves(root->right);
}
}

// A function to print all left boundry nodes, except a leaf node.


// Print the nodes in TOP DOWN manner
void printBoundaryLeft(struct node* root)
{
if (root)
{
if (root->left)
{
// to ensure top down order, print the node
// before calling itself for left subtree
printf("%d ", root->data);
printBoundaryLeft(root->left);
}
else if( root->right )
{
printf("%d ", root->data);
printBoundaryLeft(root->right);
}
// do nothing if it is a leaf node, this way we avoid
// duplicates in output
}

// A function to print all right boundry nodes, except a leaf node


// Print the nodes in BOTTOM UP manner
void printBoundaryRight(struct node* root)
{
if (root)
{
if ( root->right )
{
// to ensure bottom up order, first call for right
// subtree, then print this node
printBoundaryRight(root->right);
printf("%d ", root->data);
}
else if ( root->left )
{
printBoundaryRight(root->left);
printf("%d ", root->data);
}
// do nothing if it is a leaf node, this way we avoid
// duplicates in output
}
}

// A function to do boundary traversal of a given binary tree


void printBoundary (struct node* root)
{
if (root)
{
printf("%d ",root->data);

// Print the left boundary in top-down manner.


printBoundaryLeft(root->left);

// Print all leaf nodes

printLeaves(root->left);
printLeaves(root->right);

// Print the right boundary in bottom-up manner


printBoundaryRight(root->right);
}
}

// A utility function to create a node


struct node* newNode( int data )
{
struct node* temp = (struct node *) malloc( sizeof(struct node) );

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

return temp;
}

// Driver program to test above functions


int main()
{
// Let us construct the tree given in the above diagram
struct node *root

= newNode(20);

root->left

= newNode(8);

root->left->left

= newNode(4);

root->left->right

= newNode(12);

root->left->right->left

= newNode(10);

root->left->right->right = newNode(14);
root->right

= newNode(22);

root->right->right

= newNode(25);

printBoundary( root );

return 0;
}
Output:

208410142522
TimeComplexity:O(n)wherenisthenumberofnodesinbinarytree.

=======================================================================

CheckwhetheragivenBinaryTree
isCompleteornot
GivenaBinaryTree,writeafunctiontocheckwhetherthegivenBinaryTreeisCompleteBinaryTreeornot.
Acompletebinarytreeisabinarytreeinwhicheverylevel,exceptpossiblythelast,iscompletelyfilled,and
allnodesareasfarleftaspossible.Seefollowingexamples.

ThefollowingtreesareexamplesofCompleteBinaryTrees
1
/\
23

1
/\
23
/
4

1
/\
23
/\/
456

ThefollowingtreesareexamplesofNonCompleteBinaryTrees
1
\
3

1
/\
23

\/\
456

1
/\
23
/\
45

Source:Writeanalgorithmtocheckifatreeiscompletebinarytreeornot
Themethod2oflevelordertraversalpostcanbeeasilymodifiedtocheckwhetheratreeisCompleteor
not.Tounderstandtheapproach,letusfirstdefineatermFullNode.AnodeisFullNodeifbothleftand
rightchildrenarenotempty(ornotNULL).
Theapproachistodoalevelordertraversalstartingfromroot.Inthetraversal,onceanodeisfoundwhich
isNOTaFullNode,allthefollowingnodesmustbeleafnodes.
Also,onemorethingneedstobecheckedtohandlethebelowcase:Ifanodehasemptyleftchild,thenthe
rightchildmustbeempty.

1
/\
23
\
4
ThankstoGudduSharmaforsuggestingthissimpleandefficientapproach.
// A program to check if a given binary tree is complete or not
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define MAX_Q_SIZE 500

/* 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;
};

/* frunction prototypes for functions needed for Queue data


structure. A queue is needed for level order tarversal */
struct node** createQueue(int *, int *);
void enQueue(struct node **, int *, struct node *);
struct node *deQueue(struct node **, int *);
bool isQueueEmpty(int *front, int *rear);

/* Given a binary tree, return true if the tree is complete


else false */
bool isCompleteBT(struct node* root)
{
// Base Case: An empty tree is complete Binary Tree
if (root == NULL)
return true;

// Create an empty queue


int rear, front;
struct node **queue = createQueue(&front, &rear);

// Create a flag variable which will be set true


// when a non full node is seen
bool flag = false;

// Do level order traversal using queue.


enQueue(queue, &rear, root);
while(!isQueueEmpty(&front, &rear))
{
struct node *temp_node = deQueue(queue, &front);

/* Ceck if left child is present*/


if(temp_node->left)
{
// If we have seen a non full node, and we see a node
// with non-empty left child, then the given tree is not
// a complete Binary Tree
if (flag == true)

return false;

enQueue(queue, &rear, temp_node->left); // Enqueue Left Child


}
else // If this a non-full node, set the flag as true
flag = true;

/* Ceck if right child is present*/


if(temp_node->right)
{
// If we have seen a non full node, and we see a node
// with non-empty left child, then the given tree is not
// a complete Binary Tree
if(flag == true)
return false;

enQueue(queue, &rear, temp_node->right); // Enqueue Right Child


}
else // If this a non-full node, set the flag as true
flag = true;
}

// If we reach here, then the tree is complete Bianry Tree


return true;
}

/*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;
}

void enQueue(struct node **queue, int *rear, struct node *new_node)


{
queue[*rear] = new_node;
(*rear)++;
}

struct node *deQueue(struct node **queue, int *front)


{
(*front)++;
return queue[*front - 1];
}

bool isQueueEmpty(int *front, int *rear)


{
return (*rear == *front);
}

/* 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);
}

/* Driver program to test above functions*/


int main()
{
/* Let us construct the following Binary Tree which
is not a complete Binary Tree
1
/

/\ \
4

56

*/

struct node *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);

if ( isCompleteBT(root) == true )
printf ("Complete Binary Tree");
else
printf ("NOT Complete Binary Tree");

return 0;
}
Output:

NOTCompleteBinaryTree
TimeComplexity:O(n)wherenisthenumberofnodesingivenBinaryTree
AuxiliarySpace:O(n)forqueue.

=======================================================================

CheckifeachinternalnodeofaBST
hasexactlyonechild
GivenPreordertraversalofaBST,checkifeachnonleafnodehasonlyonechild.AssumethattheBST
containsuniqueentries.
Examples

Input:pre[]={20,10,11,13,12}
Output:Yes
ThegivearrayrepresentsfollowingBST.InthefollowingBST,everyinternal

nodehasexactly1child.Therefor,theoutputistrue.
20
/
10
\
11
\
13
/
12

InPreordertraversal,descendants(orPreordersuccessors)ofeverynodeappearafterthenode.Inthe
aboveexample,20isthefirstnodeinpreorderandalldescendantsof20appearafterit.Alldescendantsof
20aresmallerthanit.For10,alldescendantsaregreaterthanit.Ingeneral,wecansay,ifallinternalnodes
haveonlyonechildinaBST,thenallthedescendantsofeverynodeareeithersmallerorlargerthanthe
node.Thereasonissimple,sincethetreeisBSTandeverynodehasonlyonechild,alldescendantsofa
nodewilleitherbeonleftsideorrightside,meansalldescendantswilleitherbesmallerorgreater.
Approach1(Naive)
Thisapproachsimplyfollowstheaboveideathatallvaluesonrightsideareeithersmallerorlarger.Usetwo
loops,theouterlooppicksanelementonebyone,startingfromtheleftmostelement.Theinnerloopchecks
ifallelementsontherightsideofthepickedelementareeithersmallerorgreater.Thetimecomplexityof
thismethodwillbeO(n^2).
Approach2
Sinceallthedescendantsofanodemusteitherbelargerorsmallerthanthenode.Wecandofollowingfor
everynodeinaloop.
1.Findthenextpreordersuccessor(ordescendant)ofthenode.
2.Findthelastpreordersuccessor(lastelementinpre[])ofthenode.
3.Ifbothsuccessorsarelessthanthecurrentnode,orbothsuccessorsaregreaterthanthecurrentnode,
thencontinue.Else,returnfalse.
#include <stdio.h>

bool hasOnlyOneChild(int pre[], int size)


{
int nextDiff, lastDiff;

for (int i=0; i<size-1; i++)


{

nextDiff = pre[i] - pre[i+1];


lastDiff = pre[i] - pre[size-1];
if (nextDiff*lastDiff < 0)
return false;;
}
return true;
}

// driver program to test above function


int main()
{
int pre[] = {8, 3, 5, 7, 6};
int size = sizeof(pre)/sizeof(pre[0]);
if (hasOnlyOneChild(pre, size) == true )
printf("Yes");
else
printf("No");
return 0;
}
Output:

Yes
Approach3
1.Scanthelasttwonodesofpreorder&markthemasmin&max.
2.Scaneverynodedownthepreorderarray.Eachnodemustbeeithersmallerthantheminnodeorlarger
thanthemaxnode.Updatemin&maxaccordingly.
#include <stdio.h>

int hasOnlyOneChild(int pre[], int size)


{
// Initialize min and max using last two elements
int min, max;
if (pre[size-1] > pre[size-2])
{
max = pre[size-1];
min = pre[size-2]):
else
{

max = pre[size-2];
min = pre[size-1];
}

// Every element must be either smaller than min or


// greater than max
for (int i=size-3; i>=0; i--)
{
if (pre[i] < min)
min = pre[i];
else if (pre[i] > max)
max = pre[i];
else
return false;
}
return true;
}

// Driver program to test above function


int main()
{
int pre[] = {8, 3, 5, 7, 6};
int size = sizeof(pre)/sizeof(pre[0]);
if (hasOnlyOneChild(pre,size))
printf("Yes");
else
printf("No");
return 0;
}
Output:

Yes
=======================================================================

Constructaspecialtreefromgiven
preordertraversal
Givenanarraypre[]thatrepresentsPreordertraversalofaspacialbinarytreewhereeverynodehaseither
0or2children.OnemorearraypreLN[]isgivenwhichhasonlytwopossiblevaluesLandN.Thevalue
LinpreLN[]indicatesthatthecorrespondingnodeinBinaryTreeisaleafnodeandvalueNindicatesthat
thecorrespondingnodeisnonleafnode.Writeafunctiontoconstructthetreefromthegiventwoarrays.
Source:AmazonInterviewQuestion
Example:

Input:pre[]={10,30,20,5,15},preLN[]={'N','N','L','L','L'}
Output:Rootoffollowingtree
10
/\
3015
/\
205

Thefirstelementinpre[]willalwaysberoot.Sowecaneasilyfigureoutroot.Ifleftsubtreeisempty,the
rightsubtreemustalsobeemptyandpreLN[]entryforrootmustbeL.Wecansimplycreateanodeand
returnit.Ifleftandrightsubtreesarenotempty,thenrecursivelycallforleftandrightsubtreesandlinkthe
returnednodestoroot.
/* A program to construct Binary Tree from preorder traversal */
#include<stdio.h>

/* A binary tree node structure */


struct node
{
int data;
struct node *left;
struct node *right;
};

/* Utility function to create a new Binary Tree node */


struct node* newNode (int data)
{

struct node *temp = new struct node;


temp->data = data;
temp->left = NULL;
temp->right = NULL;
return temp;
}

/* A recursive function to create a Binary Tree from given pre[]


preLN[] arrays. The function returns root of tree. index_ptr is used
to update index values in recursive calls. index must be initially
passed as 0 */
struct node *constructTreeUtil(int pre[], char preLN[], int *index_ptr, int n)
{
int index = *index_ptr; // store the current value of index in pre[]

// Base Case: All nodes are constructed


if (index == n)
return NULL;

// Allocate memory for this node and increment index for


// subsequent recursive calls
struct node *temp = newNode ( pre[index] );
(*index_ptr)++;

// If this is an internal node, construct left and right subtrees and link the
subtrees
if (preLN[index] == 'N')
{
temp->left = constructTreeUtil(pre, preLN, index_ptr, n);
temp->right = constructTreeUtil(pre, preLN, index_ptr, n);
}

return temp;
}

// A wrapper over constructTreeUtil()


struct node *constructTree(int pre[], char preLN[], int n)

{
// Initialize index as 0. Value of index is used in recursion to maintain
// the current index in pre[] and preLN[] arrays.
int index = 0;

return constructTreeUtil (pre, preLN, &index, n);


}

/* This function is used only for testing */


void printInorder (struct node* node)
{
if (node == NULL)
return;

/* first recur on left child */


printInorder (node->left);

/* then print the data of node */


printf("%d ", node->data);

/* now recur on right child */


printInorder (node->right);
}

/* Driver function to test above functions */


int main()
{
struct node *root = NULL;

/* Constructing tree given in the above figure


10
/ \
30

15

/ \
20

5 */

int pre[] = {10, 30, 20, 5, 15};

char preLN[] = {'N', 'N', 'L', 'L', 'L'};


int n = sizeof(pre)/sizeof(pre[0]);

// construct the above tree


root = constructTree (pre, preLN, n);

// Test the constructed tree


printf("Following is Inorder Traversal of the Constructed Binary Tree: \n");
printInorder (root);

return 0;
}
Output:

FollowingisInorderTraversaloftheConstructedBinaryTree:
203051015

TimeComplexity:O(n)

=======================================================================

ConstructSpecialBinaryTreefrom
givenInordertraversal
GivenInorderTraversalofaSpecialBinaryTreeinwhichkeyofeverynodeisgreaterthankeysinleftand
rightchildren,constructtheBinaryTreeandreturnroot.
Examples:

Input:inorder[]={5,10,40,30,28}
Output:rootoffollowingtree
40
/\
1030
/\
528

TheideausedinConstructionofTreefromgivenInorderandPreordertraversalscanbeusedhere.Letthe
givenarrayis{1,5,10,40,30,15,28,20}.Themaximumelementingivenarraymustberoot.The

elementsonleftsideofthemaximumelementareinleftsubtreeandelementsonrightsideareinright
subtree.

40
/\
{1,5,10}{30,15,28,20}

Werecursivelyfollowabovestepforleftandrightsubtrees,andfinallygetthefollowingtree.

40
/\
1030
/\
528
//\
11520

Algorithm:buildTree()
1)Findindexofthemaximumelementinarray.ThemaximumelementmustberootofBinaryTree.
2)Createanewtreenoderootwiththedataasthemaximumvaluefoundinstep1.
3)CallbuildTreeforelementsbeforethemaximumelementandmakethebuilttreeasleftsubtreeofroot.
5)CallbuildTreeforelementsafterthemaximumelementandmakethebuilttreeasrightsubtreeofroot.
6)returnroot.
Implementation:FollowingisC/C++implementationoftheabovealgorithm.
/* program to construct tree from inorder traversal */
#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;
};

/* Prototypes of a utility function to get the maximum


value in inorder[start..end] */

int max(int inorder[], int strt, int end);

/* A utility function to allocate memory for a node */


struct node* newNode(int data);

/* Recursive function to construct binary of size len from


Inorder traversal inorder[]. Initial values of start and end
should be 0 and len -1. */
struct node* buildTree (int inorder[], int start, int end)
{
if (start > end)
return NULL;

/* Find index of the maximum element from Binary Tree */


int i = max (inorder, start, end);

/* Pick the maximum value and make it root */


struct node *root = newNode(inorder[i]);

/* If this is the only element in inorder[start..end],


then return it */
if (start == end)
return root;

/* Using index in Inorder traversal, construct left and


right subtress */
root->left = buildTree (inorder, start, i-1);
root->right = buildTree (inorder, i+1, end);

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;
}

/* 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;
}

/* This funtcion is here just to test buildTree() */


void printInorder (struct node* node)
{
if (node == NULL)
return;

/* first recur on left child */


printInorder (node->left);

/* then print the data of node */


printf("%d ", node->data);

/* now recur on right child */


printInorder (node->right);

/* Driver program to test above functions */


int main()
{
/* Assume that inorder traversal of following tree is given
40
/
10
/
5

\
30
\
28 */

int inorder[] = {5, 10, 40, 30, 28};


int len = sizeof(inorder)/sizeof(inorder[0]);
struct node *root = buildTree(inorder, 0, len - 1);

/* Let us test the built tree by printing Insorder traversal */


printf("\n Inorder traversal of the constructed tree is \n");
printInorder(root);
return 0;
}
Output:

Inordertraversaloftheconstructedtreeis
510403028
TimeComplexity:O(n^2)
=======================================================================

MergetwoBSTswithlimitedextra
space
GiventwoBinarySearchTrees(BST),printtheelementsofbothBSTsinsortedform.Theexpectedtime
complexityisO(m+n)wheremisthenumberofnodesinfirsttreeandnisthenumberofnodesinsecond
tree.MaximumallowedauxiliaryspaceisO(heightofthefirsttree+heightofthesecondtree).
Examples:

FirstBST
3
/\
15
SecondBST
4
/\
26
Output:123456

FirstBST
8
/\
210
/
1
SecondBST
5
/
3
/
0
Output:01235810

Source:Googleinterviewquestion
Asimilarquestionhasbeendiscussedearlier.Letusfirstdiscussalreadydiscussedmethodsofthe
previouspostwhichwasforBalancedBSTs.Themethod1canbeappliedherealso,butthetime
complexitywillbeO(n^2)inworstcase.Themethod2canalsobeappliedhere,buttheextraspace
requiredwillbeO(n)whichviolatestheconstraintgiveninthisquestion.Method3canbeappliedherebut
thestep3ofmethod3cantbedoneinO(n)foranunbalancedBST.
ThankstoKumarforsuggestingthefollowingsolution.
Theideaistouseiterativeinordertraversal.WeusetwoauxiliarystacksfortwoBSTs.Sinceweneedto
printtheelementsinsortedform,wheneverwegetasmallerelementfromanyofthetrees,weprintit.Ifthe
elementisgreater,thenwepushitbacktostackforthenextiteration.
#include<stdio.h>
#include<stdlib.h>

// Structure of a BST Node


struct node
{
int data;
struct node *left;
struct node *right;
};

//.................... START OF STACK RELATED STUFF....................


// A stack node
struct snode
{
struct node *t;
struct snode *next;
};

// Function to add an elemt k to stack


void push(struct snode **s, struct node *k)
{
struct snode *tmp = (struct snode *) malloc(sizeof(struct snode));

//perform memory check here


tmp->t = k;
tmp->next = *s;
(*s) = tmp;
}

// Function to pop an element t from stack


struct node *pop(struct snode **s)
{
struct node *t;
struct snode *st;
st=*s;
(*s) = (*s)->next;
t = st->t;
free(st);

return t;
}

// Fucntion to check whether the stack is empty or not


int isEmpty(struct snode *s)
{
if (s == NULL )
return 1;

return 0;
}
//.................... END OF STACK RELATED STUFF....................

/* Utility function to create a new Binary Tree node */


struct node* newNode (int data)
{
struct node *temp = new struct node;
temp->data = data;
temp->left = NULL;
temp->right = NULL;
return temp;
}

/* A utility function to print Inoder traversal of a Binary Tree */


void inorder(struct node *root)
{
if (root != NULL)
{
inorder(root->left);
printf("%d ", root->data);
inorder(root->right);
}
}

// The function to print data of two BSTs in sorted order


void merge(struct node *root1, struct node *root2)

{
// s1 is stack to hold nodes of first BST
struct snode *s1 = NULL;

// Current node of first BST


struct node *current1 = root1;

// s2 is stack to hold nodes of second BST


struct snode *s2 = NULL;

// Current node of second BST


struct node *current2 = root2;

// If first BST is empty, then output is inorder


// traversal of second BST
if (root1 == NULL)
{
inorder(root2);
return;
}
// If second BST is empty, then output is inorder
// traversal of first BST
if (root2 == NULL)
{
inorder(root1);
return ;
}

// 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 ;

// Pop an element from both stacks and compare the


// popped elements
current1 = pop(&s1);
current2 = pop(&s2);

// If element of first tree is smaller, then print it


// and push the right subtree. If the element is larger,
// then we push it back to the corresponding stack.
if (current1->data < current2->data)
{
printf("%d ", current1->data);
current1 = current1->right;
push(&s2, current2);
current2 = NULL;
}
else
{
printf("%d ", current2->data);
current2 = current2->right;
push(&s1, current1);
current1 = NULL;
}
}
}
}

/* Driver program to test above functions */


int main()
{
struct node *root1 = NULL, *root2 = NULL;

/* Let us create the following tree as first tree


3
/ \
1

*/
root1 = newNode(3);
root1->left = newNode(1);
root1->right = newNode(5);

/* Let us create the following tree as second tree


4
/ \
2

*/
root2 = newNode(4);
root2->left = newNode(2);
root2->right = newNode(6);

// Print sorted nodes of both trees


merge(root1, root2);

return 0;
}
TimeComplexity:O(m+n)
AuxiliarySpace:O(heightofthefirsttree+heightofthesecondtree)

=======================================================================

Findthemaximumsumleaftoroot
pathinaBinaryTree
GivenaBinaryTree,findthemaximumsumpathfromaleaftoroot.Forexample,inthefollowingtree,there
arethreeleaftorootpaths8>2>10,4>2>10and7>10.Thesumsofthesethreepathsare16,4and
17respectively.Themaximumofthemis17andthepathformaximumis7>10.

10
/\
27
/\
84

Solution
1)Firstfindtheleafnodethatisonthemaximumsumpath.InthefollowingcodegetTargetLeaf()doesthis
byassigningtheresultto*target_leaf_ref.
2)Oncewehavethetargetleafnode,wecanprintthemaximumsumpathbytraversingthetree.Inthe
followingcode,printPath()doesthis.
ThemainfunctionismaxSumPath()thatusesabovetwofunctionstogetthecompletesolution.
#include<stdio.h>
#include<limits.h>

/* A tree node structure */


struct node
{
int data;
struct node *left;
struct node *right;
};

// 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 true if this node is the target_leaf or target leaf is present in


// one of its descendants
if (root == target_leaf || printPath(root->left, target_leaf) ||
printPath(root->right, target_leaf) )
{
printf("%d ", root->data);
return true;
}

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;

struct node *target_leaf;


int max_sum = INT_MIN;

// find the target leaf and maximum sum

getTargetLeaf (node, &max_sum, 0, &target_leaf);

// print the path from root to the target leaf


printPath (node, target_leaf);

return max_sum; // return maximum sum


}

/* Utility function to create a new Binary Tree node */


struct node* newNode (int data)
{
struct node *temp = new struct node;
temp->data = data;
temp->left = NULL;
temp->right = NULL;
return temp;
}

/* Driver function to test above functions */


int main()
{
struct node *root = NULL;

/* Constructing tree given in the above figure */


root = newNode(10);
root->left = newNode(-2);
root->right = newNode(7);
root->left->left = newNode(8);
root->left->right = newNode(-4);

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:

Followingarethenodesonthemaximumsumpath
710
Sumofthenodesis17

TimeComplexity:TimecomplexityoftheabovesolutionisO(n)asitinvolvestreetraversaltwotimes.

=======================================================================

MergeTwoBalancedBinarySearch
Trees
Youaregiventwobalancedbinarysearchtreese.g.,AVLorRedBlackTree.Writeafunctionthatmerges
thetwogivenbalancedBSTsintoabalancedbinarysearchtree.Lettherebemelementsinfirsttreeandn
elementsintheothertree.YourmergefunctionshouldtakeO(m+n)time.
Inthefollowingsolutions,itisassumedthatsizesoftreesarealsogivenasinput.Ifthesizeisnotgiven,
thenwecangetthesizebytraversingthetree(Seethis).
Method1(Insertelementsoffirsttreetosecond)
TakeallelementsoffirstBSTonebyone,andinsertthemintothesecondBST.Insertinganelementtoa
selfbalancingBSTtakesLogntime(Seethis)wherenissizeoftheBST.Sotimecomplexityofthismethod
isLog(n)+Log(n+1)Log(m+n1).ThevalueofthisexpressionwillbebetweenmLognandmLog(m+n1).
Asanoptimization,wecanpickthesmallertreeasfirsttree.
Method2(MergeInorderTraversals)
1)Doinordertraversaloffirsttreeandstorethetraversalinonetemparrayarr1[].ThissteptakesO(m)
time.
2)Doinordertraversalofsecondtreeandstorethetraversalinanothertemparrayarr2[].Thissteptakes
O(n)time.
3)Thearrayscreatedinstep1and2aresortedarrays.Mergethetwosortedarraysintoonearrayofsizem
+n.ThissteptakesO(m+n)time.
4)Constructabalancedtreefromthemergedarrayusingthetechniquediscussedinthispost.Thisstep
takesO(m+n)time.
TimecomplexityofthismethodisO(m+n)whichisbetterthanmethod1.ThismethodtakesO(m+n)time
eveniftheinputBSTsarenotbalanced.
FollowingisC++implementationofthismethod.
#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;
};

// A utility unction to merge two sorted arrays into one


int *merge(int arr1[], int arr2[], int m, int n);

// A helper function that stores inorder traversal of a tree in inorder array


void storeInorder(struct node* node, int inorder[], int *index_ptr);

/* 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);

/* 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);

// Store inorder traversal of second tree in another array arr2[]


int *arr2 = new int[n];
int j = 0;
storeInorder(root2, arr2, &j);

// Merge the two sorted array into one


int *mergedArr = merge(arr1, arr2, m, n);

// Construct a tree from the merged array and return root of the tree
return sortedArrayToBST (mergedArr, 0, m+n-1);
}

/* 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);
}

// A utility function to print inorder traversal of a given binary tree


void printInorder(struct node* node)
{
if (node == NULL)
return;

/* first recur on left child */


printInorder(node->left);

printf("%d ", node->data);

/* now recur on right child */


printInorder(node->right);
}

// A utility unction to merge two sorted arrays into one


int *merge(int arr1[], int arr2[], int m, int n)
{
// mergedArr[] is going to contain result
int *mergedArr = new int[m + n];

int i = 0, j = 0, k = 0;

// Traverse through both arrays


while (i < m && j < n)
{
// Pick the smaler element and put it in mergedArr
if (arr1[i] < arr2[j])
{
mergedArr[k] = arr1[i];
i++;
}
else
{
mergedArr[k] = arr2[j];
j++;
}
k++;
}

// If there are more elements in first array


while (i < m)
{
mergedArr[k] = arr1[i];
i++; k++;
}

// If there are more elements in second array


while (j < n)
{
mergedArr[k] = arr2[j];
j++; k++;
}

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;

/* first recur on left child */


storeInorder(node->left, inorder, index_ptr);

inorder[*index_ptr] = node->data;
(*index_ptr)++; // increase index for next entry

/* now recur on right child */


storeInorder(node->right, inorder, index_ptr);
}

/* 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;

/* Get the middle element and make it root */


int mid = (start + end)/2;
struct node *root = newNode(arr[mid]);

/* Recursively construct the left subtree and make it


left child of root */
root->left = sortedArrayToBST(arr, start, mid-1);

/* Recursively construct the right subtree and make it


right child of root */
root->right = sortedArrayToBST(arr, mid+1, end);

return root;
}

/* Driver program to test above functions*/


int main()
{
/* Create following tree as first balanced BST
100
/ \
50

300

/\
20 70
*/
struct node *root1 = newNode(100);
root1->left

= newNode(50);

root1->right

= newNode(300);

root1->left->left

= newNode(20);

root1->left->right = newNode(70);

/* Create following tree as second balanced BST


80
/ \
40

120

*/
struct node *root2 = newNode(80);
root2->left

= newNode(40);

root2->right

= newNode(120);

struct node *mergedTree = mergeTrees(root1, root2, 5, 3);

printf ("Following is Inorder traversal of the merged tree \n");


printInorder(mergedTree);

getchar();
return 0;
}
Output:

FollowingisInordertraversalofthemergedtree
2040507080100120300

Method3(InPlaceMergeusingDLL)
WecanuseaDoublyLinkedListtomergetreesinplace.Followingarethesteps.
1)ConvertthegiventwoBinarySearchTreesintodoublylinkedlistinplace(Referthispostforthisstep).
2)MergethetwosortedLinkedLists(Referthispostforthisstep).
3)BuildaBalancedBinarySearchTreefromthemergedlistcreatedinstep2.(Referthispostforthisstep)
TimecomplexityofthismethodisalsoO(m+n)andthismethoddoesconversioninplace.

=======================================================================

AVLTree|Set2(Deletion)
WehavediscussedAVLinsertioninthepreviouspost.Inthispost,wewillfollowasimilarapproachfor
deletion.
Stepstofollowfordeletion.
TomakesurethatthegiventreeremainsAVLaftereverydeletion,wemustaugmentthestandardBST
deleteoperationtoperformsomerebalancing.Followingaretwobasicoperationsthatcanbeperformedto
rebalanceaBSTwithoutviolatingtheBSTproperty(keys(left)<key(root)<keys(right)).
1)LeftRotation
2)RightRotation

T1,T2andT3aresubtreesofthetreerootedwithy(onleftside)
orx(onrightside)
yx
/\RightRotation/\
xT3>T1y
/\</\
T1T2LeftRotationT2T3
Keysinbothoftheabovetreesfollowthefollowingorder
keys(T1)<key(x)<keys(T2)<key(y)<keys(T3)
SoBSTpropertyisnotviolatedanywhere.

Letwbethenodetobedeleted
1)PerformstandardBSTdeleteforw.

2)Startingfromw,travelupandfindthefirstunbalancednode.Letzbethefirstunbalancednode,ybethe
largerheightchildofz,andxbethelargerheightchildofy.Notethatthedefinitionsofxandyaredifferent
frominsertionhere.
3)Rebalancethetreebyperformingappropriaterotationsonthesubtreerootedwithz.Therecanbe4
possiblecasesthatneedstobehandledasx,yandzcanbearrangedin4ways.Followingarethepossible
4arrangements:
a)yisleftchildofzandxisleftchildofy(LeftLeftCase)
b)yisleftchildofzandxisrightchildofy(LeftRightCase)
c)yisrightchildofzandxisrightchildofy(RightRightCase)
d)yisrightchildofzandxisleftchildofy(RightLeftCase)
Likeinsertion,followingaretheoperationstobeperformedinabovementioned4cases.Notethat,unlike
insertion,fixingthenodezwontfixthecompleteAVLtree.Afterfixingz,wemayhavetofixancestorsofz
aswell(Seethisvideolectureforproof)
a)LeftLeftCase

T1,T2,T3andT4aresubtrees.
zy
/\/\
yT4RightRotate(z)xz
/\>/\/\
xT3T1T2T3T4
/\
T1T2

b)LeftRightCase

zzx
/\/\/\
yT4LeftRotate(y)xT4RightRotate(z)yz
/\>/\>/\/\
T1xyT3T1T2T3T4
/\/\
T2T3T1T2

c)RightRightCase

zy
/\/\
T1yLeftRotate(z)zx
/\>/\/\

T2xT1T2T3T4
/\
T3T4

d)RightLeftCase

zzx
/\/\/\
T1yRightRotate(y)T1xLeftRotate(z)zx
/\>/\>/\/\
xT4T2yT1T2T3T4
/\/\
T2T3T3T4

Unlikeinsertion,indeletion,afterweperformarotationatz,wemayhavetoperformarotationatancestors
ofz.Thus,wemustcontinuetotracethepathuntilwereachtheroot.
Cimplementation
FollowingistheCimplementationforAVLTreeDeletion.ThefollowingCimplementationusestherecursive
BSTdeleteasbasis.IntherecursiveBSTdelete,afterdeletion,wegetpointerstoallancestorsonebyone
inbottomupmanner.Sowedontneedparentpointertotravelup.Therecursivecodeitselftravelsupand
visitsalltheancestorsofthedeletednode.
1)PerformthenormalBSTdeletion.
2)Thecurrentnodemustbeoneoftheancestorsofthedeletednode.Updatetheheightofthecurrent
node.
3)Getthebalancefactor(leftsubtreeheightrightsubtreeheight)ofthecurrentnode.
4)Ifbalancefactorisgreaterthan1,thenthecurrentnodeisunbalancedandweareeitherinLeftLeftcase
orLeftRightcase.TocheckwhetheritisLeftLeftcaseorLeftRightcase,getthebalancefactorofleft
subtree.Ifbalancefactoroftheleftsubtreeisgreaterthanorequalto0,thenitisLeftLeftcase,elseLeft
Rightcase.
5)Ifbalancefactorislessthan1,thenthecurrentnodeisunbalancedandweareeitherinRightRightcase
orRightLeftcase.TocheckwhetheritisRightRightcaseorRightLeftcase,getthebalancefactorofright
subtree.Ifthebalancefactoroftherightsubtreeissmallerthanorequalto0,thenitisRightRightcase,
elseRightLeftcase.
#include<stdio.h>
#include<stdlib.h>

// An AVL tree node


struct node

{
int key;
struct node *left;
struct node *right;
int height;
};

// A utility function to get maximum of two integers


int max(int a, int b);

// A utility function to get height of the tree


int height(struct node *N)
{
if (N == NULL)
return 0;
return N->height;
}

// A utility function to get maximum of two integers


int max(int a, int b)
{
return (a > b)? a : b;
}

/* 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
node->left

= key;
= NULL;

node->right = NULL;
node->height = 1; // new node is initially added at leaf
return(node);
}

// A utility function to right rotate subtree rooted with y


// See the diagram given above.
struct node *rightRotate(struct node *y)
{
struct node *x = y->left;
struct node *T2 = x->right;

// 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;

// Return new root


return x;
}

// A utility function to left rotate subtree rooted with x


// See the diagram given above.
struct node *leftRotate(struct node *x)
{
struct node *y = x->right;
struct node *T2 = y->left;

// 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;

// Return new root


return y;
}

// Get Balance factor of node N


int getBalance(struct node *N)
{
if (N == NULL)
return 0;
return height(N->left) - height(N->right);
}

struct node* insert(struct node* node, int key)


{
/* 1. Perform the normal BST rotation */
if (node == NULL)
return(newNode(key));

if (key < node->key)


node->left = insert(node->left, key);
else
node->right = insert(node->right, key);

/* 2. Update height of this ancestor node */


node->height = max(height(node->left), height(node->right)) + 1;

/* 3. Get the balance factor of this ancestor node to check whether


this node became unbalanced */
int balance = getBalance(node);

// If this node becomes unbalanced, then there are 4 cases

// Left Left Case


if (balance > 1 && key < node->left->key)
return rightRotate(node);

// Right Right Case


if (balance < -1 && key > node->right->key)
return leftRotate(node);

// Left Right Case


if (balance > 1 && key > node->left->key)
{
node->left = leftRotate(node->left);
return rightRotate(node);
}

// Right Left Case


if (balance < -1 && key < node->right->key)
{
node->right = rightRotate(node->right);
return leftRotate(node);
}

/* return the (unchanged) node pointer */


return node;
}

/* 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;

/* loop down to find the leftmost leaf */


while (current->left != NULL)
current = current->left;

return current;
}

struct node* deleteNode(struct node* root, int key)


{
// STEP 1: PERFORM STANDARD BST DELETE

if (root == NULL)

return root;

// If the key to be deleted is smaller than the root's key,


// then it lies in left subtree
if ( key < root->key )
root->left = deleteNode(root->left, key);

// If the key to be deleted is greater than the root's key,


// then it lies in right subtree
else if( key > root->key )
root->right = deleteNode(root->right, key);

// if key is same as root's key, then This is the node


// to be deleted
else
{
// node with only one child or no child
if( (root->left == NULL) || (root->right == NULL) )
{
struct node *temp = root->left ? root->left : root->right;

// 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);

// Copy the inorder successor's data to this node


root->key = temp->key;

// Delete the inorder successor


root->right = deleteNode(root->right, temp->key);
}
}

// If the tree had only one node then return


if (root == NULL)
return root;

// STEP 2: UPDATE HEIGHT OF THE CURRENT NODE


root->height = max(height(root->left), height(root->right)) + 1;

// STEP 3: GET THE BALANCE FACTOR OF THIS NODE (to check whether
// this node became unbalanced)
int balance = getBalance(root);

// If this node becomes unbalanced, then there are 4 cases

// Left Left Case


if (balance > 1 && getBalance(root->left) >= 0)
return rightRotate(root);

// Left Right Case


if (balance > 1 && getBalance(root->left) < 0)
{
root->left = leftRotate(root->left);
return rightRotate(root);
}

// Right Right Case


if (balance < -1 && getBalance(root->right) <= 0)
return leftRotate(root);

// Right Left Case


if (balance < -1 && getBalance(root->right) > 0)
{
root->right = rightRotate(root->right);
return leftRotate(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);
}
}

/* Drier program to test above function*/


int main()
{
struct node *root = NULL;

/* Constructing tree given in the above figure */


root = insert(root, 9);
root = insert(root, 5);
root = insert(root, 10);
root = insert(root, 0);
root = insert(root, 6);
root = insert(root, 11);
root = insert(root, -1);
root = insert(root, 1);
root = insert(root, 2);

/* The constructed AVL Tree would be


9
/ \
1 10
/ \\
0
/

11

/ \

-1

2 6

*/

printf("Pre order traversal of the constructed AVL tree is \n");


preOrder(root);

root = deleteNode(root, 10);

/* The AVL Tree after deletion of 10


1
/ \
0 9
/
-1

/ \
5

11

/ \
2 6
*/

printf("\nPre order traversal after deletion of 10 \n");


preOrder(root);

return 0;
}
Output:

PreordertraversaloftheconstructedAVLtreeis
91015261011
Preordertraversalafterdeletionof10
101952611

TimeComplexity:Therotationoperations(leftandrightrotate)takeconstanttimeasonlyfewpointersare
beingchangedthere.Updatingtheheightandgettingthebalancefactoralsotakeconstanttime.Sothetime
complexityofAVLdeleteremainssameasBSTdeletewhichisO(h)wherehisheightofthetree.Since
AVLtreeisbalanced,theheightisO(Logn).SotimecomplexityofAVLdeleteisO(Logn).

=======================================================================

VerticalSuminagivenBinaryTree
GivenaBinaryTree,findverticalsumofthenodesthatareinsameverticalline.Printallsumsthrough
differentverticallines.
Examples:

1
/\
23
/\/\
4567

Thetreehas5verticallines
VerticalLine1hasonlyonenode4=>verticalsumis4
VerticalLine2:hasonlyonenode2=>verticalsumis2
VerticalLine3:hasthreenodes:1,5,6=>verticalsumis1+5+6=12
VerticalLine4:hasonlyonenode3=>verticalsumis3
VerticalLine5:hasonlyonenode7=>verticalsumis7
Soexpectedoutputis4,2,12,3and7
Solution:
WeneedtochecktheHorizontalDistancesfromrootforallnodes.IftwonodeshavethesameHorizontal
Distance(HD),thentheyareonsameverticalline.TheideaofHDissimple.HDforrootis0,arightedge
(edgeconnectingtorightsubtree)isconsideredas+1horizontaldistanceandaleftedgeisconsideredas
1horizontaldistance.Forexample,intheabovetree,HDforNode4isat2,HDforNode2is1,HDfor5
and6is0andHDfornode7is+2.
WecandoinordertraversalofthegivenBinaryTree.Whiletraversingthetree,wecanrecursivelycalculate
HDs.Weinitiallypassthehorizontaldistanceas0forroot.Forleftsubtree,wepasstheHorizontalDistance
asHorizontaldistanceofrootminus1.Forrightsubtree,wepasstheHorizontalDistanceasHorizontal
Distanceofrootplus1.

FollowingisJavaimplementationforthesame.HashMapisusedtostoretheverticalsumsfordifferent
horizontaldistances.ThankstoNagesforsuggestingthismethod.
import java.util.HashMap;

// Class for a tree node


class TreeNode {

// 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; }

// Methods to set left and right subtrees


public void setLeft(TreeNode left)

{ this.left = left; }

public void setRight(TreeNode right) { this.right = right; }


}

// Class for a Binary Tree


class Tree {

private TreeNode root;

// Constructors
public Tree() { root = null; }
public Tree(TreeNode n) { root = n; }

// Method to be called by the consumer classes like Main class


public void VerticalSumMain() { VerticalSum(root); }

// A wrapper over VerticalSumUtil()


private void VerticalSum(TreeNode root) {

// base case
if (root == null) { return; }

// Creates an empty hashMap hM


HashMap<Integer, Integer> hM = new HashMap<Integer, Integer>();

// Calls the VerticalSumUtil() to store the vertical sum values in hM


VerticalSumUtil(root, 0, hM);

// Prints the values stored by VerticalSumUtil()


if (hM != null) {
System.out.println(hM.entrySet());
}
}

// Traverses the tree in Inoorder form and builds a hashMap hM that


// contains the vertical sum
private void VerticalSumUtil(TreeNode root, int hD,
HashMap<Integer, Integer> hM) {

// base case
if (root == null) { return; }

// Store the values in hM for left subtree


VerticalSumUtil(root.left(), hD - 1, hM);

// Update vertical sum for hD of this node


int prevSum = (hM.get(hD) == null) ? 0 : hM.get(hD);
hM.put(hD, prevSum + root.key());

// Store the values in hM for right subtree


VerticalSumUtil(root.right(), hD + 1, hM);
}
}

// Driver class to test the verticalSum methods


public class Main {

public static void main(String[] args) {


/* Create following Binary Tree
1
/\
2

/\
4

56

/\
7

*/
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);

System.out.println("Following are the values of vertical sums with "


+ "the positions of the columns with respect to root ");
t.VerticalSumMain();
}
}
Seethisforasamplerun.
TimeComplexity:O(n)

==================================================================================

AVLTree|Set1(Insertion)
AVLtreeisaselfbalancingBinarySearchTree(BST)wherethedifferencebetweenheightsofleftandright
subtreescannotbemorethanoneforallnodes.
WhyAVLTrees?

MostoftheBSToperations(e.g.,search,max,min,insert,delete..etc)takeO(h)timewherehistheheight
oftheBST.ThecostoftheseoperationsmaybecomeO(n)foraskewedBinarytree.Ifwemakesurethat
heightofthetreeremainsO(Logn)aftereveryinsertionanddeletion,thenwecanguaranteeanupper
boundofO(Logn)foralltheseoperations.TheheightofanAVLtreeisalwaysO(Logn)wherenisthe
numberofnodesinthetree(Seethisvideolectureforproof).
Insertion
TomakesurethatthegiventreeremainsAVLaftereveryinsertion,wemustaugmentthestandardBST
insertoperationtoperformsomerebalancing.Followingaretwobasicoperationsthatcanbeperformedto
rebalanceaBSTwithoutviolatingtheBSTproperty(keys(left)<key(root)<keys(right)).
1)LeftRotation
2)RightRotation

T1,T2andT3aresubtreesofthetreerootedwithy(onleftside)
orx(onrightside)

yx
/\RightRotation/\
xT3>T1y
/\</\
T1T2LeftRotationT2T3
Keysinbothoftheabovetreesfollowthefollowingorder
keys(T1)<key(x)<keys(T2)<key(y)<keys(T3)
SoBSTpropertyisnotviolatedanywhere.

Stepstofollowforinsertion
Letthenewlynsertednodebew
1)PerformstandardBSTinsertforw.
2)Startingfromw,travelupandfindthefirstunbalancednode.Letzbethefirstunbalancednode,ybethe
childofzthatcomesonthepathfromwtozandxbethegrandchildofzthatcomesonthepathfromwto
z.
3)Rebalancethetreebyperformingappropriaterotationsonthesubtreerootedwithz.Therecanbe4
possiblecasesthatneedstobehandledasx,yandzcanbearrangedin4ways.Followingarethepossible
4arrangements:
a)yisleftchildofzandxisleftchildofy(LeftLeftCase)
b)yisleftchildofzandxisrightchildofy(LeftRightCase)
c)yisrightchildofzandxisrightchildofy(RightRightCase)
d)yisrightchildofzandxisleftchildofy(RightLeftCase)
Followingaretheoperationstobeperformedinabovementioned4cases.Inallofthecases,weonlyneed
torebalancethesubtreerootedwithzandthecompletetreebecomesbalancedastheheightofsubtree

(Afterappropriaterotations)rootedwithzbecomessameasitwasbeforeinsertion.(Seethisvideolecture
forproof)
a)LeftLeftCase

T1,T2,T3andT4aresubtrees.
zy
/\/\
yT4RightRotate(z)xz
/\>/\/\
xT3T1T2T3T4
/\
T1T2

b)LeftRightCase

zzx
/\/\/\
yT4LeftRotate(y)xT4RightRotate(z)yz
/\>/\>/\/\
T1xyT3T1T2T3T4
/\/\
T2T3T1T2

c)RightRightCase

zy
/\/\
T1yLeftRotate(z)zx
/\>/\/\
T2xT1T2T3T4
/\
T3T4

d)RightLeftCase

zzx
/\/\/\
T1yRightRotate(y)T1xLeftRotate(z)zy
/\>/\>/\/\
xT4T2yT1T2T3T4
/\/\

T2T3T3T4

Cimplementation
FollowingistheCimplementationforAVLTreeInsertion.ThefollowingCimplementationusestherecursive
BSTinserttoinsertanewnode.IntherecursiveBSTinsert,afterinsertion,wegetpointerstoallancestors
onebyoneinbottomupmanner.Sowedontneedparentpointertotravelup.Therecursivecodeitself
travelsupandvisitsalltheancestorsofthenewlyinsertednode.
1)PerformthenormalBSTinsertion.
2)Thecurrentnodemustbeoneoftheancestorsofthenewlyinsertednode.Updatetheheightofthe
currentnode.
3)Getthebalancefactor(leftsubtreeheightrightsubtreeheight)ofthecurrentnode.
4)Ifbalancefactorisgreaterthan1,thenthecurrentnodeisunbalancedandweareeitherinLeftLeftcase
orleftRightcase.Tocheckwhetheritisleftleftcaseornot,comparethenewlyinsertedkeywiththekeyin
leftsubtreeroot.
5)Ifbalancefactorislessthan1,thenthecurrentnodeisunbalancedandweareeitherinRightRightcase
orRightLeftcase.TocheckwhetheritisRightRightcaseornot,comparethenewlyinsertedkeywiththe
keyinrightsubtreeroot.
#include<stdio.h>
#include<stdlib.h>

// An AVL tree node


struct node
{
int key;
struct node *left;
struct node *right;
int height;
};

// A utility function to get maximum of two integers


int max(int a, int b);

// A utility function to get height of the tree


int height(struct node *N)
{
if (N == NULL)
return 0;

return N->height;
}

// A utility function to get maximum of two integers


int max(int a, int b)
{
return (a > b)? a : b;
}

/* 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
node->left

= key;
= NULL;

node->right = NULL;
node->height = 1; // new node is initially added at leaf
return(node);
}

// A utility function to right rotate subtree rooted with y


// See the diagram given above.
struct node *rightRotate(struct node *y)
{
struct node *x = y->left;
struct node *T2 = x->right;

// 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;

// Return new root


return x;
}

// A utility function to left rotate subtree rooted with x


// See the diagram given above.
struct node *leftRotate(struct node *x)
{
struct node *y = x->right;
struct node *T2 = y->left;

// 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;

// Return new root


return y;
}

// Get Balance factor of node N


int getBalance(struct node *N)
{
if (N == NULL)
return 0;
return height(N->left) - height(N->right);
}

struct node* insert(struct node* node, int key)


{
/* 1. Perform the normal BST rotation */
if (node == NULL)
return(newNode(key));

if (key < node->key)


node->left = insert(node->left, key);
else
node->right = insert(node->right, key);

/* 2. Update height of this ancestor node */


node->height = max(height(node->left), height(node->right)) + 1;

/* 3. Get the balance factor of this ancestor node to check whether


this node became unbalanced */
int balance = getBalance(node);

// If this node becomes unbalanced, then there are 4 cases

// Left Left Case


if (balance > 1 && key < node->left->key)
return rightRotate(node);

// Right Right Case


if (balance < -1 && key > node->right->key)
return leftRotate(node);

// Left Right Case


if (balance > 1 && key > node->left->key)
{
node->left = leftRotate(node->left);
return rightRotate(node);
}

// Right Left Case


if (balance < -1 && key < node->right->key)
{
node->right = rightRotate(node->right);
return leftRotate(node);
}

/* return the (unchanged) node pointer */

return node;
}

// 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);
}
}

/* Drier program to test above function*/


int main()
{
struct node *root = NULL;

/* Constructing tree given in the above figure */


root = insert(root, 10);
root = insert(root, 20);
root = insert(root, 30);
root = insert(root, 40);
root = insert(root, 50);
root = insert(root, 25);

/* The constructed AVL Tree would be


30
/ \
20

40

/ \\
10 2550
*/

printf("Pre order traversal of the constructed AVL tree is \n");

preOrder(root);

return 0;
}
Output:

PreordertraversaloftheconstructedAVLtreeis
302010254050

TimeComplexity:Therotationoperations(leftandrightrotate)takeconstanttimeasonlyfewpointersare
beingchangedthere.Updatingtheheightandgettingthebalancefactoralsotakeconstanttime.Sothetime
complexityofAVLinsertremainssameasBSTinsertwhichisO(h)wherehisheightofthetree.SinceAVL
treeisbalanced,theheightisO(Logn).SotimecomplexityofAVLinsertisO(Logn).
TheAVLtreeandotherselfbalancingsearchtreeslikeRedBlackareusefultogetallbasicoperationsdone
inO(Logn)time.TheAVLtreesaremorebalancedcomparedtoRedBlackTrees,buttheymaycausemore
rotationsduringinsertionanddeletion.Soifyourapplicationinvolvesmanyfrequentinsertionsand
deletions,thenRedBlacktreesshouldbepreferred.Andiftheinsertionsanddeletionsarelessfrequent
andsearchismorefrequentoperation,thenAVLtreeshouldbepreferredoverRedBlackTree.
Followingaresomepreviouspoststhathaveusedselfbalancingsearchtrees.
Medianinastreamofintegers(runningintegers)
Maximumofallsubarraysofsizek
Countsmallerelementsonrightside

=======================================================================

FindthelargestBSTsubtreeina
givenBinaryTree
GivenaBinaryTree,writeafunctionthatreturnsthesizeofthelargestsubtreewhichisalsoaBinary
SearchTree(BST).IfthecompleteBinaryTreeisBST,thenreturnthesizeofwholetree.
Examples:

Input:
5
/\
24
/\

13

Output:3
ThefollowingsubtreeisthemaximumsizeBSTsubtree
2
/\
13

Input:
50
/\
3060
/\/\
5204570
/\
6580
Output:5
ThefollowingsubtreeisthemaximumsizeBSTsubtree
60
/\
4570
/\
6580

Method1(Simplebutinefficient)
Startfromrootanddoaninordertraversalofthetree.ForeachnodeN,checkwhetherthesubtreerooted
withNisBSTornot.IfBST,thenreturnsizeofthesubtreerootedwithN.Else,recurdowntheleftandright
subtreesandreturnthemaximumofvaluesreturnedbyleftandrightsubtrees.
/*
See http://www.geeksforgeeks.org/archives/632 for implementation of size()

See Method 3 of http://www.geeksforgeeks.org/archives/3042 for


implementation of isBST()

max() returns maximum of two integers


*/

int largestBST(struct node *root)


{
if (isBST(root))
return size(root);
else
return max(largestBST(root->left), largestBST(root->right));
}
TimeComplexity:TheworstcasetimecomplexityofthismethodwillbeO(n^2).Consideraskewedtreefor
worstcaseanalysis.

Method2(TrickyandEfficient)
Inmethod1,wetraversethetreeintopdownmanneranddoBSTtestforeverynode.Ifwetraversethe
treeinbottomupmanner,thenwecanpassinformationaboutsubtreestotheparent.Thepassed
informationcanbeusedbytheparenttodoBSTtest(forparentnode)onlyinconstanttime(orO(1)time).
AleftsubtreeneedtotelltheparentwhetheritisBSTornotandalsoneedtopassmaximumvalueinit.So
thatwecancomparethemaximumvaluewiththeparentsdatatochecktheBSTproperty.Similarly,the
rightsubtreeneedtopasstheminimumvalueupthetree.Thesubtreesneedtopassthefollowing
informationupthetreeforthefindingthelargestBST.
1)WhetherthesubtreeitselfisBSTornot(Inthefollowingcode,is_bst_refisusedforthispurpose)
2)Ifthesubtreeisleftsubtreeofitsparent,thenmaximumvalueinit.Andifitisrightsubtreethenminimum
valueinit.
3)SizeofthissubtreeifthissubtreeisBST(Inthefollowingcode,returnvalueoflargestBSTtil()isusedfor
thispurpose)
max_refisusedforpassingthemaximumvalueupthetreeandmin_ptrisusedforpassingminimumvalue
upthetree.
#include <stdio.h>
#include <stdlib.h>
#include <limits.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;

};

/* 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);
}

int largestBSTUtil(struct node* node, int *min_ref, int *max_ref,


int *max_size_ref, bool *is_bst_ref);

/* Returns size of the largest BST subtree in a Binary Tree


(efficient version). */
int largestBST(struct node* node)
{
// Set the initial values for calling largestBSTUtil()
int min = INT_MAX; // For minimum value in right subtree
int max = INT_MIN; // For maximum value in left subtree

int max_size = 0; // For size of the largest BST


bool is_bst = 0;

largestBSTUtil(node, &min, &max, &max_size, &is_bst);

return max_size;
}

/* largestBSTUtil() updates *max_size_ref for the size of the largest BST


subtree.

Also, if the tree rooted with node is non-empty and a BST,

then returns size of the tree. Otherwise returns 0.*/

int largestBSTUtil(struct node* node, int *min_ref, int *max_ref,


int *max_size_ref, bool *is_bst_ref)
{

/* Base Case */
if (node == NULL)
{
*is_bst_ref = 1; // An empty tree is BST
return 0;

// Size of the BST is 0

int min = INT_MAX;

/* A flag variable for left subtree property


i.e., max(root->left) < root->data */
bool left_flag = false;

/* A flag variable for right subtree property


i.e., min(root->right) > root->data */
bool right_flag = false;

int ls, rs; // To store sizes of left and right subtrees

/* Following tasks are done by recursive call for left subtree


a) Get the maximum value in left subtree (Stored in *max_ref)
b) Check whether Left Subtree is BST or not (Stored in *is_bst_ref)
c) Get the size of maximum size BST in left subtree (updates *max_size) */
*max_ref = INT_MIN;
ls = largestBSTUtil(node->left, min_ref, max_ref, max_size_ref, is_bst_ref);
if (*is_bst_ref == 1 && node->data > *max_ref)
left_flag = true;

/* 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;

/* The following recursive call does similar (similar to left subtree)

task for right subtree */


*min_ref = INT_MAX;
rs = largestBSTUtil(node->right, min_ref, max_ref, max_size_ref, is_bst_ref);
if (*is_bst_ref == 1 && node->data < *min_ref)
right_flag = true;

// 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;
}
}

/* Driver program to test above functions*/


int main()
{
/* Let us construct the following Tree
50
/

10

60

/ \
5

/ \

20

55
/
45 65

70
/ \
80

*/

struct node *root = newNode(50);


root->left

= newNode(10);

root->right

= newNode(60);

root->left->left = newNode(5);
root->left->right = newNode(20);
root->right->left = newNode(55);
root->right->left->left = newNode(45);
root->right->right = newNode(70);
root->right->right->left = newNode(65);
root->right->right->right = newNode(80);

/* The complete tree is not BST as 45 is in right subtree of 50.


The following subtree is the largest BST
60
/ \
5570
/
45

/ \
65

80

*/
printf(" Size of the largest BST is %d", largestBST(root));

getchar();
return 0;
}
TimeComplexity:O(n)wherenisthenumberofnodesinthegivenBinaryTree.

================================================================
=======

ConvertagiventreetoitsSumTree
GivenaBinaryTreewhereeachnodehaspositiveandnegativevalues.Convertthistoatreewhereeach
nodecontainsthesumoftheleftandrightsubtreesintheoriginaltree.Thevaluesofleafnodesare
changedto0.
Forexample,thefollowingtree

10
/\
26
/\/\
8475

shouldbechangedto

20(42+12+6)
/\
4(84)12(7+5)
/\/\
0000

Solution:
Doatraversalofthegiventree.Inthetraversal,storetheoldvalueofthecurrentnode,recursivelycallfor
leftandrightsubtreesandchangethevalueofcurrentnodeassumofthevaluesreturnedbytherecursive
calls.Finallyreturnthesumofnewvalueandvalue(whichissumofvaluesinthesubtreerootedwiththis
node).
#include<stdio.h>

/* A tree node structure */


struct node
{
int data;
struct node *left;
struct node *right;
};

// 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;

// Store the old value


int old_val = node->data;

// 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;
}

// A utility function to print inorder traversal of a Binary Tree


void printInorder(struct node* node)
{
if (node == NULL)
return;
printInorder(node->left);
printf("%d ", node->data);
printInorder(node->right);
}

/* Utility function to create a new Binary Tree node */


struct node* newNode(int data)
{
struct node *temp = new struct node;
temp->data = data;
temp->left = NULL;

temp->right = NULL;

return temp;
}

/* Driver function to test above functions */


int main()
{
struct node *root = NULL;
int x;

/* Constructing tree given in the above figure */


root = newNode(10);
root->left = newNode(-2);
root->right = newNode(6);
root->left->left = newNode(8);
root->left->right = newNode(-4);
root->right->left = newNode(7);
root->right->right = newNode(5);

toSumTree(root);

// Print inorder traversal of the converted tree to test result of toSumTree()


printf("Inorder Traversal of the resultant tree is: \n");
printInorder(root);

getchar();
return 0;
}
Output:

InorderTraversaloftheresultanttreeis:
040200120

TimeComplexity:Thesolutioninvolvesasimpletraversalofthegiventree.SothetimecomplexityisO(n)
wherenisthenumberofnodesinthegivenBinaryTree.

=======================================================================

PopulateInorderSuccessorforall
nodes
GivenaBinaryTreewhereeachnodehasfollowingstructure,writeafunctiontopopulatenextpointerforall
nodes.Thenextpointerforeverynodeshouldbesettopointtoinordersuccessor.
struct node
{
int data;
struct node* left;
struct node* right;
struct node* next;
}
Initially,allnextpointershaveNULLvalues.Yourfunctionshouldfillthesenextpointerssothattheypointto
inordersuccessor.
Solution(UseReverseInorderTraversal)
Traversethegiventreeinreverseinordertraversalandkeeptrackofpreviouslyvisitednode.Whenanode
isbeingvisited,assignpreviouslyvisitednodeasnext.
#include <stdio.h>
#include <stdlib.h>

struct node
{
int data;
struct node *left;
struct node *right;
struct node *next;
};

/* Set next of p and all descendents of p by traversing them in reverse Inorder */


void populateNext(struct node* p)
{
// The first visited node will be the rightmost node
// next of the rightmost node will be NULL
static struct node *next = NULL;

if (p)
{
// First set the next pointer in right subtree
populateNext(p->right);

// Set the next as previously visited node in reverse Inorder


p->next = next;

// Change the prev for subsequent node


next = p;

// Finally, set the next pointer in left subtree


populateNext(p->left);
}
}

/* 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);
}

/* Driver program to test above functions*/


int main()
{

/* Constructed binary tree is


10

8 12
/
3
*/
struct node *root = newnode(10);
root->left

= newnode(8);

root->right

= newnode(12);

root->left->left = newnode(3);

// Populates nextRight pointer in all nodes


populateNext(root);

// Let us see the populated values


struct node *ptr = root->left->left;
while(ptr)
{
// -1 is printed if there is no successor
printf("Next of %d is %d \n", ptr->data, ptr->next? ptr->next->data: -1);
ptr = ptr->next;
}

return 0;
}
Wecanavoidtheuseofstaticvariablebypassingreferencetonextasparamater.
// An implementation that doesn't use static variable

// A wrapper over populateNextRecur


void populateNext(struct node *root)
{
// The first visited node will be the rightmost node
// next of the rightmost node will be NULL
struct node *next = NULL;

populateNextRecur(root, &next);
}

/* Set next of all descendents of p by traversing them in reverse Inorder */


void populateNextRecur(struct node* p, struct node **next_ref)
{
if (p)
{
// First set the next pointer in right subtree
populateNextRecur(p->right, next_ref);

// Set the next as previously visited node in reverse Inorder


p->next = *next_ref;

// Change the prev for subsequent node


*next_ref = p;

// Finally, set the next pointer in right subtree


populateNextRecur(p->left, next_ref);
}
}
TimeComplexity:O(n)

=======================================================================

SortedArraytoBalancedBST
Givenasortedarray.WriteafunctionthatcreatesaBalancedBinarySearchTreeusingarrayelements.
Examples:

Input:Array{1,2,3}
Output:ABalancedBST
2
/\
13

Input:Array{1,2,3,4}
Output:ABalancedBST
3
/\

24
/
1

Algorithm
Inthepreviouspost,wediscussedconstructionofBSTfromsortedLinkedList.Constructingfromsorted
arrayinO(n)timeissimpleraswecangetthemiddleelementinO(1)time.Followingisasimplealgorithm
wherewefirstfindthemiddlenodeoflistandmakeitrootofthetreetobeconstructed.

1)GettheMiddleofthearrayandmakeitroot.
2)Recursivelydosameforlefthalfandrighthalf.
a)Getthemiddleoflefthalfandmakeitleftchildoftheroot
createdinstep1.
b)Getthemiddleofrighthalfandmakeitrightchildofthe
rootcreatedinstep1.

FollowingisCimplementationoftheabovealgorithm.ThemaincodewhichcreatesBalancedBSTis
highlighted.
#include<stdio.h>
#include<stdlib.h>

/* A Binary Tree node */


struct TNode
{
int data;
struct TNode* left;
struct TNode* right;
};

struct TNode* newNode(int data);

/* 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;

/* Get the middle element and make it root */


int mid = (start + end)/2;
struct TNode *root = newNode(arr[mid]);

/* Recursively construct the left subtree and make it


left child of root */
root->left = sortedArrayToBST(arr, start, mid-1);

/* Recursively construct the right subtree and make it


right child of root */
root->right = sortedArrayToBST(arr, mid+1, end);

return root;
}

/* Helper function that allocates a new node with the


given data and NULL left and right pointers. */
struct TNode* newNode(int data)
{
struct TNode* node = (struct TNode*)
malloc(sizeof(struct TNode));
node->data = data;
node->left = NULL;
node->right = NULL;

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);
}

/* Driver program to test above functions */


int main()
{
int arr[] = {1, 2, 3, 4, 5, 6, 7};
int n = sizeof(arr)/sizeof(arr[0]);

/* Convert List to BST */


struct TNode *root = sortedArrayToBST(arr, 0, n-1);
printf("\n PreOrder Traversal of constructed BST ");
preOrder(root);

return 0;
}
TimeComplexity:O(n)
FollowingistherecurrancerelationforsortedArrayToBST().

T(n)=2T(n/2)+C
T(n)>Timetakenforanarrayofsizen
C>Constant(Findingmiddleofarrayandlinkingroottoleft
andrightsubtreestakeconstanttime)

TheaboverecurrencecanbesolvedusingMasterTheoremasitfallsincase2.

================================================================
=======

Connectnodesatsamelevelusing
constantextraspace
Writeafunctiontoconnectalltheadjacentnodesatthesamelevelinabinarytree.Structureofthegiven
BinaryTreenodeislikefollowing.
struct node {
int data;
struct node* left;
struct node* right;

struct node* nextRight;


}
Initially,allthenextRightpointerspointtogarbagevalues.Yourfunctionshouldsetthesepointerstopoint
nextrightforeachnode.Youcanuseonlyconstantextraspace.
Example

InputTree
A
/\
BC
/\\
DEF

OutputTree
A>NULL
/\
B>C>NULL
/\\
D>E>F>NULL

Wediscussedtwodifferentapproachestodoitinthepreviouspost.Theauxiliaryspacerequiredinbothof
thoseapproachesisnotconstant.Also,themethod2discussedthereonlyworksforcompleteBinaryTree.
Inthispost,wewillfirstmodifythemethod2tomakeitworkforallkindoftrees.Afterthat,wewillremove
recursionfromthismethodsothattheextraspacebecomesconstant.
ARecursiveSolution
Inthemethod2ofpreviouspost,wetraversedthenodesinpreorderfashion.InsteadoftraversinginPre
Orderfashion(root,left,right),ifwetraversethenextRightnodebeforetheleftandrightchildren(root,
nextRight,left),thenwecanmakesurethatallnodesatlevelihavethenextRightset,beforetheleveli+1
nodes.Letusconsiderthefollowingexample(sameexampleaspreviouspost).Themethod2failsforright
childofnode4.Inthismethod,wemakesurethatallnodesatthe4slevel(level2)havenextRightset,
beforewetrytosetthenextRightof9.SowhenwesetthenextRightof9,wesearchforanonleafnodeon
rightsideofnode4(getNextRight()doesthisforus).

1Level0
/\
23Level1
/\/\
4567Level2
/\/\

891011Level3

void connectRecur(struct node* p);


struct node *getNextRight(struct node *p);

// 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;

/* Before setting nextRight of left and right children, set nextRight


of children of other nodes at same level (because we can access
children of other nodes using p's nextRight only) */
if (p->nextRight != NULL)
connectRecur(p->nextRight);

/* Set the nextRight pointer for p's left child */


if (p->left)
{
if (p->right)
{
p->left->nextRight = p->right;
p->right->nextRight = getNextRight(p);
}

else
p->left->nextRight = getNextRight(p);

/* 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;

/* Traverse nodes at p's level and find and return


the first node's first child */
while(temp != NULL)
{
if(temp->left != NULL)
return temp->left;
if(temp->right != NULL)
return temp->right;
temp = temp->nextRight;
}

// If all the nodes at p's level are leaf nodes then return NULL
return NULL;
}

AnIterativeSolution
Therecursiveapproachdiscussedabovecanbeeasilyconvertedtoiterative.Intheiterativeversion,weuse
nestedloop.Theouterloop,goesthroughallthelevelsandtheinnerloopgoesthroughallthenodesat
everylevel.Thissolutionusesconstantspace.
#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;

/* Traverse nodes at p's level and find and return


the first node's first child */
while (temp != NULL)
{
if (temp->left != NULL)
return temp->left;
if (temp->right != NULL)
return temp->right;
temp = temp->nextRight;
}

// If all the nodes at p's level are leaf nodes then return NULL
return NULL;
}

/* Sets nextRight of all nodes of a tree with root as p */


void connect(struct node* p)
{
struct node *temp;

if (!p)
return;

// Set nextRight for root


p->nextRight = NULL;

// set nextRight of all levels one by one


while (p != NULL)
{
struct node *q = p;

/* Connect all childrem nodes of p and children nodes of all other nodes
at same level as p */
while (q != NULL)
{
// Set the nextRight pointer for p's left child
if (q->left)
{
// If q has right child, then right child is nextRight of
// p and we also need to set nextRight of right child
if (q->right)
q->left->nextRight = q->right;
else
q->left->nextRight = getNextRight(q);
}

if (q->right)

q->right->nextRight = getNextRight(q);

// Set nextRight for other nodes in pre order fashion


q = q->nextRight;
}

// start from the first node of next level


if (p->left)
p = p->left;
else if (p->right)
p = p->right;
else
p = getNextRight(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);
}

/* Driver program to test above functions*/


int main()
{

/* Constructed binary tree is


10

8 2
/

90

*/
struct node *root = newnode(10);
root->left

= newnode(8);

root->right

= newnode(2);

root->left->left = newnode(3);
root->right->right

= newnode(90);

// Populates nextRight pointer in all nodes


connect(root);

// Let us check the values of nextRight pointers


printf("Following are populated nextRight pointers in the tree "
"(-1 is printed if there is no nextRight) \n");
printf("nextRight of %d is %d \n", root->data,
root->nextRight? root->nextRight->data: -1);
printf("nextRight of %d is %d \n", root->left->data,
root->left->nextRight? root->left->nextRight->data: -1);
printf("nextRight of %d is %d \n", root->right->data,
root->right->nextRight? root->right->nextRight->data: -1);
printf("nextRight of %d is %d \n", root->left->left->data,
root->left->left->nextRight? root->left->left->nextRight->data: -1);
printf("nextRight of %d is %d \n", root->right->right->data,
root->right->right->nextRight? root->right->right->nextRight->data: -1);

getchar();
return 0;
}
Output:

FollowingarepopulatednextRightpointersinthetree(1isprintedif
thereisnonextRight)
nextRightof10is1
nextRightof8is2
nextRightof2is1

nextRightof3is90
nextRightof90is1

=======================================================================

Connectnodesatsamelevel
Writeafunctiontoconnectalltheadjacentnodesatthesamelevelinabinarytree.Structureofthegiven
BinaryTreenodeislikefollowing.
struct node{
int data;
struct node* left;
struct node* right;
struct node* nextRight;
}
Initially,allthenextRightpointerspointtogarbagevalues.Yourfunctionshouldsetthesepointerstopoint
nextrightforeachnode.
Example

InputTree
A
/\
BC
/\\
DEF

OutputTree
A>NULL
/\
B>C>NULL
/\\
D>E>F>NULL

Method1(ExtendLevelOrderTraversalorBFS)

Considerthemethod2ofLevelOrderTraversal.Themethod2caneasilybeextendedtoconnectnodesof
samelevel.Wecanaugmentqueueentriestocontainlevelofnodesalsowhichis0forroot,1forroots
childrenandsoon.Soaqueuenodewillnowcontainapointertoatreenodeandanintegerlevel.Whenwe
enqueueanode,wemakesurethatcorrectlevelvaluefornodeisbeingsetinqueue.TosetnextRight,for
everynodeN,wedequeuethenextnodefromqueue,ifthelevelnumberofnextnodeissame,wesetthe
nextRightofNasaddressofthedequeuednode,otherwisewesetnextRightofNasNULL.
TimeComplexity:O(n)
Method2(ExtendPreOrderTraversal)
ThisapproachworksonlyforCompleteBinaryTrees.InthismethodwesetnextRightinPreOrderfashion
tomakesurethatthenextRightofparentissetbeforeitschildren.Whenweareatnodep,wesetthe
nextRightofitsleftandrightchildren.Sincethetreeiscompletetree,nextRightofpsleftchild
(p>left>nextRight)willalwaysbepsrightchild,andnextRightofpsrightchild(p>right>nextRight)will
alwaysbeleftchildofpsnextRight(ifpisnottherightmostnodeatitslevel).Ifpistherightmostnode,then
nextRightofpsrightchildwillbeNULL.
#include <stdio.h>
#include <stdlib.h>

struct node
{
int data;
struct node *left;
struct node *right;
struct node *nextRight;
};

void connectRecur(struct node* p);

// 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.


Assumption: p is a compete binary tree */
void connectRecur(struct node* p)
{
// Base case
if (!p)
return;

// Set the nextRight pointer for p's left child


if (p->left)
p->left->nextRight = p->right;

// Set the nextRight pointer for p's right child


// p->nextRight will be NULL if p is the right most child at its level
if (p->right)
p->right->nextRight = (p->nextRight)? p->nextRight->left: NULL;

// Set nextRight for other nodes in pre order fashion


connectRecur(p->left);
connectRecur(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->nextRight = NULL;

return(node);
}

/* Driver program to test above functions*/


int main()
{

/* Constructed binary tree is


10
/
8

\
2

/
3
*/
struct node *root = newnode(10);
root->left

= newnode(8);

root->right

= newnode(2);

root->left->left = newnode(3);

// Populates nextRight pointer in all nodes


connect(root);

// Let us check the values of nextRight pointers


printf("Following are populated nextRight pointers in the tree "
"(-1 is printed if there is no nextRight) \n");
printf("nextRight of %d is %d \n", root->data,
root->nextRight? root->nextRight->data: -1);
printf("nextRight of %d is %d \n", root->left->data,
root->left->nextRight? root->left->nextRight->data: -1);
printf("nextRight of %d is %d \n", root->right->data,
root->right->nextRight? root->right->nextRight->data: -1);
printf("nextRight of %d is %d \n", root->left->left->data,
root->left->left->nextRight? root->left->left->nextRight->data: -1);

getchar();
return 0;
}
ThankstoDhanyaforsuggestingthisapproach.
TimeComplexity:O(n)
Whydoesntmethod2workfortreeswhicharenotCompleteBinaryTrees?

Letusconsiderfollowingtreeasanexample.InMethod2,wesetthenextRightpointerinpreorderfashion.
Whenweareatnode4,wesetthenextRightofitschildrenwhichare8and9(thenextRightof4isalready
setasnode5).nextRightof8willsimplybesetas9,butnextRightof9willbesetasNULLwhichis
incorrect.WecantsetthecorrectnextRight,becausewhenwesetnextRightof9,weonlyhavenextRight
ofnode4andancestorsofnode4,wedonthavenextRightofnodesinrightsubtreeofroot.

1
/\
23
/\/\
4567
/\/\
891011
=======================================================================

Trie|(Delete)
Inthepreviouspostontriewehavedescribedhowtoinsertandsearchanodeintrie.Hereisanalgorithm
howtodeleteanodefromtrie.
Duringdeleteoperationwedeletethekeyinbottomupmannerusingrecursion.Thefollowingarepossible
conditionswhendeletingkeyfromtrie,
1.

Keymaynotbethereintrie.Deleteoperationshouldnotmodifytrie.

2.

Keypresentasuniquekey(nopartofkeycontainsanotherkey(prefix),northekeyitselfisprefixof
anotherkeyintrie).Deleteallthenodes.

3.

Keyisprefixkeyofanotherlongkeyintrie.Unmarktheleafnode.

4.

Keypresentintrie,havingatleastoneotherkeyasprefixkey.Deletenodesfromendofkeyuntil
firstleafnodeoflongestprefixkey.

Thehighlightedcodepresentsalgorithmtoimplementaboveconditions.(Onemaybeindilemmahowa
pointerpassedtodeletehelperisreflectingchangesfromdeleteHelpertodeleteKey.Notethatweare
holdingtrieasanADTintrie_tnode,whichispassedbyreferenceorpointer).
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define ARRAY_SIZE(a) sizeof(a)/sizeof(a[0])

// Alphabet size (# of symbols)

#define ALPHABET_SIZE (26)


#define INDEX(c) ((int)c - (int)'a')

#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;

pNode = (trie_node_t *)malloc(sizeof(trie_node_t));

if( pNode )
{
int i;

pNode->value

= 0;

for(i = 0; i < ALPHABET_SIZE; i++)


{
pNode->children[i] = NULL;
}
}

return pNode;
}

void initialize(trie_t *pTrie)


{
pTrie->root = getNode();
pTrie->count = 0;
}

void insert(trie_t *pTrie, char key[])


{
int level;
int length = strlen(key);
int index;
trie_node_t *pCrawl;

pTrie->count++;
pCrawl = pTrie->root;

for( level = 0; level < length; level++ )


{
index = INDEX(key[level]);

if( pCrawl->children[index] )
{
// Skip current node
pCrawl = pCrawl->children[index];
}
else

{
// Add new node
pCrawl->children[index] = getNode();
pCrawl = pCrawl->children[index];
}
}

// mark last node as leaf (non zero)


pCrawl->value = pTrie->count;
}

int search(trie_t *pTrie, char key[])


{
int level;
int length = strlen(key);
int index;
trie_node_t *pCrawl;

pCrawl = pTrie->root;

for( level = 0; level < length; level++ )


{
index = INDEX(key[level]);

if( !pCrawl->children[index] )
{
return 0;
}

pCrawl = pCrawl->children[index];
}

return (0 != pCrawl && pCrawl->value);


}

int leafNode(trie_node_t *pNode)


{

return (pNode->value != 0);


}

int isItFreeNode(trie_node_t *pNode)


{
int i;
for(i = 0; i < ALPHABET_SIZE; i++)
{
if( pNode->children[i] )
return 0;
}

return 1;
}

bool deleteHelper(trie_node_t *pNode, char key[], int level, int len)


{
if( pNode )
{
// Base case
if( level == len )
{
if( pNode->value )
{
// Unmark leaf node
pNode->value = 0;

// If empty, node to be deleted


if( isItFreeNode(pNode) )
{
return true;
}

return false;
}
}
else // Recursive case

{
int index = INDEX(key[level]);

if( deleteHelper(pNode->children[index], key, level+1, len) )


{
// last node marked, delete it
FREE(pNode->children[index]);

// recursively climb up, and delete eligible nodes


return ( !leafNode(pNode) && isItFreeNode(pNode) );
}
}
}

return false;
}

void deleteKey(trie_t *pTrie, char key[])


{
int len = strlen(key);

if( len > 0 )


{
deleteHelper(pTrie->root, key, 0, len);
}
}

int main()
{
char keys[][8] = {"she", "sells", "sea", "shore", "the", "by", "sheer"};
trie_t trie;

initialize(&trie);

for(int i = 0; i < ARRAY_SIZE(keys); i++)


{
insert(&trie, keys[i]);

deleteKey(&trie, keys[0]);

printf("%s %s\n", "she", search(&trie, "she") ? "Present in trie" : "Not present


in trie");

return 0;
}

=======================================================================

Trie|(InsertandSearch)
Trieisanefficientinformationretrievaldatastructure.Usingtrie,searchcomplexitiescanbebroughtto
optimallimit(keylength).Ifwestorekeysinbinarysearchtree,awellbalancedBSTwillneedtime
proportionaltoM*logN,whereMismaximumstringlengthandNisnumberofkeysintree.Usingtrie,we
cansearchthekeyinO(M)time.Howeverthepenaltyisontriestoragerequirements.
Everynodeoftrieconsistsofmultiplebranches.Eachbranchrepresentsapossiblecharacterofkeys.We
needtomarkthelastnodeofeverykeyasleafnode.Atrienodefieldvaluewillbeusedtodistinguishthe
nodeasleafnode(thereareotherusesofthevaluefield).AsimplestructuretorepresentnodesofEnglish
alphabetcanbeasfollowing,

structtrie_node
{
intvalue/*Usedtomarkleafnodes*/
trie_node_t*children[ALPHABET_SIZE]
}
Insertingakeyintotrieissimpleapproach.Everycharacterofinputkeyisinsertedasanindividualtrie
node.Notethatthechildrenisanarrayofpointerstonextleveltrienodes.Thekeycharacteractsasan
indexintothearraychildren.Iftheinputkeyisneworanextensionofexistingkey,weneedtoconstruct
nonexistingnodesofthekey,andmarkleafnode.Iftheinputkeyisprefixofexistingkeyintrie,wesimply
markthelastnodeofkeyasleaf.Thekeylengthdeterminestriedepth.
Searchingforakeyissimilartoinsertoperation,howeverweonlycomparethecharactersandmovedown.
Thesearchcanterminateduetoendofstringorlackofkeyintrie.Intheformercase,ifthevaluefieldof

lastnodeisnonzerothenthekeyexistsintrie.Inthesecondcase,thesearchterminateswithoutexamining
allthecharactersofkey,sincethekeyisnotpresentintrie.
Thefollowingpictureexplainsconstructionoftrieusingkeysgivenintheexamplebelow,

root
/\\
tab
|||
hny
||\|
esye
/||
irw
|||
ree
|
r
Inthepicture,everycharacterisoftypetrie_node_t.Forexample,therootisoftypetrie_node_t,andits
childrena,bandtarefilled,allothernodesofrootwillbeNULL.Similarly,aatthenextlevelishavingonly
onechild(n),allotherchildrenareNULL.Theleafnodesareinblue.
InsertandsearchcostsO(key_length),howeverthememoryrequirementsoftrieisO(ALPHABET_SIZE*
key_length*N)whereNisnumberofkeysintrie.Thereareefficientrepresentationoftrienodes(e.g.
compressedtrie,ternarysearchtree,etc.)tominimizememoryrequirementsoftrie.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define ARRAY_SIZE(a) sizeof(a)/sizeof(a[0])

// Alphabet size (# of symbols)


#define ALPHABET_SIZE (26)
// Converts key current character into index
// use only 'a' through 'z' and lower case
#define CHAR_TO_INDEX(c) ((int)c - (int)'a')

// 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;
};

// Returns new trie node (initialized to NULLs)


trie_node_t *getNode(void)
{
trie_node_t *pNode = NULL;

pNode = (trie_node_t *)malloc(sizeof(trie_node_t));

if( pNode )
{
int i;

pNode->value = 0;

for(i = 0; i < ALPHABET_SIZE; i++)


{
pNode->children[i] = NULL;
}
}

return pNode;
}

// Initializes trie (root is dummy node)


void initialize(trie_t *pTrie)

{
pTrie->root = getNode();
pTrie->count = 0;
}

// If not present, inserts key into trie


// If the key is prefix of trie node, just marks leaf node
void insert(trie_t *pTrie, char key[])
{
int level;
int length = strlen(key);
int index;
trie_node_t *pCrawl;

pTrie->count++;
pCrawl = pTrie->root;

for( level = 0; level < length; level++ )


{
index = CHAR_TO_INDEX(key[level]);
if( !pCrawl->children[index] )
{
pCrawl->children[index] = getNode();
}

pCrawl = pCrawl->children[index];
}

// mark last node as leaf


pCrawl->value = pTrie->count;
}

// Returns non zero, if key presents in trie


int search(trie_t *pTrie, char key[])
{
int level;
int length = strlen(key);

int index;
trie_node_t *pCrawl;

pCrawl = pTrie->root;

for( level = 0; level < length; level++ )


{
index = CHAR_TO_INDEX(key[level]);

if( !pCrawl->children[index] )
{
return 0;
}

pCrawl = pCrawl->children[index];
}

return (0 != pCrawl && pCrawl->value);


}

// 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;

char output[][32] = {"Not present in trie", "Present in trie"};

initialize(&trie);

// Construct trie
for(int i = 0; i < ARRAY_SIZE(keys); i++)
{
insert(&trie, keys[i]);
}

// Search for different keys


printf("%s --- %s\n", "the", output[search(&trie, "the")] );
printf("%s --- %s\n", "these", output[search(&trie, "these")] );
printf("%s --- %s\n", "their", output[search(&trie, "their")] );
printf("%s --- %s\n", "thaw", output[search(&trie, "thaw")] );

return 0;
}

=======================================================================

Checkifabinarytreeissubtreeof
anotherbinarytree|Set1
Giventwobinarytrees,checkifthefirsttreeissubtreeofthesecondone.AsubtreeofatreeTisatreeS
consistingofanodeinTandallofitsdescendantsinT.Thesubtreecorrespondingtotherootnodeisthe
entiretreethesubtreecorrespondingtoanyothernodeiscalledapropersubtree.
Forexample,inthefollowingcase,treeSisasubtreeoftreeT.

TreeS
10
/\
46
\
30

TreeT
26
/\
103
/\\
463
\
30

Solution:TraversethetreeTinpreorderfashion.Foreveryvisitednodeinthetraversal,seeifthesubtree
rootedwiththisnodeisidenticaltoS.
FollowingisCimplementationforthis.
#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;
};

/* A utility function to check whether trees with roots as root1 and


root2 are identical or not */
bool areIdentical(struct node * root1, struct node *root2)
{
/* base cases */
if (root1 == NULL && root2 == NULL)
return true;

if (root1 == NULL || root2 == NULL)


return false;

/* 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) );
}

/* This function returns true if S is a subtree of T, otherwise false */


bool isSubtree(struct node *T, struct node *S)
{
/* base cases */

if (S == NULL)
return true;

if (T == NULL)
return false;

/* Check the tree with root as current node */


if (areIdentical(T, S))
return true;

/* If the tree with root as current node doesn't match then


try left and right subtrees one by one */
return isSubtree(T->left, S) ||
isSubtree(T->right, S);
}

/* 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);
}

/* Driver program to test above function */


int main()
{
/* Construct the following tree
26
/

10 3
/

\
30
*/
struct node *T

= newNode(26);

T->right

= newNode(3);

T->right->right

= newNode(3);

T->left

= newNode(10);

T->left->left

= newNode(4);

T->left->left->right = newNode(30);
T->left->right

= newNode(6);

/* Construct the following tree


10
/
4

\
6

\
30
*/
struct node *S = newNode(10);
S->right

= newNode(6);

S->left

= newNode(4);

S->left->right = newNode(30);

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:

TreeSissubtreeoftreeT
TimeComplexity:TimeworstcasecomplexityofabovesolutionisO(mn)wheremandnarenumberof
nodesingiventwotrees.

WecansolvetheaboveprobleminO(n)time.PleasereferCheckifabinarytreeissubtreeofanother
binarytree|Set2forO(n)solution.

=======================================================================

DecisionTreesFake(Counterfeit)
CoinPuzzle(12CoinPuzzle)
Letussolvetheclassicfakecoinpuzzleusingdecisiontrees.Therearethetwodifferentvariantsofthe
puzzlegivenbelow.Iamprovidingdescriptionofboththepuzzlesbelow,trytosolveonyourown,assume
N=8.
Easy:GivenatwopanfairbalanceandNidenticallylookingcoins,outofwhichonlyonecoinislighter(or
heavier).Tofigureouttheoddcoin,howmanyminimumnumberofweighingarerequiredintheworst
case?
Difficult:GivenatwopanfairbalanceandNidenticallylookingcoinsoutofwhichonlyonecoinmaybe
defective.Howcanwetracewhichcoin,ifany,isoddoneandalsodeterminewhetheritislighterorheavier
inminimumnumberoftrialsintheworstcase?
Letusstartwithrelativelysimpleexamples.Afterreadingeveryproblemtrytosolveonyourown.
Problem1:(Easy)
Given5coinsoutofwhichonecoinislighter.Intheworstcase,howmanyminimumnumberofweighing
arerequiredtofigureouttheoddcoin?
Namethecoinsas1,2,3,4and5.Weknowthatonecoinislighter.Consideringbestoutcomeofbalance,
wecangroupthecoinsintwodifferentways,[(1,2),(3,4)and(5)],or[(12),(34)and(5)].Wecaneasilyrule
outgroupslike[(123)and(45)],aswewillgetobviousanswer.Anyothercombinationwillfallintooneof
thesetwogroups,like[(2)(45)and(13)],etc.
Considerthefirstgroup,pairs(1,2)and(3,4).Wecancheck(1,2),iftheyareequalwegoaheadwith(3,
4).Weneedtwoweighinginworstcase.Thesameanalogycanbeappliedwhenthecoininheavier.
Withthesecondgroup,weigh(12)and(34).Iftheybalance(5)isdefectiveone,otherwisepickthelighter
pair,andweneedonemoreweighingtofindoddone.
Boththecombinationsneedtwoweighingincaseof5coinswithpriorinformationofonecoinislighter.
Analysis:Ingeneral,ifweknowthatthecoinisheavyorlight,wecantracethecoininlog3(N)trials
(roundedtonextinteger).Ifwerepresenttheoutcomeofbalanceasternarytree,everyleafrepresentan
outcome.SinceanycoinamongNcoinscanbedefective,weneedtogeta3arytreehavingminimumofN
leaves.A3arytreeatkthlevelwillhave3kleavesandhenceweneed3k>=N.

Inotherwords,inktrialswecanexamineupto3kcoins,ifweknowwhetherthedefectivecoinisheavieror
lighter.Giventhatacoinisheavier,verifythat3trialsaresufficienttofindtheoddcoinamong12coins,
because32<12<33.
Problem2:(Difficult)
Wearegiven4coins,outofwhichonlyonecoinmaybedefective.Wedontknow,whetherallcoinsare
genuineoranydefectiveoneispresent.Howmanynumberofweighingarerequiredinworstcasetofigure
outtheoddcoin,ifpresent?Wealsoneedtotellwhetheritisheavierorlighter.
Fromtheaboveanalysiswemaythinkthatk=2trialsaresufficient,sinceatwolevel3arytreeyields9
leaveswhichisgreaterthanN=4(readtheproblemonceagain).Notethatitisimpossibletosolveabove4
coinsproblemintwoweighing.Thedecisiontreeconfirmsthefact(trytodraw).
Wecangroupthecoinsintwodifferentways,[(12,34)]or[(1,2)and(3,4)].Letusconsiderthecombination
(12,34),thecorrespondingdecisiontreeisgivenbelow.Blueleavesarevalidoutcomes,andredleavesare
impossiblecases.Wearrivedatimpossiblecasesduetotheassumptionsmadeearlieronthepath.

Theoutcomecanbe(12)<(34)i.e.wegoontoleftsubtreeor(12)>(34)i.e.wegoontorightsubtree.
Theleftsubtreeispossibleintwoways,

A)Either1or2canbelighterOR

B)Either3or4canbeheavier.

Furtherontheleftsubtree,assecondtrial,weweigh(1,2)or(3,4).Letusconsider(3,4)astheanalogyfor
(1,2)issimilar.Theoutcomeofsecondtrailcanbethreeways

A)(3)<(4)yielding4asdefectiveheaviercoin,OR

B)(3)>(4)yielding3asdefectiveheaviercoinOR

C)(3)=(4),yieldingambiguity.Hereweneedonemoreweighingtocheckagenuinecoinagainst1
or2.InthefigureItook(3,2)where3isconfirmedasgenuine.Wecanget(3)>(2)inwhich2is
lighter,or(3)=(2)inwhich1islighter.Notethatitimpossibletoget(3)<(2),itcontradictsour
assumptionleanedtoleftside.

Similarlywecananalyzetherightsubtree.Weneedtwomoreweighingsonrightsubtreeaswell.
Overallweneed3weighingstotracetheoddcoin.Notethatweareunabletoutilizetwooutcomesof3ary
trees.Also,thetreeisnotfulltree,middlebranchterminatedafterfirstweighing.Infact,wecanget27
leavesof3levelfull3arytree,butonlywegot11leavesincludingimpossiblecases.
Analysis:GivenNcoins,allmaybegenuineoronlyonecoinisdefective.Weneedadecisiontreewith
atleast(2N+1)leavescorrespondtotheoutputs.BecausetherecanbeNleavestobelighter,orNleaves
tobeheavieroronegenuinecase,ontotal(2N+1)leaves.
Asexplainedearlierternarytreeatlevelk,canhaveutmost3kleavesandweneedatreewithleavesof3k>
(2N+1).
Inotherwords,weneedatleastk>log3(2N+1)weighingtofindthedefectiveone.
Observetheabovefigurethatnotallthebranchesaregeneratingleaves,i.e.wearemissingvalidoutputs
undersomebranchesthatleadingtomorenumberoftrials.Whenpossible,weshouldgroupthecoinsin
suchawaythateverybranchisgoingtoyieldvalidoutput(insimpletermsgeneratefull3arytree).Problem
4describesthisapproachof12coins.
Problem3:(Specialcaseoftwopanbalance)
Wearegiven5coins,agroupof4coinsoutofwhichonecoinisdefective(wedontknowwhetheritis
heavierorlighter),andonecoinisgenuine.Howmanyweighingarerequiredinworstcasetofigureoutthe
oddcoinwhetheritisheavierorlighter?
Labelthecoinsas1,2,3,4andG(genuine).Wenowhavesomeinformationoncoinpurity.Weneedto
makeusethatinthegroupings.
Wecanbestgroupthemas[(G1,23)and(4)].Anyothergroupcantgeneratefull3arytree,tryyourself.
Thefollowingdiagramexplainstheprocedure.


Themiddlecase(G1)=(23)isselfexplanatory,i.e.1,2,3aregenuineand4thcoincanbefiguredout
lighterorheavierinonemoretrial.
Theleftsideoftreecorrespondstothecase(G1)<(23).Thisispossibleintwoways,either1shouldbe
lighteroreitherof(2,3)shouldbeheavier.Theformerinstanceisobviouswhennextweighing(2,3)is
balanced,yielding1aslighter.Thelaterinstancecouldbe(2)<(3)yielding3asheavieror(2)>(3)yielding
2asheavier.Theleafnodesonleftbrancharenamedtoreflecttheseoutcomes.
Therightsideoftreecorrespondstothecase(G1)>(23).Thisispossibleintwoways,either1isheavieror
eitherof(2,3)shouldbelighter.Theformerinstanceisobviouswhenthenextweighing(2,3)isbalanced,
yielding1asheavier.Thelatercasecouldbe(2)<(3)yielding2aslightercoin,or(2)>(3)yielding3as
lighter.
Intheaboveproblem,underanypossibilityweneedonlytwoweighing.Weareabletousealloutcomesof
twolevelfull3arytree.Westartedwith(N+1)=5coinswhereN=4,weendupwith(2N+1)=9leaves.
Infactweshouldhave11outcomessincewestaredwith5coins,whereareother2outcomes?
Thesetwooutcomescanbedeclaredattherootoftreeitself(priortofirstweighing),canyoufigure
thesetwooutcomes?
Ifweobservethefigure,afterthefirstweighingtheproblemreducedtoweknowthreecoins,eitheronecan
belighter(heavier)oroneamongothertwocanbeheavier(lighter).Thiscanbesolvedinoneweighing
(readProblem1).
Analysis:Given(N+1)coins,oneisgenuineandtherestNcanbegenuineoronlyonecoinisdefective.
Therequireddecisiontreeshouldresultinminimumof(2N+1)leaves.Sincethetotalpossibleoutcomes
are(2(N+1)+1),numberofweighing(trials)aregivenbytheheightofternarytree,k>=log3[2(N+1)+1].
Notetheequalitysign.
RearrangingkandN,wecanweighmaximumofN<=(3k3)/2coinsinktrials.
Problem4:(Theclassic12coinpuzzle)

Youaregiventwopanfairbalance.Youhave12identicallylookingcoinsoutofwhichonecoinmaybe
lighterorheavier.Howcanyoufindoddcoin,ifany,inminimumtrials,alsodeterminewhetherdefective
coinislighterorheavier,intheworstcase?
Howdoyouwanttogroupthem?Bisetortriset?Clearlywecandiscardtheoptionofdividingintotwo
equalgroups.Itcantleadtobesttree.Fromtheabovetwoexamples,wecanensurethatthedecisiontree
canbeusedinoptimalwayifwecanrevealatleasetonegenuinecoin.Remembertogroupcoinssuchthat
thefirstweighingrevealsatleastonegenuinecoin.
Letusnamethecoinsas1,2,8,A,B,CandD.Wecancombinethecoinsinto3groups,namely(1234),
(5678)and(ABCD).Weigh(1234)and(5678).Youareencouragedtodrawdecisiontreewhilereadingthe
procedure.Theoutcomecanbethreeways,
1.

(1234)=(5678),bothgroupsareequal.Defectivecoinmaybein(ABCD)group.

2.

(1234)<(5678),i.e.firstgroupislessinweightthansecondgroup.

3.

(1234)>(5678),i.e.firstgroupismoreinweightthansecondgroup.

Theoutput(1)canbesolvedintwomoreweighingasspecialcaseoftwopanbalancegiveninProblem3.
Weknowthatgroups(1234)and(5678)aregenuineanddefectivecoinmaybein(ABCD).Pickone
genuinecoinfromanyofweighedgroups,andproceedwith(ABCD)asexplainedinProblem3.
Outcomes(2)and(3)arespecial.Inboththecases,weknowthat(ABCD)isgenuine.Andalso,weknowa
setofcoinsbeinglighterandasetofcoinsbeingheavier.Weneedtoshuffletheweighedtwogroupsin
suchawaythatweendupwithsmallerheightdecisiontree.
Considerthesecondoutcomewhere(1234)<(5678).Itispossiblewhenanycoinamong(1,2,3,4)is
lighteroranycoinamong(5,6,7,8)isheavier.Werevealedlighterorheavierpossibilityafterfirst
weighing.IfweproceedasinProblem1,wewillnotgeneratebestdecisiontree.Letusshufflecoinsas
(1235)and(4BCD)asnewgroups(therearedifferentshufflespossible,theyalsoleadtominimum
weighing,canyoutry?).Ifweweighthesetwogroupsagaintheoutcomecanbethreeways,i)(1235)<
(4BCD)yieldingoneamong1,2,3islighterwhichissimilartoProblem1explainedabove,weneedone
moreweighing,ii)(1235)=(4BCD)yieldingoneamong6,7,8isheavierwhichissimilartoProblem1
explainedabove,weneedonemoreweighingiii)(1235)>(4BCD)yieldingeither5asheaviercoinor4as
lightercoin,attheexpenseofonemoreweighing.
Similarwaywecanalsosolvetherightsubtree(thirdoutcomewhere(1234)>(5678))intwomoreweighing.
Weareabletosolvethe12coinpuzzlein3weighingintheworstcase.
FewInterestingPuzzles:
1.

SolveProblem4withN=8andN=13,Howmanyminimumtrialsarerequiredineachcase?

2.

Givenafunctionintweigh(A[],B[])whereAandBarearrays(neednotbeequalsize).Thefunction
returns1,0or1.Itreturns0ifsumofallelementsinAandBareequal,1ifA<Band1ifA>B.
Givenanarrayof12elements,allelementsareequalexceptone.Theoddelementcanbeasthat
ofothers,smallerorgreaterthanothers.Writeaprogramtofindtheoddelement(ifany)using
weigh()minimumnumberoftimes.

3.

Youmighthaveseen3panbalanceinsciencelabsduringschooldays.Givena3panbalance(4
outcomes)andNcoins,howmanyminimumtrialsareneededtofigureoutoddcoin?

=======================================================================

CheckifagivenBinaryTreeis
SumTree
WriteafunctionthatreturnstrueifthegivenBinaryTreeisSumTreeelsefalse.ASumTreeisaBinaryTree
wherethevalueofanodeisequaltosumofthenodespresentinitsleftsubtreeandrightsubtree.An
emptytreeisSumTreeandsumofanemptytreecanbeconsideredas0.Aleafnodeisalsoconsideredas
SumTree.
FollowingisanexampleofSumTree.

26
/\
103
/\\
463
Method1(Simple)
Getthesumofnodesinleftsubtreeandrightsubtree.Checkifthesumcalculatedisequaltorootsdata.
Also,recursivelycheckiftheleftandrightsubtreesareSumTrees.
#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;
};

/* A utility function to get the sum of values in tree with root


as root */
int sum(struct node *root)
{

if(root == NULL)
return 0;
return sum(root->left) + root->data + sum(root->right);
}

/* returns 1 if sum property holds for the given


node and both of its children */
int isSumTree(struct node* node)
{
int ls, rs;

/* If node is NULL or it's a leaf node then


return true */
if(node == NULL ||
(node->left == NULL && node->right == NULL))
return 1;

/* Get sum of nodes in left and right subtrees */


ls = sum(node->left);
rs = sum(node->right);

/* if the node and both of its children satisfy the


property return 1 else 0*/
if((node->data == ls + rs)&&
isSumTree(node->left) &&
isSumTree(node->right))
return 1;

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);
}

/* Driver program to test above function */


int main()
{
struct node *root = newNode(26);
root->left

= newNode(10);

root->right

= newNode(3);

root->left->left

= newNode(4);

root->left->right = newNode(6);
root->right->right = newNode(3);
if(isSumTree(root))
printf("The given tree is a SumTree ");
else
printf("The given tree is not a SumTree ");

getchar();
return 0;
}
TimeComplexity:O(n^2)inworstcase.Worstcaseoccursforaskewedtree.
Method2(Tricky)
TheMethod1usessum()togetthesumofnodesinleftandrightsubtrees.Themethod2usesfollowing
rulestogetthesumdirectly.
1)Ifthenodeisaleafnodethensumofsubtreerootedwiththisnodeisequaltovalueofthisnode.
2)Ifthenodeisnotaleafnodethensumofsubtreerootedwiththisnodeistwicethevalueofthisnode
(AssumingthatthetreerootedwiththisnodeisSumTree).
#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;
};

/* Utillity function to check if the given node is leaf or not */


int isLeaf(struct node *node)
{
if(node == NULL)
return 0;
if(node->left == NULL && node->right == NULL)
return 1;
return 0;
}

/* returns 1 if SumTree property holds for the given


tree */
int isSumTree(struct node* node)
{
int ls; // for sum of nodes in left subtree
int rs; // for sum of nodes in right subtree

/* If node is NULL or it's a leaf node then


return true */
if(node == NULL || isLeaf(node))
return 1;

if( isSumTree(node->left) && isSumTree(node->right))


{
// Get the sum of nodes in left subtree
if(node->left == NULL)
ls = 0;
else if(isLeaf(node->left))
ls = node->left->data;
else

ls = 2*(node->left->data);

// Get the sum of nodes in right subtree


if(node->right == NULL)
rs = 0;
else if(isLeaf(node->right))
rs = node->right->data;
else
rs = 2*(node->right->data);

/* If root's data is equal to sum of nodes in left


and right subtrees then return 1 else return 0*/
return(node->data == ls + rs);
}

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);
}

/* Driver program to test above function */


int main()
{
struct node *root = newNode(26);
root->left

= newNode(10);

root->right

= newNode(3);

root->left->left

= newNode(4);

root->left->right = newNode(6);
root->right->right = newNode(3);
if(isSumTree(root))
printf("The given tree is a SumTree ");
else
printf("The given tree is not a SumTree ");

getchar();
return 0;
}
TimeComplexity:O(n)
WriteafunctionthatreturnstrueifthegivenBinaryTreeisSumTreeelsefalse.ASumTreeisaBinaryTree
wherethevalueofanodeisequaltosumofthenodespresentinitsleftsubtreeandrightsubtree.An
emptytreeisSumTreeandsumofanemptytreecanbeconsideredas0.Aleafnodeisalsoconsideredas
SumTree.
FollowingisanexampleofSumTree.

26
/\
103
/\\
463
Method1(Simple)
Getthesumofnodesinleftsubtreeandrightsubtree.Checkifthesumcalculatedisequaltorootsdata.
Also,recursivelycheckiftheleftandrightsubtreesareSumTrees.
#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;
};

/* A utility function to get the sum of values in tree with root


as root */
int sum(struct node *root)
{
if(root == NULL)
return 0;
return sum(root->left) + root->data + sum(root->right);
}

/* returns 1 if sum property holds for the given


node and both of its children */
int isSumTree(struct node* node)
{
int ls, rs;

/* If node is NULL or it's a leaf node then


return true */
if(node == NULL ||
(node->left == NULL && node->right == NULL))
return 1;

/* Get sum of nodes in left and right subtrees */


ls = sum(node->left);
rs = sum(node->right);

/* if the node and both of its children satisfy the


property return 1 else 0*/
if((node->data == ls + rs)&&
isSumTree(node->left) &&
isSumTree(node->right))
return 1;

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);
}

/* Driver program to test above function */


int main()
{
struct node *root = newNode(26);
root->left

= newNode(10);

root->right

= newNode(3);

root->left->left

= newNode(4);

root->left->right = newNode(6);
root->right->right = newNode(3);
if(isSumTree(root))
printf("The given tree is a SumTree ");
else
printf("The given tree is not a SumTree ");

getchar();
return 0;
}
TimeComplexity:O(n^2)inworstcase.Worstcaseoccursforaskewedtree.
Method2(Tricky)
TheMethod1usessum()togetthesumofnodesinleftandrightsubtrees.Themethod2usesfollowing
rulestogetthesumdirectly.
1)Ifthenodeisaleafnodethensumofsubtreerootedwiththisnodeisequaltovalueofthisnode.
2)Ifthenodeisnotaleafnodethensumofsubtreerootedwiththisnodeistwicethevalueofthisnode
(AssumingthatthetreerootedwiththisnodeisSumTree).

#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;
};

/* Utillity function to check if the given node is leaf or not */


int isLeaf(struct node *node)
{
if(node == NULL)
return 0;
if(node->left == NULL && node->right == NULL)
return 1;
return 0;
}

/* returns 1 if SumTree property holds for the given


tree */
int isSumTree(struct node* node)
{
int ls; // for sum of nodes in left subtree
int rs; // for sum of nodes in right subtree

/* If node is NULL or it's a leaf node then


return true */
if(node == NULL || isLeaf(node))
return 1;

if( isSumTree(node->left) && isSumTree(node->right))


{
// Get the sum of nodes in left subtree
if(node->left == NULL)

ls = 0;
else if(isLeaf(node->left))
ls = node->left->data;
else
ls = 2*(node->left->data);

// Get the sum of nodes in right subtree


if(node->right == NULL)
rs = 0;
else if(isLeaf(node->right))
rs = node->right->data;
else
rs = 2*(node->right->data);

/* If root's data is equal to sum of nodes in left


and right subtrees then return 1 else return 0*/
return(node->data == ls + rs);
}

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);
}

/* Driver program to test above function */

int main()
{
struct node *root = newNode(26);
root->left

= newNode(10);

root->right

= newNode(3);

root->left->left

= newNode(4);

root->left->right = newNode(6);
root->right->right = newNode(3);
if(isSumTree(root))
printf("The given tree is a SumTree ");
else
printf("The given tree is not a SumTree ");

getchar();
return 0;
}
TimeComplexity:O(n)

================================================================
=======

TournamentTree(WinnerTree)and
BinaryHeap
GivenateamofNplayers.Howmanyminimumgamesarerequiredtofindsecondbestplayer?
Wecanuseadversaryargumentsbasedontournamenttree(BinaryHeap).
Tournamenttreeisaformofmin(max)heapwhichisacompletebinarytree.Everyexternalnode
representsaplayerandinternalnoderepresentswinner.Inatournamenttreeeveryinternalnodecontains
winnerandeveryleafnodecontainsoneplayer.
TherewillbeN1internalnodesinabinarytreewithNleaf(external)nodes.Fordetailsseethispost(put
n=2inequationgiveninthepost).
ItisobviousthattoselectthebestplayeramongNplayers,(N1)playerstobeeliminated,i.e.weneed
minimumof(N1)games(comparisons).Mathematicallywecanproveit.InabinarytreeI=E1,whereI
isnumberofinternalnodesandEisnumberofexternalnodes.Itmeanstofindmaximumorminimum
elementofanarray,weneedN1(internalnodes)comparisons.

SecondBestPlayer
Theinformationexploredduringbestplayerselectioncanbeusedtominimizethenumberofcomparisons
intracingthenextbestplayers.Forexample,wecanpicksecondbestplayerin(N+log2N2)
comparisons.Fordetailsreadthiscomment.
Thefollowingdiagramdisplaysatournamenttree(winnertree)asamaxheap.Notethattheconceptof
losertreeisdifferent.

Theabovetreecontains4leafnodesthatrepresentplayersandhave3levels0,1and2.Initially2games
areconductedatlevel2,onebetween5and3andanotheronebetween7and8.Inthenextmove,one
moregameisconductedbetween5and8toconcludethefinalwinner.Overallweneed3comparisons.For
secondbestplayerweneedtotracethecandidatesparticipatedwithfinalwinner,thatleadsto7assecond
best.
MedianofSortedArrays
Tournamenttreecaneffectivelybeusedtofindmedianofsortedarrays.Assume,givenMsortedarraysof
equalsizeL(forsimplicity).Wecanattachallthesesortedarraystothetournamenttree,onearrayperleaf.
WeneedatreeofheightCEIL(log2M)tohaveatleastMexternalnodes.
Consideranexample.Given3(M=3)sortedintegerarraysofmaximumsize5elements.

{2,5,7,11,15}Array1
{1,3,4}Array2
{6,8,12,13,14}Array3
Whatshouldbetheheightoftournamenttree?Weneedtoconstructatournamenttreeofheightlog23.=
1.585=2roundedtonextinteger.Abinarytreeofheight2willhave4leavestowhichwecanattachthe
arraysasshowninthebelowfigure.


Afterthefirsttournament,thetreeappearsasbelow,

WecanobservethatthewinnerisfromArray2.HencethenextelementfromArray2willdiveinandgames
willbeplayedalongthewinnerpathofprevioustournament.
Notethatinfinityisusedassentinelelement.Basedondatabeingholdinnodeswecanselectthesentinel
character.Forexampleweusuallystorethepointersinnodesratherthankeys,soNULLcanserveas
sentinel.Ifanyofthearrayexhaustswewillfillthecorrespondingleafandupcominginternalnodeswith
sentinel.

Afterthesecondtournament,thetreeappearsasbelow,

ThenextwinnerisfromArray1,sonextelementofArray1arraywhichis5willdiveintothenextround,and
nexttournamentplayedalongthepathof2.
Thetournamentscanbecontinuedtillwegetmedianelementwhichis(5+3+5)/2=7thelement.Notethat
thereareevenbetteralgorithmsforfindingmedianofunionofsortedarrays,fordetailsseetherelatedlinks
givenbelow.
IngeneralwithMsortedlistsofsizeL1,L2LmrequirestimecomplexityofO((L1+L2++Lm)*logM)to
mergeallthearrays,andO(m*logM)timetofindmedian,wheremismedianposition.
Selectsmallestonemillionelementsfromonebillionunsortedelements:
Asasimplesolution,wecansortthebillionnumbersandselectfirstonemillion.
Onalimitedmemorysystemsortingbillionelementsandpickingthefirstonemillionseemstobe
impractical.Wecanusetournamenttreeapproach.Atanytimeonlyelementsoftreetobeinmemory.
Splitthelargearray(perhapsstoredondisk)intosmallersizearraysofsizeonemillioneach(oreven
smallerthatcanbesortedbythemachine).Sortthese1000smallsizearraysandstorethemondiskas
individualfiles.Constructatournamenttreewhichcanhaveatleast1000leafnodes(treetobeofheight10
since29<1000<210,iftheindividualfilesizeisevensmallerwewillneedmoreleafnodes).Everyleafnode
willhaveanenginethatpicksnextelementfromthesortedfilestoredondisk.Wecanplaythetournament
treegametoextractfirstonemillionelements.
Totalcost=sorting1000listsofonemillioneach+treeconstruction+tournaments
Implementation

Weneedtobuildthetree(heap)inbottomupmanner.Alltheleafnodesfilledfirst.Startattheleftextreme
oftreeandfillalongthebreadth(i.e.from2k1to2k1wherekisdepthoftree)andplaythegame.After
practicingwithfewexamplesitwillbeeasytowritecode.Wewillhavecodeinanupcomingarticle.

================================================================
=======

PrintBSTkeysinthegivenrange
Giventwovaluesk1andk2(wherek1<k2)andarootpointertoaBinarySearchTree.Printallthekeysof
treeinrangek1tok2.i.e.printallxsuchthatk1<=x<=k2andxisakeyofgivenBST.Printallthekeysin
increasingorder.
Forexample,ifk1=10andk2=22,thenyourfunctionshouldprint12,20and22.

Thankstobhaskerforsuggestingthefollowingsolution.
Algorithm:
1)Ifvalueofrootskeyisgreaterthank1,thenrecursivelycallinleftsubtree.
2)Ifvalueofrootskeyisinrange,thenprinttherootskey.
3)Ifvalueofrootskeyissmallerthank2,thenrecursivelycallinrightsubtree.
Implementation:
#include<stdio.h>

/* A tree node structure */


struct node
{
int data;
struct node *left;

struct node *right;


};

/* 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);

/* if root's data lies in range, then prints root's data */


if ( k1 <= root->data && k2 >= root->data )
printf("%d ", root->data );

/* If root->data is smaller than k2, then only we can get o/p keys
in right subtree */
if ( k2 > root->data )
Print(root->right, k1, k2);
}

/* Utility function to create a new Binary Tree node */


struct node* newNode(int data)
{
struct node *temp = new struct node;
temp->data = data;
temp->left = NULL;
temp->right = NULL;

return temp;
}

/* Driver function to test above functions */


int main()
{
struct node *root = new struct node;
int k1 = 10, k2 = 25;

/* Constructing tree given in the above figure */


root = newNode(20);
root->left = newNode(8);
root->right = newNode(22);
root->left->left = newNode(4);
root->left->right = newNode(12);

Print(root, k1, k2);

getchar();
return 0;
}
Output:
122022
TimeComplexity:O(n)wherenisthetotalnumberofkeysintree.

=======================================================================

PrintAncestorsofagivennodein
BinaryTree
GivenaBinaryTreeandakey,writeafunctionthatprintsalltheancestorsofthekeyinthegivenbinary
tree.
Forexample,ifthegiventreeisfollowingBinaryTreeandkeyis7,thenyourfunctionshouldprint4,2and
1.

1
/\
23
/\

45
/
7

ThankstoMike,Sambasivaandwgpshashankfortheircontribution.
#include<iostream>
#include<stdio.h>
#include<stdlib.h>

using namespace std;

/* 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;
};

/* If target is present in tree, then prints the ancestors


and returns true, otherwise returns false. */
bool printAncestors(struct node *root, int target)
{
/* base cases */
if (root == NULL)
return false;

if (root->data == target)
return true;

/* If target is present in either left or right subtree of this node,


then print this node */
if ( printAncestors(root->left, target) ||
printAncestors(root->right, target) )
{
cout << root->data << " ";

return true;
}

/* Else return false */


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);
}

/* Driver program to test above functions*/


int main()
{

/* Construct the following binary tree


1
/

2 3
/ \
4

/
7
*/
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(7);

printAncestors(root, 7);

getchar();
return 0;
}
Output:
421
TimeComplexity:O(n)wherenisthenumberofnodesinthegivenBinaryTree.

=======================================================================

GetLevelofanodeinaBinaryTree
GivenaBinaryTreeandakey,writeafunctionthatreturnslevelofthekey.
Forexample,considerthefollowingtree.Iftheinputkeyis3,thenyourfunctionshouldreturn1.Iftheinput
keyis4,thenyourfunctionshouldreturn3.Andforkeywhichisnotpresentinkey,thenyourfunction
shouldreturn0.

Thankstoprandeeyforsuggestingthefollowingsolution.
Theideaistostartfromtherootandlevelas1.Ifthekeymatcheswithrootsdata,returnlevel.Else
recursivelycallforleftandrightsubtreeswithlevelaslevel+1.
#include<stdio.h>

/* A tree node structure */


struct node

{
int data;
struct node *left;
struct node *right;
};

/* Helper function for getLevel(). It returns level of the data if data is


present in tree, otherwise returns 0.*/
int getLevelUtil(struct node *node, int data, int level)
{
if (node == NULL)
return 0;

if (node->data == data)
return level;

int downlevel = getLevelUtil(node->left, data, level+1);


if (downlevel != 0)
return downlevel;

downlevel = getLevelUtil(node->right, data, level+1);


return downlevel;
}

/* Returns level of given data value */


int getLevel(struct node *node, int data)
{
return getLevelUtil(node,data,1);
}

/* Utility function to create a new Binary Tree node */


struct node* newNode(int data)
{
struct node *temp = new struct node;
temp->data = data;
temp->left = NULL;
temp->right = NULL;

return temp;
}

/* Driver function to test above functions */


int main()
{
struct node *root = new struct node;
int x;

/* Constructing tree given in the above figure */


root = newNode(3);
root->left = newNode(2);
root->right = newNode(5);
root->left->left = newNode(1);
root->left->right = newNode(4);

for (x = 1; x <=5; x++)


{
int level = getLevel(root, x);
if (level)
printf(" Level of %d is %d\n", x, getLevel(root, x));
else
printf(" %d is not present in tree \n", x);

getchar();
return 0;
}
Output:

Levelof1is3
Levelof2is2
Levelof3is1
Levelof4is3
Levelof5is2
TimeComplexity:O(n)wherenisthenumberofnodesinthegivenBinaryTree.

================================================================
=======

FindkthsmallestelementinBST
(OrderStatisticsinBST)
GivenrootofbinarysearchtreeandKasinput,findKthsmallestelementinBST.
Forexample,inthefollowingBST,ifk=3,thenoutputshouldbe10,andifk=5,thenoutputshouldbe14.

Method1:UsingInorderTraversal.
InordertraversalofBSTretrieveselementsoftreeinthesortedorder.Theinordertraversalusesstackto
storetobeexplorednodesoftree(threadedtreeavoidsstackandrecursionfortraversal,seethispost).The
ideaistokeeptrackofpoppedelementswhichparticipateintheorderstatics.Hypotheticalalgorithmis
providedbelow,
Timecomplexity:O(n)wherenistotalnodesintree..
Algorithm:

/*initialization*/
pCrawl=root
setinitialstackelementasNULL(sentinal)

/*traverseuptoleftextreme*/
while(pCrawlisvalid)

stack.push(pCrawl)
pCrawl=pCrawl.left

/*processothernodes*/
while(pCrawl=stack.pop()isvalid)
stopifsufficientnumberofelementsarepopped.
if(pCrawl.rightisvalid)
pCrawl=pCrawl.right
while(pCrawlisvalid)
stack.push(pCrawl)
pCrawl=pCrawl.left
Implementation:
#include <stdio.h>
#include <stdlib.h>

#define ARRAY_SIZE(arr) sizeof(arr)/sizeof(arr[0])

/* just add elements to test */


/* NOTE: A sorted array results in skewed tree */
int ele[] = { 20, 8, 22, 4, 12, 10, 14 };

/* same alias */
typedef struct node_t node_t;

/* Binary tree node */


struct node_t
{
int data;

node_t* left;
node_t* right;
};

/* simple stack that stores node addresses */


typedef struct stack_t stack_t;

/* initial element always NULL, uses as sentinal */

struct stack_t
{
node_t* base[ARRAY_SIZE(ele) + 1];
int

stackIndex;

};

/* pop operation of stack */


node_t *pop(stack_t *st)
{
node_t *ret = NULL;

if( st && st->stackIndex > 0 )


{
ret = st->base[st->stackIndex];
st->stackIndex--;
}

return ret;
}

/* push operation of stack */


void push(stack_t *st, node_t *node)
{
if( st )
{
st->stackIndex++;
st->base[st->stackIndex] = node;
}
}

/* 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;

// Traverse till appropriate node


while(pTraverse)
{
currentParent = pTraverse;

if( node->data < pTraverse->data )


{
/* left subtree */
pTraverse = pTraverse->left;
}
else
{
/* right subtree */
pTraverse = pTraverse->right;
}
}

/* If the tree is empty, make it as root node */


if( !root )
{
root = node;
}
else if( node->data < currentParent->data )
{
/* Insert on left side */
currentParent->left = node;
}
else
{
/* Insert on right side */
currentParent->right = node;
}

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;

for(iterator = 0; iterator < size; iterator++)


{
new_node = (node_t *)malloc( sizeof(node_t) );

/* initialize */
new_node->data

= keys[iterator];

new_node->left

= NULL;

new_node->right = NULL;

/* insert into BST */


root = insert_node(root, new_node);
}

return root;
}

node_t *k_smallest_element_inorder(stack_t *stack, node_t *root, int k)


{
stack_t *st = stack;
node_t *pCrawl = root;

/* move to left extremen (minimum) */


while( pCrawl )
{
push(st, pCrawl);
pCrawl = pCrawl->left;
}

/* pop off stack and process each node */


while( pCrawl = pop(st) )

{
/* each pop operation emits one element
in the order
*/
if( !--k )
{
/* loop testing */
st->stackIndex = 0;
break;
}

/* there is right subtree */


if( pCrawl->right )
{
/* push the left subtree of right subtree */
pCrawl = pCrawl->right;
while( pCrawl )
{
push(st, pCrawl);
pCrawl = pCrawl->left;
}

/* pop off stack and repeat */


}
}

/* node having k-th element or NULL node */


return pCrawl;
}

/* Driver program to test above functions */


int main(void)
{
node_t* root = NULL;
stack_t stack = { {0}, 0 };
node_t *kNode = NULL;

int k = 5;

/* Creating the tree given in the above diagram */


root = binary_search_tree(root, ele, ARRAY_SIZE(ele));

kNode = k_smallest_element_inorder(&stack, root, k);

if( kNode )
{
printf("kth smallest elment for k = %d is %d", k, kNode->data);
}
else
{
printf("There is no such element");
}

getchar();
return 0;
}
Method2:AugmentedTreeDataStructure.
Theideaistomaintainrankofeachnode.Wecankeeptrackofelementsinasubtreeofanynodewhile
buildingthetree.SinceweneedKthsmallestelement,wecanmaintainnumberofelementsofleftsubtree
ineverynode.
AssumethattherootishavingNnodesinitsleftsubtree.IfK=N+1,rootisKthnode.IfK<N,wewill
continueoursearch(recursion)fortheKthsmallestelementintheleftsubtreeofroot.IfK>N+1,we
continueoursearchintherightsubtreeforthe(KN1)thsmallestelement.Notethatweneedthecount
ofelementsinleftsubtreeonly.
Timecomplexity:O(n)wherenistotalnodesintree.
Algorithm:

start:
ifK=root.leftElement+1
rootnodeistheKthnode.
gotostop
elseifK>root.leftElements
K=K(root.leftElements+1)
root=root.right
gotostart

else
root=root.left
gotosrart

stop:
Implementation:
#include <stdio.h>
#include <stdlib.h>

#define ARRAY_SIZE(arr) sizeof(arr)/sizeof(arr[0])

typedef struct node_t node_t;

/* Binary tree node */


struct node_t
{
int data;
int lCount;

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;

// Traverse till appropriate node


while(pTraverse)
{
currentParent = pTraverse;

if( node->data < pTraverse->data )


{
/* We are branching to left subtree
increment node count */
pTraverse->lCount++;
/* left subtree */
pTraverse = pTraverse->left;
}
else
{
/* right subtree */
pTraverse = pTraverse->right;
}
}

/* If the tree is empty, make it as root node */


if( !root )
{
root = node;
}
else if( node->data < currentParent->data )
{
/* Insert on left side */
currentParent->left = node;
}
else
{
/* Insert on right side */
currentParent->right = node;
}

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;

for(iterator = 0; iterator < size; iterator++)


{
new_node = (node_t *)malloc( sizeof(node_t) );

/* initialize */
new_node->data

= keys[iterator];

new_node->lCount = 0;
new_node->left

= NULL;

new_node->right = NULL;

/* insert into BST */


root = insert_node(root, new_node);
}

return root;
}

int k_smallest_element(node_t *root, int k)


{
int ret = -1;

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;
}

/* Driver program to test above functions */


int main(void)
{
/* just add elements to test */
/* NOTE: A sorted array results in skewed tree */
int ele[] = { 20, 8, 22, 4, 12, 10, 14 };
int i;
node_t* root = NULL;

/* Creating the tree given in the above diagram */


root = binary_search_tree(root, ele, ARRAY_SIZE(ele));

/* It should print the sorted array */


for(i = 1; i <= ARRAY_SIZE(ele); i++)
{
printf("\n kth smallest elment for k = %d is %d",
i, k_smallest_element(root, i));
}

getchar();
return 0;
}

=======================================================================

InorderSuccessorinBinarySearch
Tree
InBinaryTree,InordersuccessorofanodeisthenextnodeinInordertraversaloftheBinaryTree.Inorder
SuccessorisNULLforthelastnodeinInoordertraversal.
InBinarySearchTree,InorderSuccessorofaninputnodecanalsobedefinedasthenodewiththesmallest
keygreaterthanthekeyofinputnode.So,itissometimesimportanttofindnextnodeinsortedorder.

Intheabovediagram,inordersuccessorof8is10,inordersuccessorof10is12andinordersuccessorof
14is20.
Method1(UsesParentPointer)
Inthismethod,weassumethateverynodehasparentpointer.
TheAlgorithmisdividedintotwocasesonthebasisofrightsubtreeoftheinputnodebeingemptyornot.
Input:node,root//nodeisthenodewhoseInordersuccessorisneeded.
output:succ//succisInordersuccessorofnode.
1)IfrightsubtreeofnodeisnotNULL,thensuccliesinrightsubtree.Dofollowing.
Gotorightsubtreeandreturnthenodewithminimumkeyvalueinrightsubtree.

2)IfrightsbtreeofnodeisNULL,thensuccisoneoftheancestors.Dofollowing.
Travelupusingtheparentpointeruntilyouseeanodewhichisleftchildofitsparent.Theparentofsucha
nodeisthesucc.
Implementation
NotethatthefunctiontofindInOrderSuccessorishighlighted(withgraybackground)inbelowcode.
#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;
struct node* parent;
};

struct node * minValue(struct node* node);

struct node * inOrderSuccessor(struct node *root, struct node *n)


{
// step 1 of the above algorithm
if( n->right != NULL )
return minValue(n->right);

// step 2 of the above algorithm


struct node *p = n->parent;
while(p != NULL && n == p->right)
{
n = p;
p = p->parent;
}
return p;
}

/* Given a non-empty binary search tree, return the minimum data

value found in that tree. Note that the entire tree does not need
to be searched. */
struct node * minValue(struct node* node) {
struct node* current = node;

/* loop down to find the leftmost leaf */


while (current->left != NULL) {
current = current->left;
}
return current;
}

/* 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;

/* 2. Otherwise, recur down the tree */


if (data <= node->data)
{
temp = insert(node->left, data);
node->left = temp;
temp->parent= node;
}
else
{
temp = insert(node->right, data);
node->right = temp;
temp->parent = node;
}

/* return the (unchanged) node pointer */


return node;
}
}

/* Driver program to test above functions*/


int main()
{
struct node* root = NULL, *temp, *succ, *min;

//creating the tree given in the above diagram


root = insert(root, 20);
root = insert(root, 8);
root = insert(root, 22);
root = insert(root, 4);
root = insert(root, 12);
root = insert(root, 10);
root = insert(root, 14);
temp = root->left->right->right;

succ = inOrderSuccessor(root, temp);


if(succ != NULL)
printf("\n Inorder Successor of %d is %d ", temp->data, succ->data);
else
printf("\n Inorder Successor doesn't exit");

getchar();
return 0;
}
Outputoftheaboveprogram:
InorderSuccessorof14is20
TimeComplexity:O(h)wherehisheightoftree.

Method2(Searchfromroot)
ParentpointerisNOTneededinthisalgorithm.TheAlgorithmisdividedintotwocasesonthebasisofright
subtreeoftheinputnodebeingemptyornot.
Input:node,root//nodeisthenodewhoseInordersuccessorisneeded.
output:succ//succisInordersuccessorofnode.
1)IfrightsubtreeofnodeisnotNULL,thensuccliesinrightsubtree.Dofollowing.
Gotorightsubtreeandreturnthenodewithminimumkeyvalueinrightsubtree.
2)IfrightsbtreeofnodeisNULL,thenstartfromrootandussearchliketechnique.Dofollowing.
Traveldownthetree,ifanodesdataisgreaterthanrootsdatathengorightside,otherwisegotoleftside.
struct node * inOrderSuccessor(struct node *root, struct node *n)
{
// step 1 of the above algorithm
if( n->right != NULL )
return minValue(n->right);

struct node *succ = NULL;

// 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;
}
TimeComplexity:O(h)wherehisheightoftree.

=======================================================================

Applicationsoftreedatastructure
DifficultyLevel:Rookie
WhyTree?
UnlikeArrayandLinkedList,whicharelineardatastructures,treeishierarchical(ornonlinear)data
structure.
1)

Onereasontousetreesmightbebecauseyouwanttostoreinformationthatnaturallyformsa

hierarchy.Forexample,thefilesystemonacomputer:
filesystem

/<root
/\
...home
/\
ugradcourse
//|\
...cs101cs112cs113

2)

Ifweorganizekeysinformofatree(withsomeorderinge.g.,BST),wecansearchforagivenkey

inmoderatetime(quickerthanLinkedListandslowerthanarrays).SelfbalancingsearchtreeslikeAVLand
RedBlacktreesguaranteeanupperboundofO(Logn)forsearch.

3)

Wecaninsert/deletekeysinmoderatetime(quickerthanArraysandslowerthanUnorderedLinked

Lists).SelfbalancingsearchtreeslikeAVLandRedBlacktreesguaranteeanupperboundofO(Logn)for
insertion/deletion.
4)

LikeLinkedListsandunlikeArrays,Pointerimplementationoftreesdonthaveanupperlimiton

numberofnodesasnodesarelinkedusingpointers.
AsperWikipedia,followingarethecommonusesoftree.
1.

Manipulatehierarchicaldata.

2.

Makeinformationeasytosearch(seetreetraversal).

3.

Manipulatesortedlistsofdata.

4.

Asaworkflowforcompositingdigitalimagesforvisualeffects.

5.

Routeralgorithms

=======================================================================

Sortedorderprintingofagiven
arraythatrepresentsaBST
GivenanarraythatstoresacompleteBinarySearchTree,writeafunctionthatefficientlyprintsthegiven
arrayinascendingorder.
Forexample,givenanarray[4,2,5,1,3],thefunctionshouldprint1,2,3,4,5

Solution:
InordertraversalofBSTprintsitinascendingorder.Theonlytrickistomodifyrecursiontermination
conditioninstandardInorderTreeTraversal.
Implementation:
#include<stdio.h>

void printSorted(int arr[], int start, int end)


{
if(start > end)
return;

// print left subtree


printSorted(arr, start*2 + 1, end);

// print root
printf("%d ", arr[start]);

// print right subtree


printSorted(arr, start*2 + 2, end);
}

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;
}
TimeComplexity:O(n)

=======================================================================

Printnodesatkdistancefromroot
Givenarootofatree,andanintegerk.Printallthenodeswhichareatkdistancefromroot.
Forexample,inthebelowtree,4,5&8areatdistance2fromroot.

1
/\
23
/\/
458

Theproblemcanbesolvedusingrecursion.Thankstoeldhoforsuggestingthesolution.
#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;
};

void printKDistant(node *root , int k)


{
if(root == NULL)
return;
if( k == 0 )
{
printf( "%d ", root->data );
return ;
}
else
{
printKDistant( root->left, k-1 ) ;
printKDistant( root->right, k-1 ) ;
}
}

/* 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);
}

/* Driver program to test above functions*/


int main()
{

/* Constructed binary tree is


1
/

/ \

4 5 8
*/
struct node *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(8);

printKDistant(root, 2);

getchar();
return 0;
}
Theaboveprogramprints4,5and8.
TimeComplexity:O(n)wherenisnumberofnodesinthegivenbinarytree.

=======================================================================

FoldableBinaryTrees
Question:Givenabinarytree,findoutifthetreecanbefoldedornot.

Atreecanbefoldedifleftandrightsubtreesofthetreearestructurewisemirrorimageofeachother.An
emptytreeisconsideredasfoldable.

Considerthebelowtrees:
(a)and(b)canbefolded.
(c)and(d)cannotbefolded.

(a)
10
/\
715
\/
911

(b)
10
/\
715
/\
911

(c)
10
/\
715
//
511

(d)

10
/\
715
/\/
91012

Method1(ChangeLeftsubtreetoitsMirrorandcompareitwithRightsubtree)
Algorithm:isFoldable(root)

1)Iftreeisempty,thenreturntrue.
2)Converttheleftsubtreetoitsmirrorimage
mirror(root>left)/*Seethispost*/
3)Checkifthestructureofleftsubtreeandrightsubtreeissame
andstoretheresult.
res=isStructSame(root>left,root>right)/*isStructSame()
recursivelycomparesstructuresoftwosubtreesandreturns
trueifstructuresaresame*/
4)Revertthechangesmadeinstep(2)togettheoriginaltree.
mirror(root>left)
5)Returnresultresstoredinstep2.

Thankstoajaymforsuggestingthisapproach.
#include<stdio.h>
#include<stdlib.h>

/* You would want to remove below 3 lines if your compiler


supports bool, true and false */
#define bool int
#define true 1
#define false 0

/* 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;
};

/* converts a tree to its mrror image */


void mirror(struct node* node);

/* returns true if structure of two trees a and b is same


Only structure is considered for comparison, not data! */
bool isStructSame(struct node *a, struct node *b);

/* Returns true if the given tree is foldable */


bool isFoldable(struct node *root)
{
bool res;

/* base case */
if(root == NULL)
return true;

/* convert left subtree to its mirror */


mirror(root->left);

/* Compare the structures of the right subtree and mirrored


left subtree */
res = isStructSame(root->left, root->right);

/* Get the originial tree back */


mirror(root->left);

return res;
}

bool isStructSame(struct node *a, struct node *b)


{
if (a == NULL && b == NULL)
{ return true; }
if ( a != NULL && b != NULL &&
isStructSame(a->left, b->left) &&
isStructSame(a->right, b->right)
)
{ 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);

/* swap the pointers in this node */


temp

= node->left;

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

/* 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);
}

/* Driver program to test mirror() */


int main(void)
{
/* The constructed binary tree is
1
/

4 5
*/
struct node *root = newNode(1);
root->left

= newNode(2);

root->right

= newNode(3);

root->right->left = newNode(4);
root->left->right = newNode(5);

if(isFoldable(root) == 1)
{ printf("\n tree is foldable"); }
else
{ printf("\n tree is not foldable"); }

getchar();
return 0;
}
Timecomplexity:O(n)
Method2(CheckifLeftandRightsubtreesareMirror)
Therearemainlytwofunctions:
//Checksiftreecanbefoldedornot

IsFoldable(root)
1)Iftreeisemptythenreturntrue
2)Elsecheckifleftandrightsubtreesarestructurewisemirrorsof
eachother.UseutilityfunctionIsFoldableUtil(root>left,
root>right)forthis.

//Checksifn1andn2aremirrorofeachother.

IsFoldableUtil(n1,n2)
1)Ifbothtreesareemptythenreturntrue.

2)Ifoneofthemisemptyandotherisnotthenreturnfalse.
3)Returntrueiffollowingconditionsaremet
a)n1>leftismirrorofn2>right
b)n1>rightismirrorofn2>left

#include<stdio.h>
#include<stdlib.h>

/* You would want to remove below 3 lines if your compiler


supports bool, true and false */
#define bool int
#define true 1
#define false 0

/* 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;
};

/* A utility function that checks if trees with roots as n1 and n2


are mirror of each other */
bool IsFoldableUtil(struct node *n1, struct node *n2);

/* Returns true if the given tree can be folded */


bool IsFoldable(struct node *root)
{
if (root == NULL)
{ return true; }

return IsFoldableUtil(root->left, root->right);


}

/* A utility function that checks if trees with roots as n1 and n2

are mirror of each other */


bool IsFoldableUtil(struct node *n1, struct node *n2)
{
/* If both left and right subtrees are NULL,
then return true */
if (n1 == NULL && n2 == NULL)
{ return true; }

/* If one of the trees is NULL and other is not,


then return false */
if (n1 == NULL || n2 == NULL)
{ return false; }

/* Otherwise check if left and right subtrees are mirrors of


their counterparts */
return IsFoldableUtil(n1->left, n2->right) &&
IsFoldableUtil(n1->right, n2->left);
}

/*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);
}

/* Driver program to test mirror() */


int main(void)
{
/* The constructed binary tree is

1
/

4 5
*/
struct node *root = newNode(1);
root->left

= newNode(2);

root->right

= newNode(3);

root->left->right = newNode(4);
root->right->left = newNode(5);

if(IsFoldable(root) == true)
{ printf("\n tree is foldable"); }
else
{ printf("\n tree is not foldable"); }

getchar();
return 0;
}

================================================================
=======

TotalnumberofpossibleBinary
SearchTreeswithnkeys
TotalnumberofpossibleBinarySearchTreeswithndifferentkeys=CatalannumberCn=(2n)!/(n+1)!*n!
Seereferencesforproofandexamples.
References:
http://en.wikipedia.org/wiki/Catalan_number

=======================================================================

Maximumwidthofabinarytree
Givenabinarytree,writeafunctiontogetthemaximumwidthofthegiventree.Widthofatreeismaximum
ofwidthsofalllevels.
Letusconsiderthebelowexampletree.

1
/\
23
/\\
458
/\
67

Fortheabovetree,
widthoflevel1is1,
widthoflevel2is2,
widthoflevel3is3
widthoflevel4is2.
Sothemaximumwidthofthetreeis3.

Method1(UsingLevelOrderTraversal)
Thismethodmainlyinvolvestwofunctions.Oneistocountnodesatagivenlevel(getWidth),andotheristo
getthemaximumwidthofthetree(getMaxWidth).getMaxWidth()makesuseofgetWidth()togetthewidthof
alllevelsstartingfromroot.

/*Functiontoprintlevelordertraversaloftree*/
getMaxWidth(tree)
maxWdth=0
fori=1toheight(tree)
width=getWidth(tree,i)
if(width>maxWdth)
maxWdth=width
returnwidth

/*Functiontogetwidthofagivenlevel*/
getWidth(tree,level)

iftreeisNULLthenreturn0
iflevelis1,thenreturn1
elseiflevelgreaterthan1,then
returngetWidth(tree>left,level1)+
getWidth(tree>right,level1)

#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;
};

/*Function protoypes*/
int getWidth(struct node* root, int level);
int height(struct node* node);
struct node* newNode(int data);

/* Function to get the maximum width of a binary tree*/


int getMaxWidth(struct node* root)
{
int maxWidth = 0;
int width;
int h = height(root);
int i;

/* Get width of each level and compare


the width with maximum width so far */
for(i=1; i<=h; i++)
{
width = getWidth(root, i);
if(width > maxWidth)

maxWidth = width;
}

return maxWidth;
}

/* Get width of a given level */


int getWidth(struct node* root, int level)
{

if(root == NULL)
return 0;

if(level == 1)
return 1;

else if (level > 1)


return getWidth(root->left, level-1) +
getWidth(root->right, level-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 */

return (lHeight > rHeight)? (lHeight+1): (rHeight+1);


}
}
/* 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);
}
/* Driver program to test above functions*/
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->right->right = newNode(8);
root->right->right->left = newNode(6);
root->right->right->right = newNode(7);

/*
Constructed bunary tree is:
1
/ \
2

/ \

8
/ \
6

*/
printf("Maximum width is %d \n", getMaxWidth(root));

getchar();
return 0;
}
TimeComplexity:O(n^2)intheworstcase.
WecanuseQueuebasedlevelordertraversaltooptimizethetimecomplexityofthismethod.TheQueue
basedlevelordertraversalwilltakeO(n)timeinworstcase.ThankstoNitish,DivyaCandtech.login.id2for
suggestingthisoptimization.Seetheircommentsforimplementationusingqueuebasedtraversal.

Method2(UsingPreorderTraversal)
Inthismethodwecreateatemporaryarraycount[]ofsizeequaltotheheightoftree.Weinitializeallvalues
incountas0.Wetraversethetreeusingpreordertraversalandfilltheentriesincountsothatthecount
arraycontainscountofnodesateachlevelinBinaryTree.
#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;
};

// A utility function to get height of a binary tree


int height(struct node* node);

// A utility function to allocate a new node with given data


struct node* newNode(int data);

// A utility function that returns maximum value in arr[] of size n


int getMax(int arr[], int n);

// A function that fills count array with count of nodes at every


// level of given binary tree
void getMaxWidthRecur(struct node *root, int count[], int level);

/* Function to get the maximum width of a binary tree*/


int getMaxWidth(struct node* root)
{
int width;
int h = height(root);

// Create an array that will store count of nodes at each level


int *count = (int *)calloc(sizeof(int), h);

int level = 0;

// Fill the count array using preorder traversal


getMaxWidthRecur(root, count, level);

// Return the maximum value from count array


return getMax(count, h);
}

// A function that fills count array with count of nodes at every


// level of given binary tree
void getMaxWidthRecur(struct node *root, int count[], int level)
{
if(root)
{
count[level]++;
getMaxWidthRecur(root->left, count, level+1);
getMaxWidthRecur(root->right, count, level+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 */

return (lHeight > rHeight)? (lHeight+1): (rHeight+1);


}
}
/* 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);
}

// Return the maximum value from count array


int getMax(int arr[], int n)
{
int max = arr[0];
int i;
for (i = 0; i < n; i++)
{
if (arr[i] > max)
max = arr[i];
}
return max;

/* Driver program to test above functions*/


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->right->right = newNode(8);
root->right->right->left = newNode(6);
root->right->right->right = newNode(7);

/*
Constructed bunary tree is:
1
/ \
2

/ \

8
/ \
6

*/
printf("Maximum width is %d \n", getMaxWidth(root));
getchar();
return 0;
}
TimeComplexity:O(n)

=======================================================================

DoubleTree
WriteaprogramthatconvertsagiventreetoitsDoubletree.TocreateDoubletreeofthegiventree,create
anewduplicateforeachnode,andinserttheduplicateastheleftchildoftheoriginalnode.

Sothetree

2
/\
13

ischangedto

2
/\
23
//
13
/
1

Andthetree

1
/\
23
/\
45

ischangedto

1
/\
13
//
23
/\
25
//
45
/
4

Algorithm:

Recursivelyconvertthetreetodoubletreeinpostorderfashion.Foreachnode,firstconverttheleftsubtree
ofthenode,thenrightsubtree,finallycreateaduplicatenodeofthenodeandfixtheleftchildofthenode
andleftchildofleftchild.
Implementation:
#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;
};

/* function to create a new node of tree and returns pointer */


struct node* newNode(int data);

/* Function to convert a tree to double tree */


void doubleTree(struct node* node)
{
struct node* oldLeft;

if (node==NULL) return;

/* do the subtrees */
doubleTree(node->left);
doubleTree(node->right);

/* duplicate this node to its left */


oldLeft = node->left;
node->left = newNode(node->data);
node->left->left = oldLeft;
}

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


/* 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);
}

/* Given a binary tree, print its nodes in inorder*/


void printInorder(struct node* node)
{
if (node == NULL)
return;
printInorder(node->left);
printf("%d ", node->data);
printInorder(node->right);
}

/* Driver program to test above functions*/


int main()
{

/* Constructed binary tree is


1
/
2
/ \
4 5
*/

\
3

struct node *root = newNode(1);


root->left

= newNode(2);

root->right

= newNode(3);

root->left->left = newNode(4);
root->left->right = newNode(5);

printf("Inorder traversal of the original tree is \n");


printInorder(root);

doubleTree(root);

printf("\n Inorder traversal of the double tree is \n");


printInorder(root);

getchar();
return 0;
}
TimeComplexity:O(n)wherenisthenumberofnodesinthetree.

=======================================================================

Givenabinarytree,printall
roottoleafpaths
Forthebelowexampletree,allroottoleafpathsare:
10>8>3
10>8>5
10>2>2


Algorithm:
Useapatharraypath[]tostorecurrentroottoleafpath.Traversefromroottoallleavesintopdownfashion.
Whiletraversing,storedataofallnodesincurrentpathinarraypath[].Whenwereachaleafnode,printthe
patharray.
#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;
};

/* Prototypes for funtions needed in printPaths() */


void printPathsRecur(struct node* node, int path[], int pathLen);
void printArray(int ints[], int len);

/*Given a binary tree, print out all of its root-to-leaf


paths, one per line. Uses a recursive helper to do the work.*/
void printPaths(struct node* node)
{
int path[1000];
printPathsRecur(node, path, 0);
}

/* Recursive helper function -- given a node, and an array containing


the path from the root node up to but not including this node,
print out all the root-leaf paths.*/
void printPathsRecur(struct node* node, int path[], int pathLen)
{
if (node==NULL)
return;

/* append this node to the path array */


path[pathLen] = node->data;
pathLen++;

/* it's a leaf, so print the path that led to here */


if (node->left==NULL && node->right==NULL)
{
printArray(path, pathLen);
}
else
{
/* otherwise try both subtrees */
printPathsRecur(node->left, path, pathLen);
printPathsRecur(node->right, path, pathLen);
}
}

/* 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");

/* utility 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);
}

/* Driver program to test above functions*/


int main()
{

/* Constructed binary tree is


10
/

/ \

3 5 2
*/
struct node *root = newnode(10);
root->left

= newnode(8);

root->right

= newnode(2);

root->left->left = newnode(3);
root->left->right = newnode(5);
root->right->left = newnode(2);

printPaths(root);

getchar();
return 0;

}
TimeComplexity:O(n)

=======================================================================

ConstructTreefromgivenInorder
andPreordertraversals
Letusconsiderthebelowtraversals:
Inordersequence:DBEAFC
Preordersequence:ABDECF
InaPreordersequence,leftmostelementistherootofthetree.SoweknowAisrootforgivensequences.
BysearchingAinInordersequence,wecanfindoutallelementsonleftsideofAareinleftsubtreeand
elementsonrightareinrightsubtree.Soweknowbelowstructurenow.

A
/\
/\
DBEFC

Werecursivelyfollowabovestepsandgetthefollowingtree.

A
/\
/\
BC
/\/
/\/
DEF

Algorithm:buildTree()
1)PickanelementfromPreorder.IncrementaPreorderIndexVariable(preIndexinbelowcode)topicknext
elementinnextrecursivecall.
2)CreateanewtreenodetNodewiththedataaspickedelement.
3)FindthepickedelementsindexinInorder.LettheindexbeinIndex.
4)CallbuildTreeforelementsbeforeinIndexandmakethebuilttreeasleftsubtreeoftNode.
5)CallbuildTreeforelementsafterinIndexandmakethebuilttreeasrightsubtreeoftNode.
6)returntNode.

ThankstoRohiniandTusharforsuggestingthecode.
/* program to construct tree using inorder and preorder traversals */
#include<stdio.h>
#include<stdlib.h>

/* A binary tree node has data, pointer to left child


and a pointer to right child */
struct node
{
char data;
struct node* left;
struct node* right;
};

/* Prototypes for utility functions */


int search(char arr[], int strt, int end, char value);
struct node* newNode(char data);

/* Recursive function to construct binary of size len from


Inorder traversal in[] and Preorder traversal pre[]. Initial values
of inStrt and inEnd should be 0 and len -1. The function doesn't
do any error checking for cases where inorder and preorder
do not form a tree */
struct node* buildTree(char in[], char pre[], int inStrt, int inEnd)
{
static int preIndex = 0;

if(inStrt > inEnd)


return NULL;

/* Pick current node from Preorder traversal using preIndex


and increment preIndex */
struct node *tNode = newNode(pre[preIndex++]);

/* If this node has no children then return */


if(inStrt == inEnd)
return tNode;

/* Else find the index of this node in Inorder traversal */


int inIndex = search(in, inStrt, inEnd, tNode->data);

/* Using index in Inorder traversal, construct left and


right subtress */
tNode->left = buildTree(in, pre, inStrt, inIndex-1);
tNode->right = buildTree(in, pre, inIndex+1, inEnd);

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;
}
}

/* Helper function that allocates a new node with the


given data and NULL left and right pointers. */
struct node* newNode(char data)
{
struct node* node = (struct node*)malloc(sizeof(struct node));
node->data = data;
node->left = NULL;
node->right = NULL;

return(node);
}

/* This funtcion is here just to test buildTree() */


void printInorder(struct node* node)
{
if (node == NULL)
return;

/* first recur on left child */


printInorder(node->left);

/* then print the data of node */


printf("%c ", node->data);

/* now recur on right child */


printInorder(node->right);
}

/* Driver program to test above functions */


int main()
{
char in[] = {'D', 'B', 'E', 'A', 'F', 'C'};
char pre[] = {'A', 'B', 'D', 'E', 'C', 'F'};
int len = sizeof(in)/sizeof(in[0]);
struct node *root = buildTree(in, pre, 0, len - 1);

/* Let us test the built tree by printing Insorder traversal */


printf("\n Inorder traversal of the constructed tree is \n");
printInorder(root);
getchar();
}
TimeComplexity:O(n^2).Worstcaseoccurswhentreeisleftskewed.ExamplePreorderandInorder
traversalsforworstcaseare{A,B,C,D}and{D,C,B,A}.

=======================================================================

Roottoleafpathsumequaltoa
givennumber
Givenabinarytreeandanumber,returntrueifthetreehasaroottoleafpathsuchthataddingupallthe
valuesalongthepathequalsthegivennumber.Returnfalseifnosuchpathcanbefound.

Forexample,intheabovetreeroottoleafpathsexistwithfollowingsums.
21>1083
23>1085
14>1022
Sothereturnedvalueshouldbetrueonlyfornumbers21,23and14.Foranyothernumber,returnedvalue
shouldbefalse.
Algorithm:
Recursivelycheckifleftorrightchildhaspathsumequalto(numbervalueatcurrentnode)
Implementation:
#include<stdio.h>
#include<stdlib.h>
#define bool int

/* 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;


};

/*
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;

/* otherwise check both subtrees */


int subSum = sum - node->data;

/* If we reach a leaf node and sum becomes 0 then return true*/


if ( subSum == 0 && node->left == NULL && node->right == NULL )
return 1;

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);
}

/* Driver program to test above functions*/


int main()
{

int sum = 21;

/* Constructed binary tree is


10
/

/ \

3 5 2
*/
struct node *root = newnode(10);
root->left

= newnode(8);

root->right

= newnode(2);

root->left->left = newnode(3);
root->left->right = newnode(5);
root->right->left = newnode(2);

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;
}
TimeComplexity:O(n)
References:

=======================================================================

InorderTreeTraversalwithout
recursionandwithoutstack!
UsingMorrisTraversal,wecantraversethetreewithoutusingstackandrecursion.TheideaofMorris
TraversalisbasedonThreadedBinaryTree.Inthistraversal,wefirstcreatelinkstoInordersuccessorand
printthedatausingtheselinks,andfinallyrevertthechangestorestoreoriginaltree.

1.Initializecurrentasroot
2.WhilecurrentisnotNULL
Ifcurrentdoesnothaveleftchild
a)Printcurrentsdata
b)Gototheright,i.e.,current=current>right
Else
a)Makecurrentasrightchildoftherightmostnodeincurrent'sleftsubtree
b)Gotothisleftchild,i.e.,current=current>left

Althoughthetreeismodifiedthroughthetraversal,itisrevertedbacktoitsoriginalshapeafterthe
completion.UnlikeStackbasedtraversal,noextraspaceisrequiredforthistraversal.
#include<stdio.h>
#include<stdlib.h>

/* A binary tree tNode has data, pointer to left child


and a pointer to right child */
struct tNode
{

int data;
struct tNode* left;
struct tNode* right;
};

/* Function to traverse binary tree without recursion and


without stack */
void MorrisTraversal(struct tNode *root)
{
struct tNode *current,*pre;

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;

/* Make current as right child of its inorder predecessor */


if(pre->right == NULL)
{
pre->right = current;
current = current->left;
}

/* Revert the changes made in if part to restore the original

tree i.e., fix the right child of predecssor */


else
{
pre->right = NULL;
printf(" %d ",current->data);
current = current->right;
} /* End of if condition pre->right == NULL */
} /* End of if condition current->left == NULL*/
} /* End of while */
}

/* 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);
}

/* Driver program to test above functions*/


int main()
{

/* Constructed binary tree is


1
/
2

\
3

/ \
4 5
*/
struct tNode *root = newtNode(1);

root->left

= newtNode(2);

root->right

= newtNode(3);

root->left->left = newtNode(4);
root->left->right = newtNode(5);

MorrisTraversal(root);

getchar();
return 0;
}

================================================================
=======

InorderTreeTraversalwithout
Recursion
UsingStackistheobviouswaytotraversetreewithoutrecursion.Belowisanalgorithmfortraversingbinary
treeusingstack.Seethisforstepwisestepexecutionofthealgorithm.

1)CreateanemptystackS.
2)Initializecurrentnodeasroot
3)PushthecurrentnodetoSandsetcurrent=current>leftuntilcurrentisNULL
4)IfcurrentisNULLandstackisnotemptythen
a)Popthetopitemfromstack.
b)Printthepoppeditem,setcurrent=popped_item>right
c)Gotostep3.
5)IfcurrentisNULLandstackisemptythenwearedone.

Letusconsiderthebelowtreeforexample

1
/\
23
/\
45

Step1Createsanemptystack:S=NULL

Step2setscurrentasaddressofroot:current>1

Step3Pushesthecurrentnodeandsetcurrent=current>leftuntilcurrentisNULL
current>1
push1:StackS>1
current>2
push2:StackS>2,1
current>4
push4:StackS>4,2,1
current=NULL

Step4popsfromS
a)Pop4:StackS>2,1
b)print"4"
c)current=NULL/*rightof4*/andgotostep3
SincecurrentisNULLstep3doesn'tdoanything.

Step4popsagain.
a)Pop2:StackS>1
b)print"2"
c)current>5/*rightof2*/andgotostep3

Step3pushes5tostackandmakescurrentNULL
StackS>5,1
current=NULL

Step4popsfromS
a)Pop5:StackS>1
b)print"5"
c)current=NULL/*rightof5*/andgotostep3
SincecurrentisNULLstep3doesn'tdoanything

Step4popsagain.
a)Pop1:StackS>NULL
b)print"1"

c)current>3/*rightof5*/

Step3pushes3tostackandmakescurrentNULL
StackS>3
current=NULL

Step4popsfromS
a)Pop3:StackS>NULL
b)print"3"
c)current=NULL/*rightof3*/

TraversalisdonenowasstackSisemptyandcurrentisNULL.

Implementation:
#include<stdio.h>
#include<stdlib.h>
#define bool int

/* A binary tree tNode has data, pointer to left child


and a pointer to right child */
struct tNode
{
int data;
struct tNode* left;
struct tNode* right;
};

/* Structure of a stack node. Linked List implementation is used for


stack. A stack node contains a pointer to tree node and a pointer to
next stack node */
struct sNode
{
struct tNode *t;
struct sNode *next;
};

/* Stack related functions */

void push(struct sNode** top_ref, struct tNode *t);


struct tNode *pop(struct sNode** top_ref);
bool isEmpty(struct sNode *top);

/* Iterative function for inorder tree traversal */


void inOrder(struct tNode *root)
{
/* set current to root of binary tree */
struct tNode *current = root;
struct sNode *s = NULL; /* Initialize stack s */
bool done = 0;

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;
}

/* backtrack from the empty subtree and visit the tNode


at the top of the stack; however, if the stack is empty,
you are done */
else
{
if (!isEmpty(s))
{
current = pop(&s);
printf("%d ", current->data);

/* we have visited the node and its left subtree.


Now, it's right subtree's turn */
current = current->right;
}

else
done = 1;
}
} /* end of while */
}

/* UTILITY FUNCTIONS */
/* Function to push an item to sNode*/
void push(struct sNode** top_ref, struct tNode *t)
{
/* allocate tNode */
struct sNode* new_tNode =
(struct sNode*) malloc(sizeof(struct sNode));

if(new_tNode == NULL)
{
printf("Stack Overflow \n");
getchar();
exit(0);
}

/* put in the data */


new_tNode->t = t;

/* link the old list off the new tNode */


new_tNode->next = (*top_ref);

/* move the head to point to the new tNode */


(*top_ref) = new_tNode;
}

/* The function returns true if stack is empty, otherwise false */


bool isEmpty(struct sNode *top)
{
return (top == NULL)? 1 : 0;
}

/* Function to pop an item from stack*/


struct tNode *pop(struct sNode** top_ref)
{
struct tNode *res;
struct sNode *top;

/*If sNode is empty then error */


if(isEmpty(*top_ref))
{
printf("Stack Underflow \n");
getchar();
exit(0);
}
else
{
top = *top_ref;
res = top->t;
*top_ref = top->next;
free(top);
return res;
}
}

/* 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);
}

/* Driver program to test above functions*/

int main()
{

/* Constructed binary tree is


1
/
2

\
3

/ \
4 5
*/
struct tNode *root = newtNode(1);
root->left

= newtNode(2);

root->right

= newtNode(3);

root->left->left = newtNode(4);
root->left->right = newtNode(5);

inOrder(root);

getchar();
return 0;
}
TimeComplexity:O(n)

=======================================================================

Howtodetermineifabinarytreeis
heightbalanced?
Atreewherenoleafismuchfartherawayfromtherootthananyotherleaf.Differentbalancingschemes
allowdifferentdefinitionsofmuchfartheranddifferentamountsofworktokeepthembalanced.
Consideraheightbalancingschemewherefollowingconditionsshouldbecheckedtodetermineifabinary
treeisbalanced.
Anemptytreeisheightbalanced.AnonemptybinarytreeTisbalancedif:
1)LeftsubtreeofTisbalanced
2)RightsubtreeofTisbalanced

3)Thedifferencebetweenheightsofleftsubtreeandrightsubtreeisnotmorethan1.
TheaboveheightbalancingschemeisusedinAVLtrees.Thediagrambelowshowstwotrees,oneofthem
isheightbalancedandotherisnot.Thesecondtreeisnotheightbalancedbecauseheightofleftsubtreeis
2morethanheightofrightsubtree.

Tocheckifatreeisheightbalanced,gettheheightofleftandrightsubtrees.Returntrueifdifference
betweenheightsisnotmorethan1andleftandrightsubtreesarebalanced,otherwisereturnfalse.
/* program to check if a tree is height-balanced or not */
#include<stdio.h>
#include<stdlib.h>
#define bool int

/* 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;
};

/* Returns the height of a binary tree */


int height(struct node* node);

/* Returns true if binary tree with root as root is height-balanced */


bool isBalanced(struct node *root)

{
int lh; /* for height of left subtree */
int rh; /* for height of right subtree */

/* If tree is empty then return true */


if(root == NULL)
return 1;

/* Get the height of left and right sub trees */


lh = height(root->left);
rh = height(root->right);

if( abs(lh-rh) <= 1 &&


isBalanced(root->left) &&
isBalanced(root->right))
return 1;

/* If we reach here then tree is not height-balanced */


return 0;
}

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

/* returns maximum of two integers */


int max(int a, int b)
{
return (a >= b)? a: b;
}

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


number of nodes along the longest path from the root node
down to the farthest leaf node.*/
int height(struct node* node)
{
/* base case tree is empty */
if(node == NULL)
return 0;

/* If tree is not empty then height = 1 + max of left


height and right heights */
return 1 + max(height(node->left), height(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);
}

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;
}
TimeComplexity:O(n^2)Worstcaseoccursincaseofskewedtree.

Optimizedimplementation:Aboveimplementationcanbeoptimizedbycalculatingtheheightinthesame
recursionratherthancallingaheight()functionseparately.ThankstoAmarforsuggestingthisoptimized
version.ThisoptimizationreducestimecomplexitytoO(n).
/* program to check if a tree is height-balanced or not */
#include<stdio.h>
#include<stdlib.h>
#define bool int

/* 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;
};

/* The function returns true if root is balanced else false


The second parameter is to store the height of tree.
Initially, we need to pass a pointer to a location with value
as 0. We can also write a wrapper over this function */
bool isBalanced(struct node *root, int* height)
{
/* lh --> Height of left subtree
rh --> Height of right subtree */
int lh = 0, rh = 0;

/* l will be true if left subtree is balanced


and r will be true if right subtree is balanced */
int l = 0, r = 0;

if(root == NULL)
{
*height = 0;
return 1;

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


And store the returned values in l and r */
l = isBalanced(root->left, &lh);
r = isBalanced(root->right,&rh);

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


right subtrees plus 1*/
*height = (lh > rh? lh: rh) + 1;

/* If difference between heights of left and right


subtrees is more than 2 then this node is not balanced
so return 0 */
if((lh - rh >= 2) || (rh - lh >= 2))
return 0;

/* If this node is balanced and left and right subtrees


are balanced then return true */
else return l&&r;
}

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

/* 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);
}

int main()
{
int height = 0;

/* Constructed binary tree is


1
/
2

\
3

/ \ /
4

5 6

/
7
*/
struct node *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->left->left->left = newNode(7);

if(isBalanced(root, &height))
printf("Tree is balanced");
else
printf("Tree is not balanced");

getchar();
return 0;
}
TimeComplexity:O(n)

=======================================================================

DiameterofaBinaryTree
Thediameterofatree(sometimescalledthewidth)isthenumberofnodesonthelongestpathbetweentwo
leavesinthetree.Thediagrambelowshowstwotreeseachwithdiameternine,theleavesthatformthe
endsofalongestpathareshaded(notethatthereismorethanonepathineachtreeoflengthnine,butno
pathlongerthanninenodes).

ThediameterofatreeTisthelargestofthefollowingquantities:
*thediameterofTsleftsubtree
*thediameterofTsrightsubtree
*thelongestpathbetweenleavesthatgoesthroughtherootofT(thiscanbecomputedfromtheheightsof
thesubtreesofT)
Implementation:
#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;
};

/* function to create a new node of tree and returns pointer */

struct node* newNode(int data);

/* returns max of two integers */


int max(int a, int b);

/* function to Compute height of a tree. */


int height(struct node* node);

/* Function to get diameter of a binary tree */


int diameter(struct node * tree)
{
/* base case where tree is empty */
if (tree == 0)
return 0;

/* get the height of left and right sub-trees */


int lheight = height(tree->left);
int rheight = height(tree->right);

/* get the diameter of left and right sub-trees */


int ldiameter = diameter(tree->left);
int rdiameter = diameter(tree->right);

/* Return max of following three


1) Diameter of left subtree
2) Diameter of right subtree
3) Height of left subtree + height of right subtree + 1 */
return max(lheight + rheight + 1, max(ldiameter, rdiameter));
}

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

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


number f nodes along the longest path from the root node
down to the farthest leaf node.*/
int height(struct node* node)
{

/* base case tree is empty */


if(node == NULL)
return 0;

/* If tree is not empty then height = 1 + max of left


height and right heights */
return 1 + max(height(node->left), height(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);
}

/* returns maximum of two integers */


int max(int a, int b)
{
return (a >= b)? a: b;
}

/* Driver program to test above functions*/


int main()
{

/* Constructed binary tree is


1
/
2
/ \

\
3

4 5
*/
struct node *root = newNode(1);
root->left

= newNode(2);

root->right

= newNode(3);

root->left->left = newNode(4);
root->left->right = newNode(5);

printf("Diameter of the given binary tree is %d\n", diameter(root));

getchar();
return 0;
}
TimeComplexity:O(n^2)

Optimizedimplementation:Theaboveimplementationcanbeoptimizedbycalculatingtheheightinthe
samerecursionratherthancallingaheight()separately.ThankstoAmarforsuggestingthisoptimized
version.ThisoptimizationreducestimecomplexitytoO(n).
/*The second parameter is to store the height of tree.
Initially, we need to pass a pointer to a location with value
as 0. So, function should be used as follows:

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;

/* ldiameter --> diameter of left subtree


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

if(root == NULL)

{
*height = 0;
return 0; /* diameter is also 0 */
}

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


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

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


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

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


}
TimeComplexity:O(n)

================================================================
=======

ConvertanarbitraryBinaryTreeto
atreethatholdsChildrenSum
Property
Question:Givenanarbitrarybinarytree,convertittoabinarytreethatholdsChildrenSumProperty.You
canonlyincrementdatavaluesinanynode(Youcannotchangestructureoftreeandcannotdecrement
valueofanynode).
Forexample,thebelowtreedoesntholdthechildrensumproperty,convertittoatreethatholdsthe
property.

50
/\
/\

72
/\/\
/\/\
35130

Algorithm:
Traversegiventreeinpostordertoconvertit,i.e.,firstchangeleftandrightchildrentoholdthechildrensum
propertythenchangetheparentnode.
Letdifferencebetweennodesdataandchildrensumbediff.

diff=nodeschildrensumnodesdata

Ifdiffis0thennothingneedstobedone.
Ifdiff>0(nodesdataissmallerthannodeschildrensum)incrementthenodesdatabydiff.
Ifdiff<0(nodesdataisgreaterthanthenode'schildrensum)thenincrementonechildsdata.Wecan
choosetoincrementeitherleftorrightchildiftheybotharenotNULL.Letusalwaysfirstincrementtheleft
child.Incrementingachildchangesthesubtreeschildrensumpropertysoweneedtochangeleftsubtree
also.Sowerecursivelyincrementtheleftchild.Ifleftchildisemptythenwerecursivelycallincrement()for
rightchild.
Letusrunthealgorithmforthegivenexample.
Firstconverttheleftsubtree(increment7to8).

50
/\
/\
82
/\/\
/\/\
35130

Thenconverttherightsubtree(increment2to31)

50
/\
/\
831
/\/\
/\/\
35130

Nowconverttheroot,wehavetoincrementleftsubtreeforconvertingtheroot.

50
/\
/\
1931
/\/\
/\/\
145130

Pleasenotethelaststepwehaveincremented8to19,andtofixthesubtreewehaveincremented3to
14.
Implementation:
/* Program to convert an aribitary binary tree to
a tree that holds children sum property */

#include <stdio.h>
#include <stdlib.h>

struct node
{
int data;
struct node* left;
struct node* right;
};

/* This function is used to increment left subtree */


void increment(struct node* node, int diff);

/* Helper function that allocates a new node


with the given data and NULL left and right
pointers. */
struct node* newNode(int data);

/* This function changes a tree to to hold children sum


property */
void convertTree(struct node* node)
{

int left_data = 0, right_data = 0, diff;

/* If tree is empty or it's a leaf node then


return true */
if (node == NULL ||
(node->left == NULL && node->right == NULL))
return;
else
{
/* convert left and right subtrees */
convertTree(node->left);
convertTree(node->right);

/* If left child is not present then 0 is used


as data of left child */
if (node->left != NULL)
left_data = node->left->data;

/* If right child is not present then 0 is used


as data of right child */
if (node->right != NULL)
right_data = node->right->data;

/* get the diff of node's data and children sum */


diff = left_data + right_data - node->data;

/* If node's children sum is greater than the node's data */


if (diff > 0)
node->data = node->data + diff;

/* THIS IS TRICKY --> If node's data is greater than children sum,


then increment subtree by diff */
if (diff < 0)
increment(node, -diff); // -diff is used to make diff positive
}
}

/* This function is used to increment subtree by diff */


void increment(struct node* node, int diff)
{
/* IF left child is not NULL then increment it */
if(node->left != NULL)
{
node->left->data = node->left->data + diff;

// Recursively call to fix the descendants of node->left


increment(node->left, diff);
}
else if (node->right != NULL) // Else increment right child
{
node->right->data = node->right->data + diff;

// Recursively call to fix the descendants of node->right


increment(node->right, diff);
}
}

/* Given a binary tree, printInorder() prints out its


inorder traversal*/
void printInorder(struct node* node)
{
if (node == NULL)
return;

/* first recur on left child */


printInorder(node->left);

/* then print the data of node */


printf("%d ", node->data);

/* now recur on right child */


printInorder(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);
}

/* Driver program to test above functions */


int main()
{
struct node *root = newNode(50);
root->left

= newNode(7);

root->right

= newNode(2);

root->left->left = newNode(3);
root->left->right = newNode(5);
root->right->left = newNode(1);
root->right->right = newNode(30);

printf("\n Inorder traversal before conversion ");


printInorder(root);

convertTree(root);

printf("\n Inorder traversal after conversion ");


printInorder(root);

getchar();
return 0;
}
TimeComplexity:O(n^2),Worstcasecomplexityisforaskewedtreesuchthatnodesareindecreasing
orderfromroottoleaf.

=======================================================================

CheckforChildrenSumPropertyin
aBinaryTree.
Givenabinarytree,writeafunctionthatreturnstrueifthetreesatisfiesbelowproperty.
Foreverynode,datavaluemustbeequaltosumofdatavaluesinleftandrightchildren.Considerdata
valueas0forNULLchildren.Belowtreeisanexample

Algorithm:
Traversethegivenbinarytree.Foreachnodecheck(recursively)ifthenodeandbothitschildrensatisfythe
ChildrenSumProperty,ifsothenreturntrueelsereturnfalse.
Implementation:
/* Program to check children sum property */
#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;
};

/* returns 1 if children sum property holds for the given


node and both of its children*/
int isSumProperty(struct node* node)
{
/* left_data is left child data and right_data is for right child data*/
int left_data = 0, right_data = 0;

/* If node is NULL or it's a leaf node then


return true */
if(node == NULL ||
(node->left == NULL && node->right == NULL))
return 1;
else
{
/* If left child is not present then 0 is used
as data of left child */
if(node->left != NULL)
left_data = node->left->data;

/* If right child is not present then 0 is used


as data of right child */
if(node->right != NULL)
right_data = node->right->data;

/* if the node and both of its children satisfy the


property return 1 else 0*/
if((node->data == left_data + right_data)&&
isSumProperty(node->left) &&
isSumProperty(node->right))
return 1;
else
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);
}

/* Driver program to test above function */


int main()
{
struct node *root = newNode(10);
root->left

= newNode(8);

root->right

= newNode(2);

root->left->left

= newNode(3);

root->left->right = newNode(5);
root->right->right = newNode(2);
if(isSumProperty(root))
printf("The given tree satisfies the children sum property ");
else
printf("The given tree does not satisfy the children sum property ");

getchar();
return 0;
}
TimeComplexity:O(n),wearedoingacompletetraversalofthetree.

=======================================================================

Levelordertraversalinspiralform
Writeafunctiontoprintspiralordertraversalofatree.Forbelowtree,functionshouldprint1,2,3,4,5,6,7.

Method1(Recursive)
Thisproblemcanbeeseenasanextensionofthelevelordertraversalpost.
Toprintthenodesinspiralorder,nodesatdifferentlevelsshouldbeprintedinalternatingorder.An
additionalBooleanvariableltrisusedtochangeprintingorderoflevels.Ifltris1thenprintGivenLevel()
printsnodesfromlefttorightelsefromrighttoleft.Valueofltrisflippedineachiterationtochangethe
order.
Functiontoprintlevelordertraversaloftree

printSpiral(tree)
boolltr=0
ford=1toheight(tree)
printGivenLevel(tree,d,ltr)
ltr~=ltr/*flipltr*/

Functiontoprintallnodesatagivenlevel

printGivenLevel(tree,level,ltr)
iftreeisNULLthenreturn
iflevelis1,then
print(tree>data)
elseiflevelgreaterthan1,then
if(ltr)
printGivenLevel(tree>left,level1,ltr)
printGivenLevel(tree>right,level1,ltr)
else

printGivenLevel(tree>right,level1,ltr)
printGivenLevel(tree>left,level1,ltr)

FollowingisCimplementationofabovealgorithm.
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.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;
};

/* Function protoypes */
void printGivenLevel(struct node* root, int level, int ltr);
int height(struct node* node);
struct node* newNode(int data);

/* Function to print spiral traversal of a tree*/


void printSpiral(struct node* root)
{
int h = height(root);
int i;

/*ltr -> Left to Right. If this variable is set,


then the given level is traverseed from left to right. */
bool ltr = false;
for(i=1; i<=h; i++)
{
printGivenLevel(root, i, ltr);

/*Revert ltr to traverse next level in oppposite order*/


ltr = !ltr;

}
}

/* Print nodes at a given level */


void printGivenLevel(struct node* root, int level, int ltr)
{
if(root == NULL)
return;
if(level == 1)
printf("%d ", root->data);
else if (level > 1)
{
if(ltr)
{
printGivenLevel(root->left, level-1, ltr);
printGivenLevel(root->right, level-1, ltr);
}
else
{
printGivenLevel(root->right, level-1, ltr);
printGivenLevel(root->left, level-1, ltr);
}
}
}

/* 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 */


if (lheight > rheight)
return(lheight+1);
else return(rheight+1);
}
}

/* 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);
}

/* Driver program to test above functions*/


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);
printf("Spiral Order traversal of binary tree is \n");
printSpiral(root);

return 0;
}
Output:

SpiralOrdertraversalofbinarytreeis
1234567
TimeComplexity:WorstcasetimecomplexityoftheabovemethodisO(n^2).Worstcaseoccursincaseof
skewedtrees.

Method2(Iterative)
WecanprintspiralordertraversalinO(n)timeandO(n)extraspace.Theideaistousetwostacks.Wecan
useonestackforprintingfromlefttorightandotherstackforprintingfromrighttoleft.Ineveryiteration,we
havenodesofonelevelinoneofthestacks.Weprintthenodes,andpushnodesofnextlevelinother
stack.
// C++ implementation of a O(n) time method for spiral order traversal
#include <iostream>
#include <stack>
using namespace std;

// Binary Tree node


struct node
{
int data;
struct node *left, *right;
};

void printSpiral(struct node *root)


{
if (root == NULL) return;

// NULL check

// Create two stacks to store alternate levels


stack<struct node*> s1; // For levels to be printed from right to left
stack<struct node*> s2; // For levels to be printed from left to right

// Push first level to first stack 's1'


s1.push(root);

// Keep ptinting while any of the stacks has some nodes


while (!s1.empty() || !s2.empty())
{

// Print nodes of current level from s1 and push nodes of


// next level to s2
while (!s1.empty())
{
struct node *temp = s1.top();
s1.pop();
cout << temp->data << " ";

// Note that is right is pushed before left


if (temp->right)
s2.push(temp->right);
if (temp->left)
s2.push(temp->left);
}

// Print nodes of current level from s2 and push nodes of


// next level to s1
while (!s2.empty())
{
struct node *temp = s2.top();
s2.pop();
cout << temp->data << " ";

// Note that is left is pushed before right


if (temp->left)
s1.push(temp->left);
if (temp->right)
s1.push(temp->right);
}
}
}

// A utility functiont to create a new node


struct node* newNode(int data)
{
struct node* node = new struct node;
node->data = data;

node->left = NULL;
node->right = NULL;

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:

SpiralOrdertraversalofbinarytreeis
1234567

=======================================================================

Aprogramtocheckifabinarytree
isBSTornot
Abinarysearchtree(BST)isanodebasedbinarytreedatastructurewhichhasthefollowingproperties.
Theleftsubtreeofanodecontainsonlynodeswithkeyslessthanthenodeskey.
Therightsubtreeofanodecontainsonlynodeswithkeysgreaterthanthenodeskey.
Boththeleftandrightsubtreesmustalsobebinarysearchtrees.
Fromtheabovepropertiesitnaturallyfollowsthat:
Eachnode(iteminthetree)hasadistinctkey.

METHOD1(SimplebutWrong)
Followingisasimpleprogram.Foreachnode,checkifleftnodeofitissmallerthanthenodeandrightnode
ofitisgreaterthanthenode.
int isBST(struct node* node)
{
if (node == NULL)
return 1;

/* false if left is > than node */


if (node->left != NULL && node->left->data > node->data)
return 0;

/* false if right is < than node */


if (node->right != NULL && node->right->data < node->data)
return 0;

/* false if, recursively, the left or right is not a BST */


if (!isBST(node->left) || !isBST(node->right))
return 0;

/* passing all that, it's a BST */


return 1;
}
Thisapproachiswrongasthiswillreturntrueforbelowbinarytree(andbelowtreeisnotaBST
because4isinleftsubtreeof3)

METHOD2(Correctbutnotefficient)
Foreachnode,checkifmaxvalueinleftsubtreeissmallerthanthenodeandminvalueinrightsubtree
greaterthanthenode.
/* Returns true if a binary tree is a binary search tree */
int isBST(struct node* node)
{
if (node == NULL)
return(true);

/* false if the max of the left is > than us */


if (node->left!=NULL && maxValue(node->left) > node->data)
return(false);

/* false if the min of the right is <= than us */


if (node->right!=NULL && minValue(node->right) < node->data)
return(false);

/* false if, recursively, the left or right is not a BST */


if (!isBST(node->left) || !isBST(node->right))
return(false);

/* passing all that, it's a BST */

return(true);
}
ItisassumedthatyouhavehelperfunctionsminValue()andmaxValue()thatreturntheminormaxintvalue
fromanonemptytree

METHOD3(CorrectandEfficient)
Method2aboverunsslowlysinceittraversesoversomepartsofthetreemanytimes.Abettersolution
looksateachnodeonlyonce.ThetrickistowriteautilityhelperfunctionisBSTUtil(structnode*node,int
min,intmax)thattraversesdownthetreekeepingtrackofthenarrowingminandmaxallowedvaluesasit
goes,lookingateachnodeonlyonce.TheinitialvaluesforminandmaxshouldbeINT_MINandINT_MAX
theynarrowfromthere.

/*Returnstrueifthegiventreeisabinarysearchtree
(efficientversion).*/
intisBST(structnode*node)
{
return(isBSTUtil(node,INT_MIN,INT_MAX))
}

/*ReturnstrueifthegiventreeisaBSTandits
valuesare>=minand<=max.*/
intisBSTUtil(structnode*node,intmin,intmax)

Implementation:
#include <stdio.h>
#include <stdlib.h>
#include <limits.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;
};

int isBSTUtil(struct node* node, int min, int max);

/* Returns true if the given tree is a binary search tree


(efficient version). */
int isBST(struct node* node)
{
return(isBSTUtil(node, INT_MIN, INT_MAX));
}

/* Returns true if the given tree is a BST and its


values are >= min and <= max. */
int isBSTUtil(struct node* node, int min, int max)
{

/* an empty tree is BST */


if (node==NULL)
return 1;

/* false if this node violates the min/max constraint */


if (node->data < min || node->data > max)
return 0;

/* otherwise check the subtrees recursively,


tightening the min or max constraint */
return
isBSTUtil(node->left, min, node->data-1) && // Allow only distinct values
isBSTUtil(node->right, node->data+1, max); // Allow only distinct values
}

/* 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);
}

/* Driver program to test above functions*/


int main()
{
struct node *root = newNode(4);
root->left

= newNode(2);

root->right

= newNode(5);

root->left->left = newNode(1);
root->left->right = newNode(3);

if(isBST(root))
printf("Is BST");
else
printf("Not a BST");

getchar();
return 0;
}
TimeComplexity:O(n)
AuxiliarySpace:O(1)ifFunctionCallStacksizeisnotconsidered,otherwiseO(n)
METHOD4(UsingInOrderTraversal)
ThankstoLJW489forsuggestingthismethod.
1)DoInOrderTraversalofthegiventreeandstoretheresultinatemparray.
3)Checkifthetemparrayissortedinascendingorder,ifitis,thenthetreeisBST.
TimeComplexity:O(n)
WecanavoidtheuseofAuxiliaryArray.WhiledoingInOrdertraversal,wecankeeptrackofpreviously
visitednode.Ifthevalueofthecurrentlyvisitednodeislessthanthepreviousvalue,thentreeisnotBST.
Thankstoygosforthisspaceoptimization.
bool isBST(struct node* root)
{
static struct node *prev = NULL;

// traverse the tree in inorder fashion and keep track of prev node

if (root)
{
if (!isBST(root->left))
return false;

// Allows only distinct valued nodes


if (prev != NULL && root->data <= prev->data)
return false;

prev = root;

return isBST(root->right);
}

return true;
}
Theuseofstaticvariablecanalsobeavoidedbyusingreferencetoprevnodeasaparameter(Similarto
thispost).

=======================================================================

Programtocountleafnodesina
binarytree
AnodeisaleafnodeifbothleftandrightchildnodesofitareNULL.
Hereisanalgorithmtogettheleafnodecount.

getLeafCount(node)
1)IfnodeisNULLthenreturn0.
2)ElseIfleftandrightchildnodesareNULLreturn1.
3)Elserecursivelycalculateleafcountofthetreeusingbelowformula.
Leafcountofatree=Leafcountofleftsubtree+
Leafcountofrightsubtree


ExampleTree

Leafcountfortheabovetreeis3.
Implementation:
#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;
};

/* Function to get the count of leaf nodes in a binary tree*/


unsigned int getLeafCount(struct node* node)
{
if(node == NULL)
return 0;
if(node->left == NULL && node->right==NULL)
return 1;
else
return getLeafCount(node->left)+
getLeafCount(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);
}

/*Driver program to test above functions*/


int main()
{
/*create a tree*/
struct node *root = newNode(1);
root->left

= newNode(2);

root->right

= newNode(3);

root->left->left = newNode(4);
root->left->right = newNode(5);

/*get leaf count of the above created tree*/


printf("Leaf count of the tree is %d", getLeafCount(root));

getchar();
return 0;
}
Time&SpaceComplexities:Sincethisprogramissimilartotraversaloftree,timeandspacecomplexities
willbesameasTreetraversal(PleaseseeourTreeTraversalpostfordetails)

=======================================================================

LevelOrderTreeTraversal
Levelordertraversalofatreeisbreadthfirsttraversalforthetree.

ExampleTree

Levelordertraversaloftheabovetreeis12345
METHOD1(Usefunctiontoprintagivenlevel)
Algorithm:
Therearebasicallytwofunctionsinthismethod.Oneistoprintallnodesatagivenlevel(printGivenLevel),
andotheristoprintlevelordertraversalofthetree(printLevelorder).printLevelordermakesuseof
printGivenLeveltoprintnodesatalllevelsonebyonestartingfromroot.

/*Functiontoprintlevelordertraversaloftree*/
printLevelorder(tree)
ford=1toheight(tree)
printGivenLevel(tree,d)

/*Functiontoprintallnodesatagivenlevel*/
printGivenLevel(tree,level)
iftreeisNULLthenreturn
iflevelis1,then
print(tree>data)
elseiflevelgreaterthan1,then
printGivenLevel(tree>left,level1)
printGivenLevel(tree>right,level1)

Implementation:

#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;
};

/*Function protoypes*/
void printGivenLevel(struct node* root, int level);
int height(struct node* node);
struct node* newNode(int data);

/* Function to print level order traversal a tree*/


void printLevelOrder(struct node* root)
{
int h = height(root);
int i;
for(i=1; i<=h; i++)
printGivenLevel(root, i);
}

/* Print nodes at a given level */


void printGivenLevel(struct node* root, int level)
{
if(root == NULL)
return;
if(level == 1)
printf("%d ", root->data);
else if (level > 1)
{
printGivenLevel(root->left, level-1);
printGivenLevel(root->right, level-1);

}
}

/* 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 */


if (lheight > rheight)
return(lheight+1);
else return(rheight+1);
}
}

/* 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);
}

/* Driver program to test above functions*/

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);

printf("Level Order traversal of binary tree is \n");


printLevelOrder(root);

getchar();
return 0;
}
TimeComplexity:O(n^2)inworstcase.Foraskewedtree,printGivenLevel()takesO(n)timewherenisthe
numberofnodesintheskewedtree.SotimecomplexityofprintLevelOrder()isO(n)+O(n1)+O(n2)+..+
O(1)whichisO(n^2).

METHOD2(UseQueue)
Algorithm:
Foreachnode,firstthenodeisvisitedandthenitschildnodesareputinaFIFOqueue.

printLevelorder(tree)
1)Createanemptyqueueq
2)temp_node=root/*startfromroot*/
3)Loopwhiletemp_nodeisnotNULL
a)printtemp_node>data.
b)Enqueuetemp_nodeschildren(firstleftthenrightchildren)toq
c)Dequeueanodefromqandassignitsvaluetotemp_node

Implementation:
Hereisasimpleimplementationoftheabovealgorithm.Queueisimplementedusinganarraywith
maximumsizeof500.Wecanimplementqueueaslinkedlistalso.
#include <stdio.h>

#include <stdlib.h>
#define MAX_Q_SIZE 500

/* 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;
};

/* frunction prototypes */
struct node** createQueue(int *, int *);
void enQueue(struct node **, int *, struct node *);
struct node *deQueue(struct node **, int *);

/* Given a binary tree, print its nodes in level order


using array for implementing queue */
void printLevelOrder(struct node* root)
{
int rear, front;
struct node **queue = createQueue(&front, &rear);
struct node *temp_node = root;

while(temp_node)
{
printf("%d ", temp_node->data);

/*Enqueue left child */


if(temp_node->left)
enQueue(queue, &rear, temp_node->left);

/*Enqueue right child */


if(temp_node->right)
enQueue(queue, &rear, temp_node->right);

/*Dequeue node and make it temp_node*/


temp_node = deQueue(queue, &front);
}
}

/*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;
}

void enQueue(struct node **queue, int *rear, struct node *new_node)


{
queue[*rear] = new_node;
(*rear)++;
}

struct node *deQueue(struct node **queue, int *front)


{
(*front)++;
return queue[*front - 1];
}

/* 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);
}

/* Driver program to test above functions*/


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);

printf("Level Order traversal of binary tree is \n");


printLevelOrder(root);

getchar();
return 0;
}
TimeComplexity:O(n)wherenisnumberofnodesinthebinarytree

================================================================
=======

Findthenodewithminimumvalue
inaBinarySearchTree
Thisisquitesimple.JusttraversethenodefromroottoleftrecursivelyuntilleftisNULL.Thenodewhose
leftisNULListhenodewithminimumvalue.


Fortheabovetree,westartwith20,thenwemoveleft8,wekeeponmovingtoleftuntilweseeNULL.
Sinceleftof4isNULL,4isthenodewithminimumvalue.
#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;
};

/* 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);
}

/* 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
{
/* 2. Otherwise, recur down the tree */
if (data <= node->data)
node->left = insert(node->left, data);
else
node->right = insert(node->right, data);

/* return the (unchanged) node pointer */


return node;
}
}

/* Given a non-empty binary search tree,


return the minimum data value found in that
tree. Note that the entire tree does not need
to be searched. */
int minValue(struct node* node) {
struct node* current = node;

/* loop down to find the leftmost leaf */

while (current->left != NULL) {


current = current->left;
}
return(current->data);
}

/* Driver program to test sameTree function*/


int main()
{
struct node* root = NULL;
root = insert(root, 4);
insert(root, 2);
insert(root, 1);
insert(root, 3);
insert(root, 6);
insert(root, 5);

printf("\n Minimum value in BST is %d", minValue(root));


getchar();
return 0;
}
TimeComplexity:O(n)Worstcasehappensforleftskewedtrees.
Similarlywecangetthemaximumvaluebyrecursivelytraversingtherightnodeofabinarysearchtree.

=======================================================================

TheGreatTreeListRecursion
Problem.
Question:
WritearecursivefunctiontreeToList(Noderoot)thattakesanorderedbinarytreeandrearrangesthe
internalpointerstomakeacirculardoublylinkedlistoutofthetreenodes.Thepreviouspointersshouldbe
storedinthesmallfieldandthenextpointersshouldbestoredinthelargefield.Thelistshouldbe
arrangedsothatthenodesareinincreasingorder.Returntheheadpointertothenewlist.

Thisisverywellexplainedandimplementedathttp://cslibrary.stanford.edu/109/TreeListRecursion.html

=======================================================================

LowestCommonAncestorinaBinarySearchTree

GivenvaluesoftwonodesinaBinarySearchTree,writeacprogramtofindtheLowestCommonAncestor
(LCA).Youmayassumethatboththevaluesexistinthetree.
Thefunctionprototypeshouldbeasfollows:

structnode*lca(node*root,intn1,intn2)
n1andn2aretwogivenvaluesinthetreewithgivenroot.

Forexample,considertheBSTindiagram,LCAof10and14is12andLCAof8and14is8.
FollowingisdefinitionofLCAfromWikipedia:
LetTbearootedtree.Thelowestcommonancestorbetweentwonodesn1andn2isdefinedasthelowest
nodeinTthathasbothn1andn2asdescendants(whereweallowanodetobeadescendantofitself).
TheLCAofn1andn2inTisthesharedancestorofn1andn2thatislocatedfarthestfromtheroot.
Computationoflowestcommonancestorsmaybeuseful,forinstance,aspartofaprocedurefor
determiningthedistancebetweenpairsofnodesinatree:thedistancefromn1ton2canbecomputedas
thedistancefromtherootton1,plusthedistancefromtherootton2,minustwicethedistancefromtheroot
totheirlowestcommonancestor.(SourceWiki)
Solutions:
IfwearegivenaBSTwhereeverynodehasparentpointer,thenLCAcanbeeasilydeterminedby
traversingupusingparentpointerandprintingthefirstintersectingnode.
WecansolvethisproblemusingBSTproperties.WecanrecursivelytraversetheBSTfromroot.Themain
ideaofthesolutionis,whiletraversingfromtoptobottom,thefirstnodenweencounterwithvaluebetween
n1andn2,i.e.,n1<n<n2orsameasoneofthen1orn2,isLCAofn1andn2(assumingthatn1<n2).So

justrecursivelytraversetheBSTin,ifnode'svalueisgreaterthanbothn1andn2thenourLCAliesinleft
sideofthenode,ifit'sissmallerthanbothn1andn2,thenLCAliesonrightside.OtherwiserootisLCA
(assumingthatbothn1andn2arepresentinBST)
// A recursive C program to find LCA of two nodes n1 and n2.
#include <stdio.h>
#include <stdlib.h>

struct node
{
int data;
struct node* left, *right;
};

/* 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)
{
if (root == NULL) return NULL;

// If both n1 and n2 are smaller than root, then LCA lies in left
if (root->data > n1 && root->data > n2)
return lca(root->left, n1, n2);

// If both n1 and n2 are greater than root, then LCA lies in right
if (root->data < n1 && root->data < n2)
return lca(root->right, n1, n2);

return root;
}

/* Helper function that allocates a new node with the 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);

/* Driver program to test mirror() */


int main()
{
// Let us construct the BST shown in the above figure
struct node *root

= newNode(20);

root->left

= newNode(8);

root->right

= newNode(22);

root->left->left

= newNode(4);

root->left->right

= newNode(12);

root->left->right->left = newNode(10);
root->left->right->right = newNode(14);

int n1 = 10, n2 = 14;


struct node *t = lca(root, n1, n2);
printf("LCA of %d and %d is %d \n", n1, n2, t->data);

n1 = 14, n2 = 8;
t = lca(root, n1, n2);
printf("LCA of %d and %d is %d \n", n1, n2, t->data);

n1 = 10, n2 = 22;
t = lca(root, n1, n2);
printf("LCA of %d and %d is %d \n", n1, n2, t->data);

getchar();
return 0;
}
Output:

LCAof10and14is12
LCAof14and8is8
LCAof10and22is20

TimecomplexityofabovesolutionisO(h)wherehisheightoftree.Also,theabovesolutionrequiresO(h)
extraspaceinfunctioncallstackforrecursivefunctioncalls.Wecanavoidextraspaceusingiterative
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;
}
Seethisforcompleteprogram.
YoumayliketoseeLowestCommonAncestorinaBinaryTreealso.
Exercise
Theabovefunctionsassumethatn1andn2bothareinBST.Ifn1andn2arenotpresent,thentheymay
returnincorrectresult.ExtendtheabovesolutionstoreturnNULLifn1orn2orbothnotpresentinBST.

=======================================================================

Givenabinarytree,printoutallof
itsroottoleafpathsoneperline.
Hereisthesolution.

Algorithm:

initialize:pathlen=0,path[1000]
/*1000issomemaxlimitforpaths,itcanchange*/

/*printPathsRecurtraversesnodesoftreeinpreorder*/
printPathsRecur(tree,path[],pathlen)
1)IfnodeisnotNULLthen
a)pushdatatopatharray:
path[pathlen]=node>data.
b)incrementpathlen
pathlen++
2)Ifnodeisaleafnodethenprintthepatharray.
3)Else
a)CallprintPathsRecurforleftsubtree
printPathsRecur(node>left,path,pathLen)
b)CallprintPathsRecurforrightsubtree.
printPathsRecur(node>right,path,pathLen)

Example:

ExampleTree

Outputfortheaboveexamplewillbe

124
125
13

Implementation:
/*program to print all of its root-to-leaf paths 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;
struct node* right;
};

void printArray(int [], int);


void printPathsRecur(struct node*, int [], int);
struct node* newNode(int );
void printPaths(struct node*);

/* Given a binary tree, print out all of its root-to-leaf


paths, one per line. Uses a recursive helper to do the work.*/
void printPaths(struct node* node)
{
int path[1000];
printPathsRecur(node, path, 0);
}

/* Recursive helper function -- given a node, and an array containing


the path from the root node up to but not including this node,
print out all the root-leaf paths. */
void printPathsRecur(struct node* node, int path[], int pathLen)
{
if (node==NULL) return;

/* append this node to the path array */


path[pathLen] = node->data;
pathLen++;

/* it's a leaf, so print the path that led to here */


if (node->left==NULL && node->right==NULL)
{
printArray(path, pathLen);

}
else
{
/* otherwise try both subtrees */
printPathsRecur(node->left, path, pathLen);
printPathsRecur(node->right, path, pathLen);
}
}

/* 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);
}

/* 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");
}

/* Driver program to test mirror() */


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);

/* Print all root-to-leaf paths of the input tree */


printPaths(root);

getchar();
return 0;
}

=======================================================================

Ifyouaregiventwotraversal
sequences,canyouconstructthe
binarytree?
Itdependsonwhattraversalsaregiven.IfoneofthetraversalmethodsisInorderthenthetreecanbe
constructed,otherwisenot.

Therefore,followingcombinationcanuniquelyidentifyatree.
InorderandPreorder.

InorderandPostorder.
InorderandLevelorder.

Andfollowingdonot.
PostorderandPreorder.
PreorderandLevelorder.
PostorderandLevelorder.
Forexample,Preorder,LevelorderandPostordertraversalsaresameforthetreesgiveninabovediagram.
PreorderTraversal=AB
PostorderTraversal=BA
LevelOrderTraversal=AB
So,evenifthreeofthem(Pre,PostandLevel)aregiven,thetreecannotbeconstructed.

=======================================================================

WriteanEfficientCFunctionto
ConvertaBinaryTreeintoits
MirrorTree
MirrorofaTree:MirrorofaBinaryTreeTisanotherBinaryTreeM(T)withleftandrightchildrenofall
nonleafnodesinterchanged.

Treesinthebelowfigurearemirrorofeachother

AlgorithmMirror(tree):

(1)CallMirrorforleftsubtreei.e.,Mirror(leftsubtree)
(2)CallMirrorforrightsubtreei.e.,Mirror(leftsubtree)
(3)Swapleftandrightsubtrees.
temp=leftsubtree
leftsubtree=rightsubtree
rightsubtree=temp

Program:
#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;
};

/* 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);
}

/* Change a tree so that the roles of the left and


right pointers are swapped at every node.

So the tree...
4
/\
2

/\
1

is changed to...
4
/\
5

2
/\
3

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

/* do the subtrees */
mirror(node->left);
mirror(node->right);

/* swap the pointers in this node */


temp

= node->left;

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

/* Helper function to test mirror(). Given a binary


search tree, print out its data elements in
increasing sorted order.*/
void inOrder(struct node* node)
{
if (node == NULL)
return;

inOrder(node->left);
printf("%d ", node->data);

inOrder(node->right);
}

/* Driver program to test mirror() */


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);

/* Print inorder traversal of the input tree */


printf("\n Inorder traversal of the constructed tree is \n");
inOrder(root);

/* Convert tree to its mirror */


mirror(root);

/* Print inorder traversal of the mirror tree */


printf("\n Inorder traversal of the mirror tree is \n");
inOrder(root);

getchar();

return 0;
}
Time&SpaceComplexities:Thisprogramissimilartotraversaloftreespaceandtimecomplexitieswillbe
sameasTreetraversal(PleaseseeourTreeTraversalpostfordetails)

=======================================================================

WriteaCprogramtoDeleteaTree.
Todeleteatreewemusttraverseallthenodesofthetreeanddeletethemonebyone.Sowhichtraversal
weshoulduseInorderorPreorderorPostorder.AnswerissimplePostorder,becausebeforedeleting
theparentnodeweshoulddeleteitschildrennodesfirst
Wecandeletetreewithothertraversalsalsowithextraspacecomplexitybutwhyshouldwegoforother
traversalsifwehavePostorderavailablewhichdoestheworkwithoutstoringanythinginsametime
complexity.
Forthefollowingtreenodesaredeletedinorder4,5,2,3,1

ExampleTree

Program
#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;
};

/* 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);
}

/* This function traverses tree in post order to


to delete each and every node of the tree */
void deleteTree(struct node* node)
{
if (node == NULL) return;

/* first delete both subtrees */


deleteTree(node->left);
deleteTree(node->right);

/* then delete the node */


printf("\n Deleting node: %d", node->data);
free(node);
}

/* Driver program to test deleteTree function*/


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);

deleteTree(root);
root = NULL;

printf("\n Tree deleted ");

getchar();
return 0;
}
TheabovedeleteTree()functiondeletesthetree,butdoesntchangeroottoNULLwhichmaycause
problemsiftheuserofdeleteTree()doesntchangeroottoNULLandtirestoaccessvaluesusingroot
pointer.WecanmodifythedeleteTree()functiontotakereferencetotherootnodesothatthisproblem
doesntoccur.Seethefollowingcode.
#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;
};

/* 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);
}

/* This function is same as deleteTree() in the previous program */


void _deleteTree(struct node* node)
{
if (node == NULL) return;

/* first delete both subtrees */


_deleteTree(node->left);
_deleteTree(node->right);

/* then delete the node */


printf("\n Deleting node: %d", node->data);
free(node);
}

/* Deletes a tree and sets the root as NULL */


void deleteTree(struct node** node_ref)
{
_deleteTree(*node_ref);
*node_ref = NULL;
}

/* Driver program to test deleteTree function*/


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);

// Note that we pass the address of root here

deleteTree(&root);
printf("\n Tree deleted ");

getchar();
return 0;
}
TimeComplexity:O(n)
SpaceComplexity:IfwedontconsidersizeofstackforfunctioncallsthenO(1)otherwiseO(n)

=======================================================================

WriteaCProgramtoFindthe
MaximumDepthorHeightofaTree
Maximumdepthorheightofthebelowtreeis3.

ExampleTree

Recursivelycalculateheightofleftandrightsubtreesofanodeandassignheighttothenodeasmaxofthe
heightsoftwochildrenplus1.Seebelowpseudocodeandprogramfordetails.
Algorithm:

maxDepth()
1.Iftreeisemptythenreturn0
2.Else

(a)Getthemaxdepthofleftsubtreerecursivelyi.e.,
callmaxDepth(tree>leftsubtree)
(a)Getthemaxdepthofrightsubtreerecursivelyi.e.,
callmaxDepth(tree>rightsubtree)
(c)Getthemaxofmaxdepthsofleftandright
subtreesandadd1toitforthecurrentnode.
max_depth=max(maxdeptofleftsubtree,
maxdepthofrightsubtree)
+1
(d)Returnmax_depth

SeethebelowdiagramformoreclarityaboutexecutionoftherecursivefunctionmaxDepth()for
aboveexampletree.

maxDepth('1')=max(maxDepth('2'),maxDepth('3'))+1
=2+1
/\
/\
/\
/\
/\
maxDepth('1')maxDepth('3')=1
=max(maxDepth('4'),maxDepth('5'))+1
=1+1=2

/\
/\
/\
/\
/\
maxDepth('4')=1maxDepth('5')=1

Implementation:
#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;
};

/* Compute the "maxDepth" of a tree -- the number of


nodes along the longest path from the root node
down to the farthest leaf node.*/
int maxDepth(struct node* node)
{
if (node==NULL)
return 0;
else
{
/* compute the depth of each subtree */
int lDepth = maxDepth(node->left);
int rDepth = maxDepth(node->right);

/* use the larger one */


if (lDepth > rDepth)
return(lDepth+1);
else return(rDepth+1);
}
}

/* 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);
}

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);

printf("Hight of tree is %d", maxDepth(root));

getchar();
return 0;
}
TimeComplexity:O(n)(PleaseseeourpostTreeTraversalfordetails)

=======================================================================

WriteCCodetoDetermineifTwo
TreesareIdentical
Twotreesareidenticalwhentheyhavesamedataandarrangementofdataisalsosame.
Toidentifyiftwotreesareidentical,weneedtotraversebothtreessimultaneously,andwhiletraversingwe
needtocomparedataandchildrenofthetrees.
Algorithm:

sameTree(tree1,tree2)
1.Ifbothtreesareemptythenreturn1.
2.ElseIfbothtreesarenonempty
(a)Checkdataoftherootnodes(tree1>data==tree2>data)
(b)Checkleftsubtreesrecursivelyi.e.,callsameTree(
tree1>left_subtree,tree2>left_subtree)

(c)Checkrightsubtreesrecursivelyi.e.,callsameTree(
tree1>right_subtree,tree2>right_subtree)
(d)Ifa,bandcaretruethenreturn1.
3Elsereturn0(oneisemptyandotherisnot)

#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;
};

/* 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);
}

/* Given two trees, return true if they are


structurally identical */
int identicalTrees(struct node* a, struct node* b)
{
/*1. both empty */
if (a==NULL && b==NULL)
return 1;

/* 2. both non-empty -> compare them */


if (a!=NULL && b!=NULL)
{
return
(
a->data == b->data &&
identicalTrees(a->left, b->left) &&
identicalTrees(a->right, b->right)
);
}

/* 3. one empty, one not -> false */


return 0;
}

/* Driver program to test identicalTrees function*/


int main()
{
struct node *root1 = newNode(1);
struct node *root2 = newNode(1);
root1->left = newNode(2);
root1->right = newNode(3);
root1->left->left = newNode(4);
root1->left->right = newNode(5);

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;
}
TimeComplexity:
ComplexityoftheidenticalTree()willbeaccordingtothetreewithlessernumberofnodes.Letnumberof
nodesintwotreesbemandnthencomplexityofsameTree()isO(m)wherem<n.

=======================================================================

WriteaCprogramtoCalculateSize
ofatree
Sizeofatreeisthenumberofelementspresentinthetree.Sizeofthebelowtreeis5.

ExampleTree

Size()functionrecursivelycalculatesthesizeofatree.Itworksasfollows:
Sizeofatree=Sizeofleftsubtree+1+Sizeofrightsubtree
Algorithm:

size(tree)
1.Iftreeisemptythenreturn0
2.Else
(a)Getthesizeofleftsubtreerecursivelyi.e.,call
size(tree>leftsubtree)
(a)Getthesizeofrightsubtreerecursivelyi.e.,call
size(tree>rightsubtree)
(c)Calculatesizeofthetreeasfollowing:

tree_size=size(leftsubtree)+size(right
subtree)+1
(d)Returntree_size

#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;
};

/* 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);
}

/* Computes the number of nodes in a tree. */


int size(struct node* node)
{
if (node==NULL)
return 0;
else
return(size(node->left) + 1 + size(node->right));
}

/* Driver program to test size function*/


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);

printf("Size of the tree is %d", size(root));


getchar();
return 0;
}
Time&SpaceComplexities:Sincethisprogramissimilartotraversaloftree,timeandspacecomplexities
willbesameasTreetraversal(PleaseseeourTreeTraversalpostfordetails)

=======================================================================

TreeTraversals
Unlikelineardatastructures(Array,LinkedList,Queues,Stacks,etc)whichhaveonlyonelogicalwayto
traversethem,treescanbetraversedindifferentways.Followingarethegenerallyusedwaysfortraversing
trees.

ExampleTree

DepthFirstTraversals:
(a)Inorder
(b)Preorder
(c)Postorder
BreadthFirstorLevelOrderTraversal
PleaseseethispostforBreadthFirstTraversal.
InorderTraversal:

AlgorithmInorder(tree)
1.Traversetheleftsubtree,i.e.,callInorder(leftsubtree)
2.Visittheroot.
3.Traversetherightsubtree,i.e.,callInorder(rightsubtree)

UsesofInorder
Incaseofbinarysearchtrees(BST),Inordertraversalgivesnodesinnondecreasingorder.Togetnodesof
BSTinnonincreasingorder,avariationofInordertraversalwhereInorderitraversalsreversed,canbe
used.
Example:Inordertraversalfortheabovegivenfigureis42513.

PreorderTraversal:

AlgorithmPreorder(tree)
1.Visittheroot.
2.Traversetheleftsubtree,i.e.,callPreorder(leftsubtree)
3.Traversetherightsubtree,i.e.,callPreorder(rightsubtree)

UsesofPreorder
Preordertraversalisusedtocreateacopyofthetree.Preordertraversalisalsousedtogetprefix
expressiononofanexpressiontree.Pleaseseehttp://en.wikipedia.org/wiki/Polish_notationtoknowwhy
prefixexpressionsareuseful.
Example:Preordertraversalfortheabovegivenfigureis12453.

PostorderTraversal:

AlgorithmPostorder(tree)
1.Traversetheleftsubtree,i.e.,callPostorder(leftsubtree)
2.Traversetherightsubtree,i.e.,callPostorder(rightsubtree)
3.Visittheroot.

UsesofPostorder

Postordertraversalisusedtodeletethetree.Pleaseseethequestionfordeletionoftreefordetails.
Postordertraversalisalsousefultogetthepostfixexpressionofanexpressiontree.Pleasesee
http://en.wikipedia.org/wiki/Reverse_Polish_notationtofortheusageofpostfixexpression.
Example:Postordertraversalfortheabovegivenfigureis45231.
#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;
};

/* 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);
}

/* Given a binary tree, print its nodes according to the


"bottom-up" postorder traversal. */
void printPostorder(struct node* node)
{
if (node == NULL)
return;

// first recur on left subtree

printPostorder(node->left);

// then recur on right subtree


printPostorder(node->right);

// now deal with the node


printf("%d ", node->data);
}

/* Given a binary tree, print its nodes in inorder*/


void printInorder(struct node* node)
{
if (node == NULL)
return;

/* first recur on left child */


printInorder(node->left);

/* then print the data of node */


printf("%d ", node->data);

/* now recur on right child */


printInorder(node->right);
}

/* Given a binary tree, print its nodes in inorder*/


void printPreorder(struct node* node)
{
if (node == NULL)
return;

/* first print data of node */


printf("%d ", node->data);

/* then recur on left sutree */


printPreorder(node->left);

/* now recur on right subtree */


printPreorder(node->right);
}

/* Driver program to test above functions*/


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);

printf("\n Preorder traversal of binary tree is \n");


printPreorder(root);

printf("\n Inorder traversal of binary tree is \n");


printInorder(root);

printf("\n Postorder traversal of binary tree is \n");


printPostorder(root);

getchar();
return 0;
}
TimeComplexity:O(n)
Letusproveit:
ComplexityfunctionT(n)forallproblemwheretreetraversalisinvolvedcanbedefinedas:
T(n)=T(k)+T(nk1)+c
Wherekisthenumberofnodesononesideofrootandnk1ontheotherside.
Letsdoanalysisofboundaryconditions
Case1:Skewedtree(Oneofthesubtreesisemptyandothersubtreeisnonempty)
kis0inthiscase.
T(n)=T(0)+T(n1)+c
T(n)=2T(0)+T(n2)+2c
T(n)=3T(0)+T(n3)+3c

T(n)=4T(0)+T(n4)+4c

.
T(n)=(n1)T(0)+T(1)+(n1)c
T(n)=nT(0)+(n)c
ValueofT(0)willbesomeconstantsayd.(traversingaemptytreewilltakesomeconstantstime)
T(n)=n(c+d)
T(n)=()(n)(Thetaofn)
Case2:Bothleftandrightsubtreeshaveequalnumberofnodes.
T(n)=2T(|_n/2_|)+c
Thisrecursivefunctionisinthestandardform(T(n)=aT(n/b)+()(n))formaster
methodhttp://en.wikipedia.org/wiki/Master_theorem.Ifwesolveitbymastermethodweget()(n)
AuxiliarySpace:IfwedontconsidersizeofstackforfunctioncallsthenO(1)otherwiseO(n).

=======================================================================

InorderSuccessorinBinarySearch
Tree
InBinaryTree,InordersuccessorofanodeisthenextnodeinInordertraversaloftheBinaryTree.Inorder
SuccessorisNULLforthelastnodeinInoordertraversal.
InBinarySearchTree,InorderSuccessorofaninputnodecanalsobedefinedasthenodewiththesmallest
keygreaterthanthekeyofinputnode.So,itissometimesimportanttofindnextnodeinsortedorder.


Intheabovediagram,inordersuccessorof8is10,inordersuccessorof10is12andinordersuccessorof
14is20.
Method1(UsesParentPointer)
Inthismethod,weassumethateverynodehasparentpointer.
TheAlgorithmisdividedintotwocasesonthebasisofrightsubtreeoftheinputnodebeingemptyornot.
Input:node,root//nodeisthenodewhoseInordersuccessorisneeded.
output:succ//succisInordersuccessorofnode.
1)IfrightsubtreeofnodeisnotNULL,thensuccliesinrightsubtree.Dofollowing.
Gotorightsubtreeandreturnthenodewithminimumkeyvalueinrightsubtree.
2)IfrightsbtreeofnodeisNULL,thensuccisoneoftheancestors.Dofollowing.
Travelupusingtheparentpointeruntilyouseeanodewhichisleftchildofitsparent.Theparentofsucha
nodeisthesucc.
Implementation
NotethatthefunctiontofindInOrderSuccessorishighlighted(withgraybackground)inbelowcode.
#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;

struct node* parent;


};

struct node * minValue(struct node* node);

struct node * inOrderSuccessor(struct node *root, struct node *n)


{
// step 1 of the above algorithm
if( n->right != NULL )
return minValue(n->right);

// step 2 of the above algorithm


struct node *p = n->parent;
while(p != NULL && n == p->right)
{
n = p;
p = p->parent;
}
return p;
}

/* Given a non-empty binary search tree, return the minimum data


value found in that tree. Note that the entire tree does not need
to be searched. */
struct node * minValue(struct node* node) {
struct node* current = node;

/* loop down to find the leftmost leaf */


while (current->left != NULL) {
current = current->left;
}
return current;
}

/* 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;

/* 2. Otherwise, recur down the tree */


if (data <= node->data)
{
temp = insert(node->left, data);
node->left = temp;
temp->parent= node;
}
else
{
temp = insert(node->right, data);
node->right = temp;
temp->parent = node;

/* return the (unchanged) node pointer */


return node;
}
}

/* Driver program to test above functions*/


int main()
{
struct node* root = NULL, *temp, *succ, *min;

//creating the tree given in the above diagram


root = insert(root, 20);
root = insert(root, 8);
root = insert(root, 22);
root = insert(root, 4);
root = insert(root, 12);
root = insert(root, 10);
root = insert(root, 14);
temp = root->left->right->right;

succ = inOrderSuccessor(root, temp);


if(succ != NULL)
printf("\n Inorder Successor of %d is %d ", temp->data, succ->data);
else
printf("\n Inorder Successor doesn't exit");

getchar();
return 0;
}
Outputoftheaboveprogram:
InorderSuccessorof14is20
TimeComplexity:O(h)wherehisheightoftree.

Method2(Searchfromroot)

ParentpointerisNOTneededinthisalgorithm.TheAlgorithmisdividedintotwocasesonthebasisofright
subtreeoftheinputnodebeingemptyornot.
Input:node,root//nodeisthenodewhoseInordersuccessorisneeded.
output:succ//succisInordersuccessorofnode.
1)IfrightsubtreeofnodeisnotNULL,thensuccliesinrightsubtree.Dofollowing.
Gotorightsubtreeandreturnthenodewithminimumkeyvalueinrightsubtree.
2)IfrightsbtreeofnodeisNULL,thenstartfromrootandussearchliketechnique.Dofollowing.
Traveldownthetree,ifanodesdataisgreaterthanrootsdatathengorightside,otherwisegotoleftside.
struct node * inOrderSuccessor(struct node *root, struct node *n)
{
// step 1 of the above algorithm
if( n->right != NULL )
return minValue(n->right);

struct node *succ = NULL;

// 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;
}

TimeComplexity:O(h)wherehisheightoftree.

=======================================================================

BinaryTreetoBinarySearchTree
Conversion
GivenaBinaryTree,convertittoaBinarySearchTree.Theconversionmustbedoneinsuchawaythat
keepstheoriginalstructureofBinaryTree.
Examples.

Example1
Input:
10
/\
27
/\
84
Output:
8
/\
410
/\
27

Example2
Input:
10
/\
3015
/\
205
Output:
15
/\
1020
/\
530

Solution
Followingisa3stepsolutionforconvertingBinarytreetoBinarySearchTree.
1)Createatemparrayarr[]thatstoresinordertraversalofthetree.ThissteptakesO(n)time.
2)Sortthetemparrayarr[].Timecomplexityofthisstepdependsuponthesortingalgorithm.Inthefollowing
implementation,QuickSortisusedwhichtakes(n^2)time.ThiscanbedoneinO(nLogn)timeusingHeap
SortorMergeSort.
3)Againdoinordertraversaloftreeandcopyarrayelementstotreenodesonebyone.ThissteptakesO(n)
time.
FollowingisCimplementationoftheaboveapproach.Themainfunctiontoconvertishighlightedinthe
followingcode.
/* A program to convert Binary Tree to Binary Search Tree */
#include<stdio.h>
#include<stdlib.h>

/* A binary tree node structure */


struct node
{
int data;
struct node *left;
struct node *right;
};

/* A helper function that stores inorder traversal of a tree rooted


with node */
void storeInorder (struct node* node, int inorder[], int *index_ptr)
{
// Base Case
if (node == NULL)
return;

/* first store the left subtree */


storeInorder (node->left, inorder, index_ptr);

/* Copy the root's data */


inorder[*index_ptr] = node->data;
(*index_ptr)++; // increase index for next entry

/* finally store the right subtree */


storeInorder (node->right, inorder, index_ptr);
}

/* A helper function to count nodes in a Binary Tree */


int countNodes (struct node* root)
{
if (root == NULL)
return 0;
return countNodes (root->left) +
countNodes (root->right) + 1;
}

// Following function is needed for library function qsort()


int compare (const void * a, const void * b)
{
return ( *(int*)a - *(int*)b );
}

/* A helper function that copies contents of arr[] to Binary Tree.


This functon basically does Inorder traversal of Binary Tree and
one by one copy arr[] elements to Binary Tree nodes */
void arrayToBST (int *arr, struct node* root, int *index_ptr)
{
// Base Case
if (root == NULL)
return;

/* first update the left subtree */


arrayToBST (arr, root->left, index_ptr);

/* Now update root's data and increment index */


root->data = arr[*index_ptr];
(*index_ptr)++;

/* finally update the right subtree */


arrayToBST (arr, root->right, index_ptr);

// This function converts a given Binary Tree to BST


void binaryTreeToBST (struct node *root)
{
// base case: tree is empty
if(root == NULL)
return;

/* Count the number of nodes in Binary Tree so that


we know the size of temporary array to be created */
int n = countNodes (root);

// 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);

// Sort the array using library function for quick sort


qsort (arr, n, sizeof(arr[0]), compare);

// Copy array elements back to Binary Tree


i = 0;
arrayToBST (arr, root, &i);

// delete dynamically allocated memory to avoid meory leak


delete [] arr;
}

/* Utility function to create a new Binary Tree node */


struct node* newNode (int data)
{
struct node *temp = new struct node;
temp->data = data;
temp->left = NULL;
temp->right = NULL;
return temp;

/* Utility function to print inorder traversal of Binary Tree */


void printInorder (struct node* node)
{
if (node == NULL)
return;

/* first recur on left child */


printInorder (node->left);

/* then print the data of node */


printf("%d ", node->data);

/* now recur on right child */


printInorder (node->right);
}

/* Driver function to test above functions */


int main()
{
struct node *root = NULL;

/* Constructing tree given in the above figure


10
/ \
30

15

20

*/

root = newNode(10);
root->left = newNode(30);
root->right = newNode(15);
root->left->left = newNode(20);
root->right->right = newNode(5);

// convert Binary Tree to BST


binaryTreeToBST (root);

printf("Following is Inorder Traversal of the converted BST: \n");


printInorder (root);

return 0;
}
Output:

FollowingisInorderTraversaloftheconvertedBST:
510152030
WewillbecoveringanothermethodforthisproblemwhichconvertsthetreeusingO(heightoftree)extra
space.

=======================================================================

Aprogramtocheckifabinarytree
isBSTornot
Abinarysearchtree(BST)isanodebasedbinarytreedatastructurewhichhasthefollowingproperties.
Theleftsubtreeofanodecontainsonlynodeswithkeyslessthanthenodeskey.
Therightsubtreeofanodecontainsonlynodeswithkeysgreaterthanthenodeskey.
Boththeleftandrightsubtreesmustalsobebinarysearchtrees.
Fromtheabovepropertiesitnaturallyfollowsthat:
Eachnode(iteminthetree)hasadistinctkey.

METHOD1(SimplebutWrong)
Followingisasimpleprogram.Foreachnode,checkifleftnodeofitissmallerthanthenodeandrightnode
ofitisgreaterthanthenode.
int isBST(struct node* node)
{
if (node == NULL)
return 1;

/* false if left is > than node */


if (node->left != NULL && node->left->data > node->data)
return 0;

/* false if right is < than node */


if (node->right != NULL && node->right->data < node->data)
return 0;

/* false if, recursively, the left or right is not a BST */


if (!isBST(node->left) || !isBST(node->right))
return 0;

/* passing all that, it's a BST */


return 1;
}
Thisapproachiswrongasthiswillreturntrueforbelowbinarytree(andbelowtreeisnotaBST
because4isinleftsubtreeof3)

METHOD2(Correctbutnotefficient)
Foreachnode,checkifmaxvalueinleftsubtreeissmallerthanthenodeandminvalueinrightsubtree
greaterthanthenode.
/* Returns true if a binary tree is a binary search tree */
int isBST(struct node* node)
{
if (node == NULL)
return(true);

/* false if the max of the left is > than us */


if (node->left!=NULL && maxValue(node->left) > node->data)
return(false);

/* false if the min of the right is <= than us */


if (node->right!=NULL && minValue(node->right) < node->data)
return(false);

/* false if, recursively, the left or right is not a BST */


if (!isBST(node->left) || !isBST(node->right))
return(false);

/* passing all that, it's a BST */


return(true);
}
ItisassumedthatyouhavehelperfunctionsminValue()andmaxValue()thatreturntheminormaxintvalue
fromanonemptytree

METHOD3(CorrectandEfficient)
Method2aboverunsslowlysinceittraversesoversomepartsofthetreemanytimes.Abettersolution
looksateachnodeonlyonce.ThetrickistowriteautilityhelperfunctionisBSTUtil(structnode*node,int
min,intmax)thattraversesdownthetreekeepingtrackofthenarrowingminandmaxallowedvaluesasit
goes,lookingateachnodeonlyonce.TheinitialvaluesforminandmaxshouldbeINT_MINandINT_MAX
theynarrowfromthere.

/*Returnstrueifthegiventreeisabinarysearchtree
(efficientversion).*/
intisBST(structnode*node)
{
return(isBSTUtil(node,INT_MIN,INT_MAX))
}

/*ReturnstrueifthegiventreeisaBSTandits
valuesare>=minand<=max.*/
intisBSTUtil(structnode*node,intmin,intmax)

Implementation:
#include <stdio.h>
#include <stdlib.h>
#include <limits.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;
};

int isBSTUtil(struct node* node, int min, int max);

/* Returns true if the given tree is a binary search tree


(efficient version). */
int isBST(struct node* node)
{
return(isBSTUtil(node, INT_MIN, INT_MAX));
}

/* Returns true if the given tree is a BST and its


values are >= min and <= max. */
int isBSTUtil(struct node* node, int min, int max)

/* an empty tree is BST */


if (node==NULL)
return 1;

/* false if this node violates the min/max constraint */


if (node->data < min || node->data > max)
return 0;

/* otherwise check the subtrees recursively,


tightening the min or max constraint */
return
isBSTUtil(node->left, min, node->data-1) && // Allow only distinct values
isBSTUtil(node->right, node->data+1, max); // Allow only distinct values
}

/* 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);
}

/* Driver program to test above functions*/


int main()
{
struct node *root = newNode(4);
root->left

= newNode(2);

root->right

= newNode(5);

root->left->left = newNode(1);

root->left->right = newNode(3);

if(isBST(root))
printf("Is BST");
else
printf("Not a BST");

getchar();
return 0;
}
TimeComplexity:O(n)
AuxiliarySpace:O(1)ifFunctionCallStacksizeisnotconsidered,otherwiseO(n)
METHOD4(UsingInOrderTraversal)
ThankstoLJW489forsuggestingthismethod.
1)DoInOrderTraversalofthegiventreeandstoretheresultinatemparray.
3)Checkifthetemparrayissortedinascendingorder,ifitis,thenthetreeisBST.
TimeComplexity:O(n)
WecanavoidtheuseofAuxiliaryArray.WhiledoingInOrdertraversal,wecankeeptrackofpreviously
visitednode.Ifthevalueofthecurrentlyvisitednodeislessthanthepreviousvalue,thentreeisnotBST.
Thankstoygosforthisspaceoptimization.
bool isBST(struct node* root)
{
static struct node *prev = NULL;

// traverse the tree in inorder fashion and keep track of prev node
if (root)
{
if (!isBST(root->left))
return false;

// Allows only distinct valued nodes


if (prev != NULL && root->data <= prev->data)
return false;

prev = root;

return isBST(root->right);

return true;
}

=======================================================================

LowestCommonAncestorina
BinarySearchTree.
GivenvaluesoftwonodesinaBinarySearchTree,writeacprogramtofindtheLowestCommonAncestor
(LCA).Youmayassumethatboththevaluesexistinthetree.
Thefunctionprototypeshouldbeasfollows:

structnode*lca(node*root,intn1,intn2)
n1andn2aretwogivenvaluesinthetreewithgivenroot.

Forexample,considertheBSTindiagram,LCAof10and14is12andLCAof8and14is8.
FollowingisdefinitionofLCAfromWikipedia:
LetTbearootedtree.Thelowestcommonancestorbetweentwonodesn1andn2isdefinedasthelowest
nodeinTthathasbothn1andn2asdescendants(whereweallowanodetobeadescendantofitself).
TheLCAofn1andn2inTisthesharedancestorofn1andn2thatislocatedfarthestfromtheroot.
Computationoflowestcommonancestorsmaybeuseful,forinstance,aspartofaprocedurefor
determiningthedistancebetweenpairsofnodesinatree:thedistancefromn1ton2canbecomputedas
thedistancefromtherootton1,plusthedistancefromtherootton2,minustwicethedistancefromtheroot
totheirlowestcommonancestor.(SourceWiki)

Solutions:
IfwearegivenaBSTwhereeverynodehasparentpointer,thenLCAcanbeeasilydeterminedby
traversingupusingparentpointerandprintingthefirstintersectingnode.
WecansolvethisproblemusingBSTproperties.WecanrecursivelytraversetheBSTfromroot.Themain
ideaofthesolutionis,whiletraversingfromtoptobottom,thefirstnodenweencounterwithvaluebetween
n1andn2,i.e.,n1<n<n2orsameasoneofthen1orn2,isLCAofn1andn2(assumingthatn1<n2).So
justrecursivelytraversetheBSTin,ifnode'svalueisgreaterthanbothn1andn2thenourLCAliesinleft
sideofthenode,ifit'sissmallerthanbothn1andn2,thenLCAliesonrightside.OtherwiserootisLCA
(assumingthatbothn1andn2arepresentinBST)
// A recursive C program to find LCA of two nodes n1 and n2.
#include <stdio.h>
#include <stdlib.h>

struct node
{
int data;
struct node* left, *right;
};

/* 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)
{
if (root == NULL) return NULL;

// If both n1 and n2 are smaller than root, then LCA lies in left
if (root->data > n1 && root->data > n2)
return lca(root->left, n1, n2);

// If both n1 and n2 are greater than root, then LCA lies in right
if (root->data < n1 && root->data < n2)
return lca(root->right, n1, n2);

return root;
}

/* Helper function that allocates a new node with the 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);
}

/* Driver program to test mirror() */


int main()
{
// Let us construct the BST shown in the above figure
struct node *root

= newNode(20);

root->left

= newNode(8);

root->right

= newNode(22);

root->left->left

= newNode(4);

root->left->right

= newNode(12);

root->left->right->left = newNode(10);
root->left->right->right = newNode(14);

int n1 = 10, n2 = 14;


struct node *t = lca(root, n1, n2);
printf("LCA of %d and %d is %d \n", n1, n2, t->data);

n1 = 14, n2 = 8;
t = lca(root, n1, n2);
printf("LCA of %d and %d is %d \n", n1, n2, t->data);

n1 = 10, n2 = 22;
t = lca(root, n1, n2);
printf("LCA of %d and %d is %d \n", n1, n2, t->data);

getchar();
return 0;
}
Output:

LCAof10and14is12
LCAof14and8is8
LCAof10and22is20

TimecomplexityofabovesolutionisO(h)wherehisheightoftree.Also,theabovesolutionrequiresO(h)
extraspaceinfunctioncallstackforrecursivefunctioncalls.Wecanavoidextraspaceusingiterative
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;
}

=======================================================================

MergeTwoBalancedBinarySearch
Trees
Youaregiventwobalancedbinarysearchtreese.g.,AVLorRedBlackTree.Writeafunctionthatmerges
thetwogivenbalancedBSTsintoabalancedbinarysearchtree.Lettherebemelementsinfirsttreeandn
elementsintheothertree.YourmergefunctionshouldtakeO(m+n)time.
Inthefollowingsolutions,itisassumedthatsizesoftreesarealsogivenasinput.Ifthesizeisnotgiven,
thenwecangetthesizebytraversingthetree(Seethis).

Method1(Insertelementsoffirsttreetosecond)
TakeallelementsoffirstBSTonebyone,andinsertthemintothesecondBST.Insertinganelementtoa
selfbalancingBSTtakesLogntime(Seethis)wherenissizeoftheBST.Sotimecomplexityofthismethod
isLog(n)+Log(n+1)Log(m+n1).ThevalueofthisexpressionwillbebetweenmLognandmLog(m+n1).
Asanoptimization,wecanpickthesmallertreeasfirsttree.
Method2(MergeInorderTraversals)
1)Doinordertraversaloffirsttreeandstorethetraversalinonetemparrayarr1[].ThissteptakesO(m)
time.
2)Doinordertraversalofsecondtreeandstorethetraversalinanothertemparrayarr2[].Thissteptakes
O(n)time.
3)Thearrayscreatedinstep1and2aresortedarrays.Mergethetwosortedarraysintoonearrayofsizem
+n.ThissteptakesO(m+n)time.
4)Constructabalancedtreefromthemergedarrayusingthetechniquediscussedinthispost.Thisstep
takesO(m+n)time.
TimecomplexityofthismethodisO(m+n)whichisbetterthanmethod1.ThismethodtakesO(m+n)time
eveniftheinputBSTsarenotbalanced.
FollowingisC++implementationofthismethod.
#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;
};

// A utility unction to merge two sorted arrays into one


int *merge(int arr1[], int arr2[], int m, int n);

// A helper function that stores inorder traversal of a tree in inorder array


void storeInorder(struct node* node, int inorder[], int *index_ptr);

/* 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);

/* 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);

// Store inorder traversal of second tree in another array arr2[]


int *arr2 = new int[n];
int j = 0;
storeInorder(root2, arr2, &j);

// Merge the two sorted array into one


int *mergedArr = merge(arr1, arr2, m, n);

// Construct a tree from the merged array and return root of the tree
return sortedArrayToBST (mergedArr, 0, m+n-1);
}

/* 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);
}

// A utility function to print inorder traversal of a given binary tree

void printInorder(struct node* node)


{
if (node == NULL)
return;

/* first recur on left child */


printInorder(node->left);

printf("%d ", node->data);

/* now recur on right child */


printInorder(node->right);
}

// A utility unction to merge two sorted arrays into one


int *merge(int arr1[], int arr2[], int m, int n)
{
// mergedArr[] is going to contain result
int *mergedArr = new int[m + n];
int i = 0, j = 0, k = 0;

// Traverse through both arrays


while (i < m && j < n)
{
// Pick the smaler element and put it in mergedArr
if (arr1[i] < arr2[j])
{
mergedArr[k] = arr1[i];
i++;
}
else
{
mergedArr[k] = arr2[j];
j++;
}
k++;
}

// If there are more elements in first array


while (i < m)
{
mergedArr[k] = arr1[i];
i++; k++;
}

// If there are more elements in second array


while (j < n)
{
mergedArr[k] = arr2[j];
j++; k++;
}

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;

/* first recur on left child */


storeInorder(node->left, inorder, index_ptr);

inorder[*index_ptr] = node->data;
(*index_ptr)++; // increase index for next entry

/* now recur on right child */


storeInorder(node->right, inorder, index_ptr);
}

/* 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;

/* Get the middle element and make it root */


int mid = (start + end)/2;
struct node *root = newNode(arr[mid]);

/* Recursively construct the left subtree and make it


left child of root */
root->left = sortedArrayToBST(arr, start, mid-1);

/* Recursively construct the right subtree and make it


right child of root */
root->right = sortedArrayToBST(arr, mid+1, end);

return root;
}

/* Driver program to test above functions*/


int main()
{
/* Create following tree as first balanced BST
100
/ \
50

300

/\
20 70
*/
struct node *root1 = newNode(100);
root1->left

= newNode(50);

root1->right

= newNode(300);

root1->left->left

= newNode(20);

root1->left->right = newNode(70);

/* Create following tree as second balanced BST

80
/ \
40

120

*/
struct node *root2 = newNode(80);
root2->left

= newNode(40);

root2->right

= newNode(120);

struct node *mergedTree = mergeTrees(root1, root2, 5, 3);

printf ("Following is Inorder traversal of the merged tree \n");


printInorder(mergedTree);

getchar();
return 0;
}
Output:

FollowingisInordertraversalofthemergedtree
2040507080100120300

Method3(InPlaceMergeusingDLL)
WecanuseaDoublyLinkedListtomergetreesinplace.Followingarethesteps.
1)ConvertthegiventwoBinarySearchTreesintodoublylinkedlistinplace(Referthispostforthisstep).
2)MergethetwosortedLinkedLists(Referthispostforthisstep).
3)BuildaBalancedBinarySearchTreefromthemergedlistcreatedinstep2.(Referthispostforthisstep)
TimecomplexityofthismethodisalsoO(m+n)andthismethoddoesconversioninplace.

=======================================================================

Findthenodewithminimumvalue
inaBinarySearchTree
Thisisquitesimple.JusttraversethenodefromroottoleftrecursivelyuntilleftisNULL.Thenodewhose
leftisNULListhenodewithminimumvalue.

Fortheabovetree,westartwith20,thenwemoveleft8,wekeeponmovingtoleftuntilweseeNULL.
Sinceleftof4isNULL,4isthenodewithminimumvalue.
#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;
};

/* 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);
}

/* 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
{
/* 2. Otherwise, recur down the tree */
if (data <= node->data)
node->left = insert(node->left, data);
else
node->right = insert(node->right, data);

/* return the (unchanged) node pointer */


return node;
}
}

/* Given a non-empty binary search tree,


return the minimum data value found in that
tree. Note that the entire tree does not need
to be searched. */
int minValue(struct node* node) {
struct node* current = node;

/* loop down to find the leftmost leaf */


while (current->left != NULL) {
current = current->left;
}
return(current->data);
}

/* Driver program to test sameTree function*/


int main()
{
struct node* root = NULL;
root = insert(root, 4);
insert(root, 2);
insert(root, 1);
insert(root, 3);
insert(root, 6);
insert(root, 5);

printf("\n Minimum value in BST is %d", minValue(root));


getchar();
return 0;
}
TimeComplexity:O(n)Worstcasehappensforleftskewedtrees.

=======================================================================

DynamicProgramming|Set24
(OptimalBinarySearchTree)
Givenasortedarraykeys[0..n1]ofsearchkeysandanarrayfreq[0..n1]offrequencycounts,wherefreq[i]
isthenumberofsearchestokeys[i].Constructabinarysearchtreeofallkeyssuchthatthetotalcostofall
thesearchesisassmallaspossible.
LetusfirstdefinethecostofaBST.ThecostofaBSTnodeislevelofthatnodemultipliedbyitsfrequency.
Levelofrootis1.

Example1
Input:keys[]={10,12},freq[]={34,50}
TherecanbefollowingtwopossibleBSTs
1012
\/
1210
III
Frequencyofsearchesof10and12are34and50respectively.
ThecostoftreeIis34*1+50*2=134
ThecostoftreeIIis50*1+34*2=118

Example2
Input:keys[]={10,12,20},freq[]={34,8,50}
TherecanbefollowingpossibleBSTs
1012201020
\/\/\/
121020122010
\//\
20101212
IIIIIIIVV
AmongallpossibleBSTs,costofthefifthBSTisminimum.
CostofthefifthBSTis1*50+2*34+3*8=142

1)OptimalSubstructure:
Theoptimalcostforfreq[i..j]canberecursivelycalculatedusingfollowingformula.


WeneedtocalculateoptCost(0,n1)tofindtheresult.
Theideaofaboveformulaissimple,weonebyonetryallnodesasroot(rvariesfromitojinsecondterm).
Whenwemakerthnodeasroot,werecursivelycalculateoptimalcostfromitor1andr+1toj.
Weaddsumoffrequenciesfromitoj(seefirsttermintheaboveformula),thisisaddedbecauseevery
searchwillgothroughrootandonecomparisonwillbedoneforeverysearch.
2)OverlappingSubproblems
Followingisrecursiveimplementationthatsimplyfollowstherecursivestructurementionedabove.
// A naive recursive implementation of optimal binary search tree problem
#include <stdio.h>
#include <limits.h>

// A utility function to get sum of array elements freq[i] to freq[j]


int sum(int freq[], int i, int j);

// A recursive function to calculate cost of optimal binary search tree


int optCost(int freq[], int i, int j)
{
// Base cases
if (j < i)

// If there are no elements in this subarray

return 0;
if (j == i)

// If there is one element in this subarray

return freq[i];

// Get sum of freq[i], freq[i+1], ... freq[j]


int fsum = sum(freq, i, j);

// Initialize minimum value


int min = INT_MAX;

// One by one consider all elements as root and recursively find cost
// of the BST, compare the cost with min and update min if needed
for (int r = i; r <= j; ++r)
{
int cost = optCost(freq, i, r-1) + optCost(freq, r+1, j);

if (cost < min)


min = cost;
}

// Return minimum value


return min + fsum;
}

// The main function that calculates minimum cost of a Binary Search Tree.
// It mainly uses optCost() to find the optimal cost.
int optimalSearchTree(int keys[], int freq[], int n)
{
// Here array keys[] is assumed to be sorted in increasing order.
// If keys[] is not sorted, then add code to sort keys, and rearrange
// freq[] accordingly.
return optCost(freq, 0, n-1);
}

// A utility function to get sum of array elements freq[i] to freq[j]


int sum(int freq[], int i, int j)
{
int s = 0;
for (int k = i; k <=j; k++)
s += freq[k];
return s;
}

// Driver program to test above functions


int main()
{
int keys[] = {10, 12, 20};
int freq[] = {34, 8, 50};
int n = sizeof(keys)/sizeof(keys[0]);
printf("Cost of Optimal BST is %d ", optimalSearchTree(keys, freq, n));
return 0;
}
Output:

CostofOptimalBSTis142
Timecomplexityoftheabovenaiverecursiveapproachisexponential.Itshouldbenotedthattheabove
functioncomputesthesamesubproblemsagainandagain.Wecanseemanysubproblemsbeingrepeated
inthefollowingrecursiontreeforfreq[1..4].

Sincesamesuproblemsarecalledagain,thisproblemhasOverlappingSubprolemsproperty.Sooptimal
BSTproblemhasbothproperties(seethisandthis)ofadynamicprogrammingproblem.Likeothertypical
DynamicProgramming(DP)problems,recomputationsofsamesubproblemscanbeavoidedbyconstructing
atemporaryarraycost[][]inbottomupmanner.
DynamicProgrammingSolution
FollowingisC/C++implementationforoptimalBSTproblemusingDynamicProgramming.Weusean
auxiliaryarraycost[n][n]tostorethesolutionsofsubproblems.cost[0][n1]willholdthefinalresult.The
challengeinimplementationis,alldiagonalvaluesmustbefilledfirst,thenthevalueswhichlieontheline
justabovethediagonal.Inotherwords,wemustfirstfillallcost[i][i]values,thenallcost[i][i+1]values,then
allcost[i][i+2]values.Sohowtofillthe2Darrayinsuchmanner>Theideausedintheimplementationis
sameasMatrixChainMultiplicationproblem,weuseavariableLforchainlengthandincrementL,oneby
one.WecalculatecolumnnumberjusingthevaluesofiandL.
// Dynamic Programming code for Optimal Binary Search Tree Problem
#include <stdio.h>
#include <limits.h>

// A utility function to get sum of array elements freq[i] to freq[j]


int sum(int freq[], int i, int j);

/* A Dynamic Programming based function that calculates minimum cost of


a Binary Search Tree. */
int optimalSearchTree(int keys[], int freq[], int n)

{
/* Create an auxiliary 2D matrix to store results of subproblems */
int cost[n][n];

/* cost[i][j] = Optimal cost of binary search tree that can be


formed from keys[i] to keys[j].
cost[0][n-1] will store the resultant cost */

// For a single key, cost is equal to frequency of the key


for (int i = 0; i < n; i++)
cost[i][i] = freq[i];

// Now we need to consider chains of length 2, 3, ... .


// L is chain length.
for (int L=2; L<=n; L++)
{
// i is row number in cost[][]
for (int i=0; i<=n-L+1; i++)
{
// Get column number j from row number i and chain length L
int j = i+L-1;
cost[i][j] = INT_MAX;

// Try making all keys in interval keys[i..j] as root


for (int r=i; r<=j; r++)
{
// c = cost when keys[r] becomes root of this subtree
int c = ((r > i)? cost[i][r-1]:0) +
((r < j)? cost[r+1][j]:0) +
sum(freq, i, j);
if (c < cost[i][j])
cost[i][j] = c;
}
}
}
return cost[0][n-1];
}

// A utility function to get sum of array elements freq[i] to freq[j]


int sum(int freq[], int i, int j)
{
int s = 0;
for (int k = i; k <=j; k++)
s += freq[k];
return s;
}

// Driver program to test above functions


int main()
{
int keys[] = {10, 12, 20};
int freq[] = {34, 8, 50};
int n = sizeof(keys)/sizeof(keys[0]);
printf("Cost of Optimal BST is %d ", optimalSearchTree(keys, freq, n));
return 0;
}
Output:

CostofOptimalBSTis142
Notes
1)ThetimecomplexityoftheabovesolutionisO(n^4).ThetimecomplexitycanbeeasilyreducedtoO(n^3)
byprecalculatingsumoffrequenciesinsteadofcallingsum()againandagain.
2)Intheabovesolutions,wehavecomputedoptimalcostonly.Thesolutionscanbeeasilymodifiedtostore
thestructureofBSTsalso.Wecancreateanotherauxiliaryarrayofsizentostorethestructureoftree.All
weneedtodois,storethechosenrintheinnermostloop.

=======================================================================

You might also like