Connect nodes at same level
Last Updated :
05 Dec, 2022
Given a Binary Tree, The task is to connect all the adjacent nodes at the same level starting from the left-most node of that level, and ending at the right-most node using nextRight pointer by setting these pointers to point the next right for each node.
Examples:
Input:
1
/ \
2 3
/ \ \
4 5 6
Output:
1—>NULL
/ \
2–>3–>NULL
/ \ \
4–>5–>6–>NULL
Input:
10
/ \
12 15
/ \ \
5 4 3
Output:
10—>NULL
/ \
12–>15–>NULL
/ \ \
5–>4–>3–>NULL
Below is the idea to solve the problem
Traverse the tree using Breadth first search traversal and maintain a prev pointer initialized with NULL, firstly point it to root then every time a new node is traversed set prev’s nextRight to current node and move prev to prev’s next.
Follow the below steps to Implement the idea:
- Initialize a node pointer Prev to NULL and a queue of node pointer Q.
- Traverse the tree in Breadth-first search order starting from the root.
- Calculate the size sz of the Q and run a for loop from 0 to sz – 1.
- If prev is Null then set prev to the current node.
- Else set prev’s next to the current node and prev to the current node.
- Set prev’s next to Null and prev to Null.
- If the current node’s left is not null push it into the queue.
- If the current node’s right is not null push it into the queue.
Below is the Implementation of the above approach:
C++
#include <iostream>
#include <queue>
using namespace std;
class node {
public :
int data;
node* left;
node* right;
node* nextRight;
node( int data)
{
this ->data = data;
this ->left = NULL;
this ->right = NULL;
this ->nextRight = NULL;
}
};
void connect(node* root)
{
if (root == NULL)
return ;
queue<node*> q;
q.push(root);
while (!q.empty()) {
int size = q.size();
node* prev = NULL;
while (size--) {
node* temp = q.front();
q.pop();
if (temp->left)
q.push(temp->left);
if (temp->right)
q.push(temp->right);
if (prev != NULL)
prev->nextRight = temp;
prev = temp;
}
prev->nextRight = NULL;
}
}
int main()
{
node* root = new node(10);
root->left = new node(8);
root->right = new node(2);
root->left->left = new node(3);
connect(root);
cout << "Following are populated nextRight pointers in "
"the tree"
" (-1 is printed if there is no nextRight)\n" ;
cout << "nextRight of " << root->data << " is "
<< (root->nextRight ? root->nextRight->data : -1)
<< endl;
cout << "nextRight of " << root->left->data << " is "
<< (root->left->nextRight
? root->left->nextRight->data
: -1)
<< endl;
cout << "nextRight of " << root->right->data << " is "
<< (root->right->nextRight
? root->right->nextRight->data
: -1)
<< endl;
cout << "nextRight of " << root->left->left->data
<< " is "
<< (root->left->left->nextRight
? root->left->left->nextRight->data
: -1)
<< endl;
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class Node {
int data;
Node left, right, nextRight;
Node( int item)
{
data = item;
left = right = nextRight = null ;
}
}
public class BinaryTree {
Node root;
void connect(Node p)
{
Queue<Node> q = new LinkedList<>();
q.add(root);
Node temp = null ;
while (!q.isEmpty()) {
int n = q.size();
for ( int i = 0 ; i < n; i++) {
Node prev = temp;
temp = q.poll();
if (i > 0 )
prev.nextRight = temp;
if (temp.left != null )
q.add(temp.left);
if (temp.right != null )
q.add(temp.right);
}
temp.nextRight = null ;
}
}
public static void main(String args[])
{
BinaryTree tree = new BinaryTree();
tree.root = new Node( 10 );
tree.root.left = new Node( 8 );
tree.root.right = new Node( 2 );
tree.root.left.left = new Node( 3 );
tree.connect(tree.root);
System.out.println(
"Following are populated nextRight pointers in "
+ "the tree"
+ "(-1 is printed if there is no nextRight)" );
int a = tree.root.nextRight != null
? tree.root.nextRight.data
: - 1 ;
System.out.println( "nextRight of " + tree.root.data
+ " is " + a);
int b = tree.root.left.nextRight != null
? tree.root.left.nextRight.data
: - 1 ;
System.out.println( "nextRight of "
+ tree.root.left.data + " is "
+ b);
int c = tree.root.right.nextRight != null
? tree.root.right.nextRight.data
: - 1 ;
System.out.println( "nextRight of "
+ tree.root.right.data + " is "
+ c);
int d = tree.root.left.left.nextRight != null
? tree.root.left.left.nextRight.data
: - 1 ;
System.out.println( "nextRight of "
+ tree.root.left.left.data
+ " is " + d);
}
}
|
Python3
class newnode:
def __init__( self , data):
self .data = data
self .left = self .right = self .nextRight = None
def connect(root):
if root is None :
return
queue = []
queue.append(root)
while len (queue) ! = 0 :
size = len (queue)
prev = newnode( None )
for i in range (size):
temp = queue.pop( 0 )
if temp.left:
queue.append(temp.left)
if temp.right:
queue.append(temp.right)
if prev ! = None :
prev.nextRight = temp
prev = temp
prev.nextRight = None
if __name__ = = '__main__' :
root = newnode( 10 )
root.left = newnode( 8 )
root.right = newnode( 2 )
root.left.left = newnode( 3 )
connect(root)
print ( "Following are populated nextRight" ,
"pointers in the tree (-1 is printed" ,
"if there is no nextRight)" )
print ( "nextRight of" , root.data, "is " , end = "")
if root.nextRight:
print (root.nextRight.data)
else :
print ( - 1 )
print ( "nextRight of" , root.left.data, "is " , end = "")
if root.left.nextRight:
print (root.left.nextRight.data)
else :
print ( - 1 )
print ( "nextRight of" , root.right.data, "is " , end = "")
if root.right.nextRight:
print (root.right.nextRight.data)
else :
print ( - 1 )
print ( "nextRight of" , root.left.left.data, "is " , end = "")
if root.left.left.nextRight:
print (root.left.left.nextRight.data)
else :
print ( - 1 )
|
C#
using System;
using System.Collections.Generic;
class Node {
public int data;
public Node left, right, nextRight;
public Node( int item)
{
data = item;
left = right = nextRight = null ;
}
}
public class BinaryTree {
Node root;
void connect(Node p)
{
Queue<Node> q = new Queue<Node>();
q.Enqueue(root);
Node temp = null ;
while (q.Count > 0) {
int n = q.Count;
for ( int i = 0; i < n; i++) {
Node prev = temp;
temp = q.Dequeue();
if (i > 0)
prev.nextRight = temp;
if (temp.left != null )
q.Enqueue(temp.left);
if (temp.right != null )
q.Enqueue(temp.right);
}
temp.nextRight = null ;
}
}
public static void Main(String[] args)
{
BinaryTree tree = new BinaryTree();
tree.root = new Node(10);
tree.root.left = new Node(8);
tree.root.right = new Node(2);
tree.root.left.left = new Node(3);
tree.connect(tree.root);
Console.WriteLine(
"Following are populated nextRight pointers in "
+ "the tree"
+ "(-1 is printed if there is no nextRight)" );
int a = tree.root.nextRight != null
? tree.root.nextRight.data
: -1;
Console.WriteLine( "nextRight of " + tree.root.data
+ " is " + a);
int b = tree.root.left.nextRight != null
? tree.root.left.nextRight.data
: -1;
Console.WriteLine( "nextRight of "
+ tree.root.left.data + " is "
+ b);
int c = tree.root.right.nextRight != null
? tree.root.right.nextRight.data
: -1;
Console.WriteLine( "nextRight of "
+ tree.root.right.data + " is "
+ c);
int d = tree.root.left.left.nextRight != null
? tree.root.left.left.nextRight.data
: -1;
Console.WriteLine( "nextRight of "
+ tree.root.left.left.data
+ " is " + d);
Console.ReadKey();
}
}
|
Javascript
<script>
class Node
{
constructor(item)
{
this .data = item;
this .left = this .right = this .nextRight = null ;
}
}
let root;
function connect(p)
{
let q = [];
q.push(root);
let temp = null ;
while (q.length!=0) {
let n = q.length;
for (let i = 0; i < n; i++) {
let prev = temp;
temp = q.shift();
if (i > 0)
prev.nextRight = temp;
if (temp.left != null )
q.push(temp.left);
if (temp.right != null )
q.push(temp.right);
}
temp.nextRight = null ;
}
}
root = new Node(10);
root.left = new Node(8);
root.right = new Node(2);
root.left.left = new Node(3);
connect(root);
document.write( "Following are populated nextRight pointers in "
+ "the tree"
+ "(-1 is printed if there is no nextRight)<br>" );
let a = root.nextRight != null ? root.nextRight.data : -1;
document.write( "nextRight of " + root.data + " is "
+ a+ "<br>" );
let b = root.left.nextRight != null ? root.left.nextRight.data : -1;
document.write( "nextRight of " + root.left.data + " is "
+ b+ "<br>" );
let c = root.right.nextRight != null ? root.right.nextRight.data : -1;
document.write( "nextRight of " + root.right.data + " is "
+ c+ "<br>" );
let d = root.left.left.nextRight != null ? root.left.left.nextRight.data : -1;
document.write( "nextRight of " + root.left.left.data + " is "
+ d+ "<br>" );
</script>
|
Output
Following are populated nextRight pointers in the tree (-1 is printed if there is no nextRight)
nextRight of 10 is -1
nextRight of 8 is 2
nextRight of 2 is -1
nextRight of 3 is -1
Time Complexity: O(N)
Auxiliary Space: O(N)
Connect nodes at the same level using Pre Order Traversal:
This approach works only for Complete Binary Trees. In this method we set nextRight in Pre Order fashion to make sure that the nextRight of parent is set before its children. When we are at node p, we set the nextRight of its left and right children. Since the tree is complete tree, nextRight of p’s left child (p->left->nextRight) will always be p’s right child, and nextRight of p’s right child (p->right->nextRight) will always be left child of p’s nextRight (if p is not the rightmost node at its level). If p is the rightmost node, then nextRight of p’s right child will be NULL.
Follow the below steps to Implement the idea:
- Set root ->nextRight to NULL.
- Call for a recursive function of root.
- If root -> left is not NULL then set root -> left -.> nextRight = root -> right
- If root -> right is not NULL then
- If root -> nextRight is not NULL set root -> right -.> nextRight = root -> nextRight -> left.
- Else set root -> right -.> nextRight to NULL.
- recursively call for left of root
- recursively call for right of root
Below is the Implementation of the above approach:
C++
#include <bits/stdc++.h>
#include <iostream>
using namespace std;
class node {
public :
int data;
node* left;
node* right;
node* nextRight;
node( int data)
{
this ->data = data;
this ->left = NULL;
this ->right = NULL;
this ->nextRight = NULL;
}
};
void connectRecur(node* p);
void connect(node* p)
{
p->nextRight = NULL;
connectRecur(p);
}
void connectRecur(node* p)
{
if (!p)
return ;
if (p->left)
p->left->nextRight = p->right;
if (p->right)
p->right->nextRight
= (p->nextRight) ? p->nextRight->left : NULL;
connectRecur(p->left);
connectRecur(p->right);
}
int main()
{
node* root = new node(10);
root->left = new node(8);
root->right = new node(2);
root->left->left = new node(3);
connect(root);
cout << "Following are populated nextRight pointers in "
"the tree"
" (-1 is printed if there is no nextRight)\n" ;
cout << "nextRight of " << root->data << " is "
<< (root->nextRight ? root->nextRight->data : -1)
<< endl;
cout << "nextRight of " << root->left->data << " is "
<< (root->left->nextRight
? root->left->nextRight->data
: -1)
<< endl;
cout << "nextRight of " << root->right->data << " is "
<< (root->right->nextRight
? root->right->nextRight->data
: -1)
<< endl;
cout << "nextRight of " << root->left->left->data
<< " is "
<< (root->left->left->nextRight
? root->left->left->nextRight->data
: -1)
<< endl;
return 0;
}
|
C
#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node* left;
struct node* right;
struct node* nextRight;
};
void connectRecur( struct node* p);
void connect( struct node* p)
{
p->nextRight = NULL;
connectRecur(p);
}
void connectRecur( struct node* p)
{
if (!p)
return ;
if (p->left)
p->left->nextRight = p->right;
if (p->right)
p->right->nextRight
= (p->nextRight) ? p->nextRight->left : NULL;
connectRecur(p->left);
connectRecur(p->right);
}
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);
}
int main()
{
struct node* root = newnode(10);
root->left = newnode(8);
root->right = newnode(2);
root->left->left = newnode(3);
connect(root);
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);
return 0;
}
|
Java
import java.util.*;
class GFG {
static class node {
int data;
node left;
node right;
node nextRight;
node( int data)
{
this .data = data;
this .left = null ;
this .right = null ;
this .nextRight = null ;
}
};
static void connect(node p)
{
p.nextRight = null ;
connectRecur(p);
}
static void connectRecur(node p)
{
if (p == null )
return ;
if (p.left != null )
p.left.nextRight = p.right;
if (p.right != null )
p.right.nextRight = (p.nextRight) != null
? p.nextRight.left
: null ;
connectRecur(p.left);
connectRecur(p.right);
}
public static void main(String[] args)
{
node root = new node( 10 );
root.left = new node( 8 );
root.right = new node( 2 );
root.left.left = new node( 3 );
connect(root);
System.out.print(
"Following are populated nextRight pointers in the tree"
+ " (-1 is printed if there is no nextRight)\n" );
System.out.print(
"nextRight of " + root.data + " is "
+ (root.nextRight != null ? root.nextRight.data
: - 1 )
+ "\n" );
System.out.print( "nextRight of " + root.left.data
+ " is "
+ (root.left.nextRight != null
? root.left.nextRight.data
: - 1 )
+ "\n" );
System.out.print( "nextRight of " + root.right.data
+ " is "
+ (root.right.nextRight != null
? root.right.nextRight.data
: - 1 )
+ "\n" );
System.out.print(
"nextRight of " + root.left.left.data + " is "
+ (root.left.left.nextRight != null
? root.left.left.nextRight.data
: - 1 )
+ "\n" );
}
}
|
Python3
class newnode:
def __init__( self , data):
self .data = data
self .left = self .right = self .nextRight = None
def connect(p):
p.nextRight = None
connectRecur(p)
def connectRecur(p):
if ( not p):
return
if (p.left):
p.left.nextRight = p.right
if (p.right):
if p.nextRight:
p.right.nextRight = p.nextRight.left
else :
p.right.nextRight = None
connectRecur(p.left)
connectRecur(p.right)
if __name__ = = '__main__' :
root = newnode( 10 )
root.left = newnode( 8 )
root.right = newnode( 2 )
root.left.left = newnode( 3 )
connect(root)
print ( "Following are populated nextRight" ,
"pointers in the tree (-1 is printed" ,
"if there is no nextRight)" )
print ( "nextRight of" , root.data, "is " , end = "")
if root.nextRight:
print (root.nextRight.data)
else :
print ( - 1 )
print ( "nextRight of" , root.left.data, "is " , end = "")
if root.left.nextRight:
print (root.left.nextRight.data)
else :
print ( - 1 )
print ( "nextRight of" , root.right.data, "is " , end = "")
if root.right.nextRight:
print (root.right.nextRight.data)
else :
print ( - 1 )
print ( "nextRight of" , root.left.left.data, "is " , end = "")
if root.left.left.nextRight:
print (root.left.left.nextRight.data)
else :
print ( - 1 )
|
C#
using System;
public class Node {
public int data;
public Node left, right, nextRight;
public Node( int item)
{
data = item;
left = right = nextRight = null ;
}
}
public class BinaryTree {
public Node root;
public virtual void connect(Node p)
{
p.nextRight = null ;
connectRecur(p);
}
public virtual void connectRecur(Node p)
{
if (p == null ) {
return ;
}
if (p.left != null ) {
p.left.nextRight = p.right;
}
if (p.right != null ) {
p.right.nextRight = (p.nextRight != null )
? p.nextRight.left
: null ;
}
connectRecur(p.left);
connectRecur(p.right);
}
public static void Main( string [] args)
{
BinaryTree tree = new BinaryTree();
tree.root = new Node(10);
tree.root.left = new Node(8);
tree.root.right = new Node(2);
tree.root.left.left = new Node(3);
tree.connect(tree.root);
Console.WriteLine(
"Following are populated nextRight pointers in "
+ "the tree"
+ "(-1 is printed if there is no nextRight)" );
int a = tree.root.nextRight != null
? tree.root.nextRight.data
: -1;
Console.WriteLine( "nextRight of " + tree.root.data
+ " is " + a);
int b = tree.root.left.nextRight != null
? tree.root.left.nextRight.data
: -1;
Console.WriteLine( "nextRight of "
+ tree.root.left.data + " is "
+ b);
int c = tree.root.right.nextRight != null
? tree.root.right.nextRight.data
: -1;
Console.WriteLine( "nextRight of "
+ tree.root.right.data + " is "
+ c);
int d = tree.root.left.left.nextRight != null
? tree.root.left.left.nextRight.data
: -1;
Console.WriteLine( "nextRight of "
+ tree.root.left.left.data
+ " is " + d);
}
}
|
Javascript
<script>
class Node
{
constructor(item)
{
this .data = item;
this .left = this .right = this .nextRight = null ;
}
}
function connect( p) {
p.nextRight = null ;
connectRecur(p);
}
function connectRecur( p) {
if (p == null )
return ;
if (p.left != null )
p.left.nextRight = p.right;
if (p.right != null )
p.right.nextRight = (p.nextRight) != null ? p.nextRight.left : null ;
connectRecur(p.left);
connectRecur(p.right);
}
let root = new Node(10);
root.left = new Node(8);
root.right = new Node(2);
root.left.left = new Node(3);
connect(root);
document.write( "Following are populated nextRight pointers in "
+ "the tree"
+ "(-1 is printed if there is no nextRight)<br>" );
let a = root.nextRight != null ? root.nextRight.data : -1;
document.write( "nextRight of " + root.data + " is "
+ a+ "<br>" );
let b = root.left.nextRight != null ? root.left.nextRight.data : -1;
document.write( "nextRight of " + root.left.data + " is "
+ b+ "<br>" );
let c = root.right.nextRight != null ? root.right.nextRight.data : -1;
document.write( "nextRight of " + root.right.data + " is "
+ c+ "<br>" );
let d = root.left.left.nextRight != null ? root.left.left.nextRight.data : -1;
document.write( "nextRight of " + root.left.left.data + " is "
+ d+ "<br>" );
</script>
|
Output
Following are populated nextRight pointers in the tree (-1 is printed if there is no nextRight)
nextRight of 10 is -1
nextRight of 8 is 2
nextRight of 2 is -1
nextRight of 3 is -1
Thanks to Dhanya for suggesting this approach.
Time Complexity: O(N)
Auxiliary Space: O(N)
Why doesn’t method 2 work for trees which are not Complete Binary Trees?
Let us consider following tree as an example. In Method 2, we set the nextRight pointer in pre order fashion. When we are at node 4, we set the nextRight of its children which are 8 and 9 (the nextRight of 4 is already set as node 5). nextRight of 8 will simply be set as 9, but nextRight of 9 will be set as NULL which is incorrect. We can’t set the correct nextRight, because when we set nextRight of 9, we only have nextRight of node 4 and ancestors of node 4, we don’t have nextRight of nodes in right subtree of root.
1
/ \
2 3
/ \ / \
4 5 6 7
/ \ / \
8 9 10 11
See Connect nodes at same level using constant extra space for more solutions.
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...