Populate Inorder Successor for all nodes
Given a Binary Tree where each node has following structure, write a function to populate next pointer for all nodes. The next pointer for every node should be set to point to inorder successor.
struct node
{
int data;
struct node* left;
struct node* right;
struct node* next;
}
Initially, all next pointers have NULL values. Your function should fill these next pointers so that they point to inorder successor.
Solution (Use Reverse Inorder Traversal)
Traverse the given tree in reverse inorder traversal and keep track of previously visited node. When a node is being visited, assign previously visited node as next.
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
struct node *left;
struct node *right;
struct node *next;
};
/* 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 right 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;
}
We can avoid the use of static variable by passing reference to next as paramater.
// 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);
}
}
Time Complexity: O(n)
Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.
Tweet
public class InorderSuccessor { private static Node { int key; Node left; Node right; Node next; } private Node root; private Node fillInorderSuccessor(Node node, Node ancestor) { if (node == null) { return null; } Node leftMostInLeftSubTree = fillInorderSuccessor(node.left, node); Node leftMostInRightSubTree = fillInorderSuccessor(node.right, ancestor); if (leftMostInRightSubTree == null) { node.next = ancestor; } else { node.next = leftMostInRightSubTree; } if (leftMostInLeftSubTree == null) { return node; } return leftMostInLeftSubTree; } public void fillInorderSuccessor() { fillInorderSuccessor(root, null); } }Could you give an initial sample tree and the actual output
@Tika, here is a sample tree and the sample output. The algorithm is O(N) time complexity if you take the inorder traveral of the sample tree (i.e 4->5->6->7) and then reverse it (i.e. 7< -6<-5<-4) and store the inorder sucessor of each BST node in STL Hash Map before I run Populate(node6).
Hash Map Example
Node Successor
4 5
5 6
6 7
7 NULL
/* Paste your code here (You may delete these lines if not writing code) */ 6 /\ / \ 4 7 \ \ 5 6->next = 7 4->next = 5 5->next = 6 7->next = NULL nodemaryc* node6; nodemaryc* node4; nodemaryc* node7; nodemaryc* node5; node4 = new nodemaryc; node4->value = 4; node4->left = NULL; node4->next = NULL; node7 = new nodemaryc; node7->value = 7; node7->left = NULL; node7->right = NULL; node7->next = NULL; node6 = new nodemaryc; node6->value = 6; node6->left = node4; node6->right = node7; node6->next = NULL; node5 = new nodemaryc; node5->value = 5; node5->left = NULL; node5->right = NULL; node5->next = NULL; node4->right = node5; Populate(node6);Great! Thank you very much!
Here is a O(N) time complexity program if we precalculate the in order successor of each node in the BST and cache it in a hash table by hashing the tree node pointer --. Thank you, Camster.
std::map
struct nodemaryc{ int value; nodemaryc* left; nodemaryc* right; nodemaryc* next; }; void PopulateNextRecur(nodemaryc* tree, nodemaryc* node){ nodemaryc* IOSuccessor; if (node == NULL) return; PopulateNextRecur(tree,node->left); IOSuccessor = InOrderSuccessor(tree,node); if (IOSuccessor != NULL){ node->next = IOSuccessor; } PopulateNextRecur(tree,node->right); } void Populate(struct nodemaryc *root) { PopulateNextRecur(root, root); } nodemaryc* InOrderSuccessor(nodemaryvc* tree, nodemaryc* test){ nodemaryc* y = NULL; if (test->right != NULL){ return Minimum(test->right); } else { nodemaryc* candidate = NULL; y = tree; while (y != test){ // y traverses the original tree if (test->value < y->value) { candidate = y; y = y ->left; } else y = y->right; } return candidate; } } nodemaryc* Minimum(nodemaryc* z){ nodemaryc* x = z; while (x->left != NULL){ x = x->left; } return x; } int main(int argc,char** argv[]){ nodemaryc* node6; nodemaryc* node4; nodemaryc* node7; nodemaryc* node5; node4 = new nodemaryc; node4->value = 4; node4->left = NULL; node4->next = NULL; node7 = new nodemaryc; node7->value = 7; node7->left = NULL; node7->right = NULL; node7->next = NULL; node6 = new nodemaryc; node6->value = 6; node6->left = node4; node6->right = node7; node5 = new nodemaryc; node5->value = 5; node5->left = NULL; node5->right = NULL; node5->next = NULL; node5 = new nodemaryc; node5->value = 5; node5->left = NULL; node5->right = NULL; node5->next = NULL; node6->extraId = node5; // node4 node4->right = node5; Populate(node6); return 1; } /* Paste your code here (You may delete these lines if not writing code) */void InorderSuccessor(node *tree, node *previous)
{
if(tree == null) return;
InorderSuccessor(tree->left,previous);
if(previous != null)
{
previous->next = tree;
}
previous = next;
InorderSuccessor(tree->right, previous);
}
I think correct code is this
void populateNext(struct node* p, struct node ** prev) { if (p) { populateNext(p->left,prev); if((*prev) !=NULL) (*prev)->next = p; (*prev) = p; populateNext(p->right,prev); } }