Provide the Next Siblings Pointers in a Given Binary Tree
Problem
Given a binary tree
struct Node {
int val;
Node *left;
Node *right;
Node *next;
}
Populate each next pointer to point to its next right node. If there is no next right node, the next pointer should be set to NULL
.
Initially, all next pointers are set to NULL
.
Examples
Example 1:
Input:
1
/ \
2 3
/ / \
4 6 7
Output:
1 --------> NULL
/ \
2 -> 3 ------> NULL
/ / \
4 -> 6 -> 7 ----> NULL
Input: root = [1,2,3,4,5,null,7]
Output: [1,#,2,3,#,4,5,7,#]
Explanation: Given the above binary tree (Figure A), your function should populate each next pointer to point to its next right node, just like in Figure B. The serialized output is in level order as connected by the next pointers, with '#' signifying the end of each level.
Solution
Method 1 - Using Recursion
- Start from the root, if root’s left node is not null then make it point to the root’s right child.
- Check if root’s nextsibling is not null,
- if NOT then make the next sibling of root’s right node point to the root’s nextsibling’s left child. (In our example node 5 points node 6, as per our statement, Parent of node 5 is Node 2, next sibling of node 2 is node 3, and left child of node 2 is node 6, So Node 5 will points to Node 6 )
public Node connect(Node root) {
if (root == null) return null;
if (root.left != null) { // update left next
if (root.right != null) root.left.next = root.right; // if right child exists - simple connect left.next to right
else root.left.next = findNext(root); // if not - scan parent next node until we find the first left or right child
}
if (root.right != null) { // update right next
root.right.next = findNext(root);
}
connect(root.right); // update the right nodes first
connect(root.left);
return root;
}
private Node findNext(Node root) { // get parent node
while (root.next != null) { // scan all next parent nodes until we find the first left or right child
root = root.next;
if (root.left != null) return root.left;
if (root.right != null) return root.right;
}
return null;
}
Method 2 - BFS
public Node connect(Node root) {
if(root == null) return null;
Queue<Node> q = new LinkedList<>();
q.add(root);
while(!q.isEmpty()){
int size = q.size();
Node nextPointer = null;
for(int i=0;i<size;i++){
Node temp = q.poll();
temp.next = nextPointer;
nextPointer = temp;
if(temp.right != null) {
q.add(temp.right);
}
if(temp.left != null) {
q.add(temp.left);
}
}
}
return root;
}
Method 3 - Iterative
This solution is easier to understand.
public Node connect(Node root) {
// this head will always point to first element in current layer
Node dummyHead = new Node(0);
// this 'pre' will be the "current node" that builds every single layer
Node pre = dummyHead;
Node realRoot = root; // just for return statement
while(root != null){
if(root.left != null){
pre.next = root.left;
pre = pre.next;
}
if(root.right != null){
pre.next = root.right;
pre = pre.next;
}
root = root.next;
// reach the end of current layer
if(root == null){
// shift pre back to the beginning, get ready to point to the first element in next layer
pre = dummyHead;
//root comes down one level below to the first available non null node
root = dummyHead.next; ;
//reset dummyhead back to default null
dummyHead.next = null;
}
}
return realRoot;
}