How to convert a Ternary expression to a Binary tree structure? - binary-tree

I came across this problem that has Ternary expression (a?b:c) and needs the ternary expression to be converted into a Binary tree structure.
a?b:c
a
/ \
b c
a?b?c:d:e
a
/ \
b e
/ \
c d
My approach using a Binary tree implemented using a array :-
Parent resides at - i
Left child - 2i
Right child - 2i+1
Start parsing the ternary expression the first character will form the root node so it will be at position 1 in the array. If the next character is a '?' then the characters that follow will be its children so left child (b in this case will be at position 2). If the next character is a ":" then we have found the right child (c in the first case) so we add that to position 3.
In the second case we face a "?" after b so whatever follows will be its children and will be added to 2j and 2j+1 respectively where j is the position of b in the array.Now we face a ":" we check the parent of the current child if it has two children then we backtrack and check the previous node until we find a node that is missing a right child.
Is there any other way to do this? Hope I have been articulate enough.

Below is my solution which has been tested thoroughly.
class TreeNode {
char c;
TreeNode left;
TreeNode right;
TreeNode(char c) {
this.c = c;
left = null;
right = null;
}
}
public TreeNode tenaryToTree(String s) {
if (s.length() == 0) {
return null;
}
TreeNode root = new TreeNode(s.charAt(0));
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
for (int i = 1; i < s.length(); i++) {
if (s.charAt(i) == '?') {
TreeNode node = stack.peek();
node.left = new TreeNode(s.charAt(i + 1));
stack.push(node.left);
} else if (s.charAt(i) == ':') {
stack.pop();
TreeNode node = stack.pop();
node.right = new TreeNode(s.charAt(i + 1));
stack.push(node.right);
}
}
return root;
}

This one would be without using parent node. But using stack.
public NodeC convertTtoBT (char[] values) {
char xx = values[0];
NodeC n = new NodeC(xx);
Stack<NodeC> a = new Stack<NodeC>();
for (int i = 1; i < values.length; i += 2) {
if (values[i] == '?') {
n.left = new NodeC (values[i + 1]);
a.add(n);
n = n.left;
}
else if (values[i] == ':') {
n = a.pop();
while (n.right != null) {
n = a.pop();
}
n.right = new NodeC (values[i + 1]);
a.add(n);
n = n.right;
}
}
return n;
}

Walk through the expression from right to left, pushing any letters as nodes to the stack. If you see '?', then instead of pushing the next letter, take it as the root, pop two last nodes from the stack as left and right root's children, and push the root back into the stack.
public TreeNode ternaryToTree(char[] exp) {
LinkedList<TreeNode> stack = new LinkedList<TreeNode>();
for (int i = exp.length-1; i >= 0; i--) {
if (exp[i] == ':') continue;
if (exp[i] == '?') {
TreeNode node = new TreeNode(exp[--i]);
node.left = stack.pop();
node.right = stack.pop();
stack.push(node);
} else {
stack.push(new TreeNode(exp[i]));
}
}
return stack.isEmpty() ? null : stack.pop();
}

if this a?b:c?d?e:f:g?h:i?j:k is the ternary expression then tree would be like this
a
/ \
b c
/ \
d g
/ \ / \
e f h i
/ \
j k
Below is the Java solution...
private static TreeNode convertTernaryExpression(String s)
{
Stack<TreeNode> stack = new Stack<>();
int length = s.length();
int index = 0;
TreeNode rootNode = null;
while(index < length)
{
while(s.charAt(index) != ':')
{
if(s.charAt(index) == '?' && stack.peek().right != null)
{
TreeNode temp = stack.pop();
if(rootNode == null)
{
rootNode = temp;
}
stack.push(temp.right);
}
stack.push(new TreeNode(s.charAt(index++)));
}
TreeNode left = stack.pop();
TreeNode questionMark = stack.pop();
TreeNode root = stack.pop();
index++;
TreeNode right = new TreeNode(s.charAt(index++));
root.left = left;
root.right = right;
stack.push(root);
}
if(rootNode == null)
{
return stack.pop();
}
else
{
return rootNode;
}
}
class TreeNode
{
TreeNode left;
TreeNode right;
char val;
public TreeNode(char val)
{
this.val = val;
this.left = null;
this.right = null;
}
}

I came up with something like this using trees. Not tested thoroughly:
When I see a '?', it's my left child, so add to my left and go left.
If I see ':', then:
Go to my parent
If right is not null and parent is not not null, keep going to my parent
My right child is empty. Add right. Go to right.
Note: You will never go back to the root if it has a right child.
public NodeC convertTtoBT (char[] values) {
NodeC n = new NodeC (values[0]);
for (int i = 1; i < values.length; i += 2) {
if (values[i] == '?') {
n.left = new NodeC (values[i + 1]);
n = n.left;
}
else if (values[i] == ':') {
n = n.parent;
while (n.right != null && n.parent != null ) {
n = n.parent;
}
n.right = new NodeC (values[i + 1]);
n = n.right;
}
}
return n;

Idea is to start parsing the string from left to right and when you come across a '?' you go deeper in the tree else just return the new node created.
Here is my recursive solution :
struct node{
char val;
node *left;
node *right;
node(char v):val(v),left(NULL),right(NULL){
}
};
node* create_tree(string input, int &current){
if(current>=(int)input.size()){
return NULL;
}
node *temp = new node(input[current]);
current+=2;
if(current<(int)input.size()){
if(input[current-1]=='?'){
temp->left=create_ternary_tree(input,current);
temp->right=create_ternary_tree(input,current);
}
}
return temp;
}

My solution:
Each treenode doen't have parent link, so I use stack to keep them.
The advantages of this solution are that I only push root into stack, hence in the (if x==':' {}) sentence, no while loop, no push sentence.
public static TreeNode convert(String ternary) {
char[] chs = ternary.toCharArray();
Stack<TreeNode> stack = new Stack<TreeNode>();
TreeNode cur=new TreeNode(chs[0]);
TreeNode root= cur;
for (int i=1; i<chs.length; i+=2) {
if (chs[i]=='?') {
stack.push(cur);
TreeNode node = new TreeNode(chs[i+1]);
cur.left = node;
cur = node;
}
else if (chs[i]==':') {
cur = stack.pop();
TreeNode node = new TreeNode(chs[i+1]);
cur.right = node;
cur = node;
}
}
return root;
}

public static TreeNode convert_loop(char[] expr) {
if (expr == null || expr.length < 1) {
return null;
}
if (expr.length == 1) {
return new TreeNode(expr[0]);
}
if ((expr.length - 1) % 4 != 0) {
throw new InputMismatchException("wrong expression");
}
int start = 0, end = expr.length - 1;
TreeNode<Character> root = new TreeNode<>(expr[start]);
root.right = new TreeNode<>(expr[end]);
start += 2;
end -= 2;
TreeNode<Character> cur = root;
while (start != end) {
TreeNode<Character> node = new TreeNode<>(expr[start]);
node.right = new TreeNode<>(expr[end]);
cur.left = node;
cur = node;
start += 2;
end -= 2;
}
cur.left = new TreeNode(expr[start]);// care
return root;
}

Related

Recursion in Binary Search Tree construction

Below is the code implementation of binary search tree construction in C++. My confusion is I am not able to trace the recursion stack. Consider the below tree. Now I want to remove the node 10. SO this will jump to the line in the code that checks if both left and right subtree are not null and it will try to find the least value in the right subtree and that is 11 in this case. and it will recursively call remove function again . Now I have one doubt - when remove is recursively called again - first it removes 11 from that position in the original tree and return 11 from the function that is received by first remove function on the stack, but then which line in the code actually updates 11 to the root. I am really not getting this in my head. Please help me out.
10
/ \
6 12
\ / \
8 11 15
#include <bits/stdc++.h>
using namespace std;
class BST
{
public:
int value;
BST *left;
BST *right;
BST(int val)
{
value = val;
left = NULL;
right = NULL;
}
BST &insert(int val)
{
BST *currentNode = this; //this points to the current object of BST class. For instance if you created
//root node with value 10. this will store the reference to the root node object
while(true)
{
if (val < currentNode->value) //go to left subtree
{
if (currentNode->left == NULL) //if null insert
{
BST *newNode = new BST(val);
currentNode->left = newNode; //update the address
break;
}
else
{
currentNode = currentNode->left; //if not null then keep traversing
}
}
else
{
if (currentNode->right == NULL)
{
BST *newNode = new BST(val);
currentNode->right = newNode;
break;
}
else
{
currentNode = currentNode->right;
}
}
}
return *this;
}
bool contains(int val)
{
BST *currentNode = this;
while(currentNode != NULL)
{
if (val < currentNode->value)
currentNode = currentNode->left; //if value is less then keep traversing left
else if (val > currentNode->value)
currentNode = currentNode->right; //if value is greater then keep traversing right
else
return true;
}
return false;
}
BST &remove(int val, BST *parentNode = NULL)
{
BST *currentNode = this;
while (currentNode != NULL)
{
if (val < currentNode->value)
{
parentNode = currentNode;
currentNode = currentNode->left;
}
else if (val > currentNode->value)
{
parentNode = currentNode;
currentNode = currentNode->right;
}
//Up until above line the code first searches for the element to be removed
else
{
if (currentNode->left != NULL && currentNode->right != NULL) //this node checks if it has
//left and right child both and if yes then find the least value in the right subtree and then
//remove that node from that position
{
currentNode->value = currentNode->right->getMinValue();
currentNode->right->remove(currentNode->value,currentNode);
}
else if (parentNode == NULL) //this is special case of root node where there may be only
//left child existing or only right child. If both exist then above logic takes care of that
{
if (currentNode->left != NULL)
{
currentNode->value = currentNode->left->value;
currentNode->right = currentNode->left->right;
currentNode->left = currentNode->left->left;
}
else if (currentNode->right != NULL)
{
currentNode->value = currentNode->right->value;
currentNode->left = currentNode->right->left;
currentNode->right = currentNode->right->right;
}
else
{} //This is for single node tree. Do nothing
}
else if (parentNode->left == currentNode) //this condition if the parent node left child is
//the node to be removed . Then we can do simple one liner and update the node
{
parentNode->left = currentNode->left != NULL ? currentNode->left : currentNode->right;
}
else if (parentNode->right == currentNode)
{
parentNode->right = currentNode->left != NULL ? currentNode->left : currentNode->right;
}
break;
}
}
return *this;
}
int getMinValue()
{
if (left == NULL)
return value;
else
return left->getMinValue();
}
void show()
{
BST *currentNode = this;
cout<<currentNode->value;
}
};
int main()
{
int value = 10;
BST b1(value);
b1.insert(12);
b1.insert(6);
b1.insert(8);
b1.insert(15);
b1.insert(11);
b1.remove(10);
b1.show();
}

Tree Postorder Traversal performance

I tried to work on my own to get iterative postorder traversal. My solution got Time Limited Exceeded in Leetcode Online Judge
public List<Integer> postorderTraversalIterativel(TreeNode root) {
List<Integer> ret = new LinkedList<Integer>();
Stack<TreeNode> stack = new Stack<TreeNode>();
TreeNode cur = root;
while (cur != null || !stack.isEmpty()) {
if (cur != null) {
stack.push(cur);
cur = cur.left;
} else {
TreeNode parent = stack.peek(), child = null;
if (parent.right == null) {
// pop hard
stack.pop();
while (parent.right == child && !stack.isEmpty()) {
child = parent;
ret.add(child.val);
parent = stack.pop();
}
} else {
cur = parent.right;
}
}
}
return ret;
}
while the official implementation from wikipedia could pass the test.
public List<Integer> postorderTraversalIterativel(TreeNode root) {
List<Integer> ret = new LinkedList<Integer>();
Stack<TreeNode> stack = new Stack<TreeNode>();
TreeNode cur = root, lastVisited = null;
while (cur != null || !stack.isEmpty()) {
if (cur != null) {
stack.push(cur);
cur = cur.left;
} else {
TreeNode parent = stack.peek();
if (parent.right != null && lastVisited != parent.right) {
// make sure pop all the node has right child of the
// previous pop
cur = parent.right;
} else {
stack.pop();
ret.add(parent.val);
lastVisited = parent;
}
}
}
return ret;
}
by inspecting the code, I am unable to see why my implementation is slower than the official one. Could anyone point out what's happening? (It's possible that my solution is logically wrong, but the one failed my solution in timing I have unit tested, and the unit test finishes quick ...). Any comments are welcome.
public void testPostorderTraversal1() {
TreeNode root = new TreeNode(3);
TreeNode right = new TreeNode(1);
TreeNode rightLeft = new TreeNode(2);
root.right = right;
right.left = rightLeft;
List<Integer> list = new LinkedList<Integer>();
list.add(2);
list.add(1);
list.add(3);
assertEquals(list.toString(), sut.postorderTraversal(root).toString());
}
public void testPostorderTraversal2() {
TreeNode root = new TreeNode(1);
TreeNode right = new TreeNode(2);
root.right = right;
List<Integer> list = new LinkedList<Integer>();
list.add(2);
list.add(1);
assertEquals(list.toString(), sut.postorderTraversal(root).toString());
}
Your code has possible to do Infinite loop.
Your 'testPostorderTraversal1' unitest is not finish.
If there is any node that has right child node that has left child node, can't finish.

Check if a binary tree is balanced with iterative function?

I need to implement a non-recursive function to determine if a binary tree is balanced or not.
Anyone?
Thanks!!!
Assuming that by "balanced", you mean "height-balanced" in the AVL-tree sense, and you can store arbitrary information for each node,
For each node in post-order,
if either child doesn't exist, assume its respective height is 0.
if the height of both children differs by more than one, the tree is not balanced.
otherwise, this node's height is the larger of both children's heights.
If this point is reached, the tree is balanced.
One way to perform post-order traversal:
start at the root
loop
if this node's left child exists and does not have its height computed, visit its left child next.
else if this node's right child exists and does not have its height computed, visit its right child next.
else
compute this node's height, possibly returning early
if this node is not the root, visit its parent next.
If this point is reached, the tree is balanced.
Try this,
public class BalancedBinaryTree {
public static class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode() {}
TreeNode(int val) { this.val = val; }
TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}
}
public boolean isBalanced(TreeNode root) {
if (root==null) {
return true;
}
Stack<TreeNode> stack = new Stack<>();
Map<TreeNode, Integer> map = new HashMap<>();
stack.push(root);
while(!stack.isEmpty()) {
TreeNode node = stack.pop();
if ((node.left==null || (node.left!=null && map.containsKey(node.left))) && (node.right==null || (node.right!=null && map.containsKey(node.right)))) {
int right = (node.right==null) ? 0 : map.get(node.right);
int left = (node.left==null) ? 0 : map.get(node.left);
if (Math.abs(right-left)>1) {
return false;
} else {
map.put(node, Math.max(right, left)+1);
}
} else {
if (node.left!=null && !map.containsKey(node.left)) {
stack.push(node);
stack.push(node.left);
} else {
stack.push(node);
stack.push(node.right);
}
}
}
return true;
}
public static void main(String[] args) {
BalancedBinaryTree b = new BalancedBinaryTree();
boolean v = b.isBalanced(new TreeNode(3, new TreeNode(9), new TreeNode(20, new TreeNode(15), new TreeNode(7))));
System.out.println(v);
v = b.isBalanced(new TreeNode(1, new TreeNode(2, new TreeNode(3, new TreeNode(4), new TreeNode(4)), new TreeNode(3)), new TreeNode(2)));
System.out.println(v);
v = b.isBalanced(new TreeNode(1, new TreeNode(2, new TreeNode(4, new TreeNode(8), null), new TreeNode(5)), new TreeNode(3, new TreeNode(6), null)));
System.out.println(v);
}
}
Here is a c++ code that works, inspired by the postorder traversal. The code is not commented because i do not think a simple comment is enough to explain the whole algorithm. You can execute this code manually with the example below and then you will understand everything.
bool IsBalance(const Node *head)
{
std::stack<const Node *> s;
std::stack<int> sV;
const Node *curr = head, *lastVisit = nullptr;
int deep = 0;
while (curr || !s.empty())
{
while (curr)
{
s.push(curr);
sV.push(-1);
curr = curr->m_pLeft;
}
curr = s.top();
if (sV.top() == -1)
{
sV.top() = deep;
}
if (!curr->m_pRight || curr->m_pRight == lastVisit)
{
if (!curr->m_pRight)
{
deep = 0;
}
if (std::abs(sV.top() - deep) > 1)
{
return false;
}
deep = std::max(sV.top(), deep) + 1;
lastVisit = curr;
s.pop();
sV.pop();
curr = nullptr;
}
else
{
deep = 0;
curr = curr->m_pRight;
}
}
return true;
}
examples:
(1) 21,10,3,1,#,#,5,#,6,#,#,15,12,#,#,18,16,#,#,20,#,#,35,30,22,#,#,#,40,36,#,#,42,#,45,#,#
(2) 1,2,#,4,#,5,#,#,3,6,8,#,#,#,7,#,#
(3) 3,1,#,2,#,#,#
Where nodes are arranged by PreOrder, separated by commas, and # indicates an empty node.
Find the height of left subtree and right subtree for a node of the tree, using Level order traversal and check if that node is balanced.
Repeat this for every node of the tree. For traversing all the nodes we can use level order traversal to avoid recursion.
int height(TreeNode* root){
if(!root){
return 0;
}
queue<TreeNode*> q;
q.push(root);
int count=0;
while(!q.empty()){
int size=q.size();
for(int i=0;i<size;++i){
TreeNode* temp=q.front();
q.pop();
if(temp->left){
q.push(temp->left);
}
if(temp->right){
q.push(temp->right);
}
}
count++;
}
return count;
}
bool checkEveryNode(TreeNode* root){
if(!root){
return true;
}
queue<TreeNode*> q;
q.push(root);
while(!q.empty()){
int count=q.size();
for(int i=0;i<count;++i){
TreeNode* temp=q.front();
q.pop();
int left=height(temp->left);
int right=height(temp->right);
if(abs(left-right)>1){
return false;
}
if(temp->left){
q.push(temp->left);
}
if(temp->right){
q.push(temp->right);
}
}
}
return true;
}
bool isBalanced(TreeNode* root) {
return checkEveryNode(root);
}
Time complexity of this approach is O(n^2), as we need to traverse all the descendant nodes for finding the height of a node(N) and we need to do this for all the nodes(N)

Interview Question: Merge two sorted singly linked lists without creating new nodes

This is a programming question asked during a written test for an interview.
"You have two singly linked lists that are already sorted, you have to merge them and return a the head of the new list without creating any new extra nodes. The returned list should be sorted as well"
The method signature is:
Node MergeLists(Node list1, Node list2);
Node class is below:
class Node{
int data;
Node next;
}
I tried many solutions but not creating an extra node screws things. Please help.
Here is the accompanying blog entry http://techieme.in/merging-two-sorted-singly-linked-list/
Node MergeLists(Node list1, Node list2) {
if (list1 == null) return list2;
if (list2 == null) return list1;
if (list1.data < list2.data) {
list1.next = MergeLists(list1.next, list2);
return list1;
} else {
list2.next = MergeLists(list2.next, list1);
return list2;
}
}
Recursion should not be needed to avoid allocating a new node:
Node MergeLists(Node list1, Node list2) {
if (list1 == null) return list2;
if (list2 == null) return list1;
Node head;
if (list1.data < list2.data) {
head = list1;
} else {
head = list2;
list2 = list1;
list1 = head;
}
while(list1.next != null) {
if (list1.next.data > list2.data) {
Node tmp = list1.next;
list1.next = list2;
list2 = tmp;
}
list1 = list1.next;
}
list1.next = list2;
return head;
}
Node MergeLists(Node node1, Node node2)
{
if(node1 == null)
return node2;
else (node2 == null)
return node1;
Node head;
if(node1.data < node2.data)
{
head = node1;
node1 = node1.next;
else
{
head = node2;
node2 = node2.next;
}
Node current = head;
while((node1 != null) ||( node2 != null))
{
if (node1 == null) {
current.next = node2;
return head;
}
else if (node2 == null) {
current.next = node1;
return head;
}
if (node1.data < node2.data)
{
current.next = node1;
current = current.next;
node1 = node1.next;
}
else
{
current.next = node2;
current = current.next;
node2 = node2.next;
}
}
current.next = NULL // needed to complete the tail of the merged list
return head;
}
Look ma, no recursion!
struct llist * llist_merge(struct llist *one, struct llist *two, int (*cmp)(struct llist *l, struct llist *r) )
{
struct llist *result, **tail;
for (result=NULL, tail = &result; one && two; tail = &(*tail)->next ) {
if (cmp(one,two) <=0) { *tail = one; one=one->next; }
else { *tail = two; two=two->next; }
}
*tail = one ? one: two;
return result;
}
Here is the algorithm on how to merge two sorted linked lists A and B:
while A not empty or B not empty:
if first element of A < first element of B:
remove first element from A
insert element into C
end if
else:
remove first element from B
insert element into C
end while
Here C will be the output list.
Iteration can be done as below. Complexity = O(n)
public static LLNode mergeSortedListIteration(LLNode nodeA, LLNode nodeB) {
LLNode mergedNode ;
LLNode tempNode ;
if (nodeA == null) {
return nodeB;
}
if (nodeB == null) {
return nodeA;
}
if ( nodeA.getData() < nodeB.getData())
{
mergedNode = nodeA;
nodeA = nodeA.getNext();
}
else
{
mergedNode = nodeB;
nodeB = nodeB.getNext();
}
tempNode = mergedNode;
while (nodeA != null && nodeB != null)
{
if ( nodeA.getData() < nodeB.getData())
{
mergedNode.setNext(nodeA);
nodeA = nodeA.getNext();
}
else
{
mergedNode.setNext(nodeB);
nodeB = nodeB.getNext();
}
mergedNode = mergedNode.getNext();
}
if (nodeA != null)
{
mergedNode.setNext(nodeA);
}
if (nodeB != null)
{
mergedNode.setNext(nodeB);
}
return tempNode;
}
Node mergeList(Node h1, Node h2) {
if (h1 == null) return h2;
if (h2 == null) return h1;
Node head;
if (h1.data < h2.data) {
head = h1;
} else {
head = h2;
h2 = h1;
h1 = head;
}
while (h1.next != null && h2 != null) {
if (h1.next.data < h2.data) {
h1 = h1.next;
} else {
Node afterh2 = h2.next;
Node afterh1 = h1.next;
h1.next = h2;
h2.next = afterh1;
if (h2.next != null) {
h2 = afterh2;
}
}
}
return head;
}
This could be done without creating the extra node, with just an another Node reference passing to the parameters (Node temp).
private static Node mergeTwoLists(Node nodeList1, Node nodeList2, Node temp) {
if(nodeList1 == null) return nodeList2;
if(nodeList2 == null) return nodeList1;
if(nodeList1.data <= nodeList2.data){
temp = nodeList1;
temp.next = mergeTwoLists(nodeList1.next, nodeList2, temp);
}
else{
temp = nodeList2;
temp.next = mergeTwoLists(nodeList1, nodeList2.next, temp);
}
return temp;
}
I would like to share how i thought the solution... i saw the solution that involves recursion and they are pretty amazing, is the outcome of well functional and modular thinking. I really appreciate the sharing.
I would like to add that recursion won't work for big lits, the stack calls will overflow; so i decided to try the iterative approach... and this is what i get.
The code is pretty self explanatory, i added some inline comments to try to assure this.
If you don't get it, please notify me and i will improve the readability (perhaps i am having a misleading interpretation of my own code).
import java.util.Random;
public class Solution {
public static class Node<T extends Comparable<? super T>> implements Comparable<Node<T>> {
T data;
Node next;
#Override
public int compareTo(Node<T> otherNode) {
return data.compareTo(otherNode.data);
}
#Override
public String toString() {
return ((data != null) ? data.toString() + ((next != null) ? "," + next.toString() : "") : "null");
}
}
public static Node merge(Node firstLeft, Node firstRight) {
combine(firstLeft, firstRight);
return Comparision.perform(firstLeft, firstRight).min;
}
private static void combine(Node leftNode, Node rightNode) {
while (leftNode != null && rightNode != null) {
// get comparision data about "current pair of nodes being analized".
Comparision comparision = Comparision.perform(leftNode, rightNode);
// stores references to the next nodes
Node nextLeft = leftNode.next;
Node nextRight = rightNode.next;
// set the "next node" of the "minor node" between the "current pair of nodes being analized"...
// ...to be equals the minor node between the "major node" and "the next one of the minor node" of the former comparision.
comparision.min.next = Comparision.perform(comparision.max, comparision.min.next).min;
if (comparision.min == leftNode) {
leftNode = nextLeft;
} else {
rightNode = nextRight;
}
}
}
/** Stores references to two nodes viewed as one minimum and one maximum. The static factory method populates properly the instance being build */
private static class Comparision {
private final Node min;
private final Node max;
private Comparision(Node min, Node max) {
this.min = min;
this.max = max;
}
private static Comparision perform(Node a, Node b) {
Node min, max;
if (a != null && b != null) {
int comparision = a.compareTo(b);
if (comparision <= 0) {
min = a;
max = b;
} else {
min = b;
max = a;
}
} else {
max = null;
min = (a != null) ? a : b;
}
return new Comparision(min, max);
}
}
// Test example....
public static void main(String args[]) {
Node firstLeft = buildList(20);
Node firstRight = buildList(40);
Node firstBoth = merge(firstLeft, firstRight);
System.out.println(firstBoth);
}
// someone need to write something like this i guess...
public static Node buildList(int size) {
Random r = new Random();
Node<Integer> first = new Node<>();
first.data = 0;
first.next = null;
Node<Integer> current = first;
Integer last = first.data;
for (int i = 1; i < size; i++) {
Node<Integer> node = new Node<>();
node.data = last + r.nextInt(5);
last = node.data;
node.next = null;
current.next = node;
current = node;
}
return first;
}
}
A simple iterative solution.
Node* MergeLists(Node* A, Node* B)
{
//handling the corner cases
//if both lists are empty
if(!A && !B)
{
cout << "List is empty" << endl;
return 0;
}
//either of list is empty
else if(!A) return B;
else if(!B) return A;
else
{
Node* head = NULL;//this will be the head of the newList
Node* previous = NULL;//this will act as the
/* In this algorithm we will keep the
previous pointer that will point to the last node of the output list.
And, as given we have A & B as pointer to the given lists.
The algorithm will keep on going untill either one of the list become empty.
Inside of the while loop, it will divide the algorithm in two parts:
- First, if the head of the output list is not obtained yet
- Second, if head is already there then we will just compare the values and keep appending to the 'previous' pointer.
When one of the list become empty we will append the other 'left over' list to the output list.
*/
while(A && B)
{
if(!head)
{
if(A->data <= B->data)
{
head = A;//setting head of the output list to A
previous = A; //initializing previous
A = A->next;
}
else
{
head = B;//setting head of the output list to B
previous = B;//initializing previous
B = B->next;
}
}
else//when head is already set
{
if(A->data <= B->data)
{
if(previous->next != A)
previous->next = A;
A = A->next;//Moved A forward but keeping B at the same position
}
else
{
if(previous->next != B)
previous->next = B;
B = B->next; //Moved B forward but keeping A at the same position
}
previous = previous->next;//Moving the Output list pointer forward
}
}
//at the end either one of the list would finish
//and we have to append the other list to the output list
if(!A)
previous->next = B;
if(!B)
previous->next = A;
return head; //returning the head of the output list
}
}
I show below an iterative solution. A recursive solution would be more compact, but since we don't know the length of the lists, recursion runs the risk of stack overflow.
The basic idea is similar to the merge step in merge sort; we keep a pointer corresponding to each input list; at each iteration, we advance the pointer corresponding to the smaller element. However, there's one crucial difference where most people get tripped. In merge sort, since we use a result array, the next position to insert is always the index of the result array. For a linked list, we need to keep a pointer to the last element of the sorted list. The pointer may jump around from one input list to another depending on which one has the smaller element for the current iteration.
With that, the following code should be self-explanatory.
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
if (l1 == null) {
return l2;
}
if (l2 == null) {
return l1;
}
ListNode first = l1;
ListNode second = l2;
ListNode head = null;
ListNode last = null;
while (first != null && second != null) {
if (first.val < second.val) {
if (last != null) {
last.next = first;
}
last = first;
first = first.next;
} else {
if (last != null) {
last.next = second;
}
last = second;
second = second.next;
}
if (head == null) {
head = last;
}
}
if (first == null) {
last.next = second;
}
if (second == null) {
last.next = first;
}
return head;
}
Simple code in javascript to merge two linked list inplace.
function mergeLists(l1, l2) {
let head = new ListNode(0); //dummy
let curr = head;
while(l1 && l2) {
if(l2.val >= l1.val) {
curr.next = l1;
l1 = l1.next;
} else {
curr.next = l2;
l2=l2.next
}
curr = curr.next;
}
if(!l1){
curr.next=l2;
}
if(!l2){
curr.next=l1;
}
return head.next;
}
First of all understand the mean of "without creating any new extra nodes", As I understand it does not mean that I can not have pointer(s) which points to an existing node(s).
You can not achieve it without talking pointers to existing nodes, even if you use recursion to achieve the same, system will create pointers for you as call stacks. It is just like telling system to add pointers which you have avoided in your code.
Simple function to achieve the same with taking extra pointers:
typedef struct _LLNode{
int value;
struct _LLNode* next;
}LLNode;
LLNode* CombineSortedLists(LLNode* a,LLNode* b){
if(NULL == a){
return b;
}
if(NULL == b){
return a;
}
LLNode* root = NULL;
if(a->value < b->value){
root = a;
a = a->next;
}
else{
root = b;
b = b->next;
}
LLNode* curr = root;
while(1){
if(a->value < b->value){
curr->next = a;
curr = a;
a=a->next;
if(NULL == a){
curr->next = b;
break;
}
}
else{
curr->next = b;
curr = b;
b=b->next;
if(NULL == b){
curr->next = a;
break;
}
}
}
return root;
}
Node * merge_sort(Node *a, Node *b){
Node *result = NULL;
if(a == NULL)
return b;
else if(b == NULL)
return a;
/* For the first node, we would set the result to either a or b */
if(a->data <= b->data){
result = a;
/* Result's next will point to smaller one in lists
starting at a->next and b */
result->next = merge_sort(a->next,b);
}
else {
result = b;
/*Result's next will point to smaller one in lists
starting at a and b->next */
result->next = merge_sort(a,b->next);
}
return result;
}
Please refer to my blog post for http://www.algorithmsandme.com/2013/10/linked-list-merge-two-sorted-linked.html
Node MergeLists(Node list1, Node list2) {
//if list is null return other list
if(list1 == null)
{
return list2;
}
else if(list2 == null)
{
return list1;
}
else
{
Node head;
//Take head pointer to the node which has smaller first data node
if(list1.data < list2.data)
{
head = list1;
list1 = list1.next;
}
else
{
head = list2;
list2 = list2.next;
}
Node current = head;
//loop till both list are not pointing to null
while(list1 != null || list2 != null)
{
//if list1 is null, point rest of list2 by current pointer
if(list1 == null){
current.next = list2;
return head;
}
//if list2 is null, point rest of list1 by current pointer
else if(list2 == null){
current.next = list1;
return head;
}
//compare if list1 node data is smaller than list2 node data, list1 node will be
//pointed by current pointer
else if(list1.data < list2.data)
{
current.next = list1;
current = current.next;
list1 = list1.next;
}
else
{
current.next = list2;
current = current.next;
list2 = list2.next;
}
}
return head;
}
}
Here is a complete working example that uses the linked list implemented java.util. You can just copy paste the code below inside a main() method.
LinkedList<Integer> dList1 = new LinkedList<Integer>();
LinkedList<Integer> dList2 = new LinkedList<Integer>();
LinkedList<Integer> dListMerged = new LinkedList<Integer>();
dList1.addLast(1);
dList1.addLast(8);
dList1.addLast(12);
dList1.addLast(15);
dList1.addLast(85);
dList2.addLast(2);
dList2.addLast(3);
dList2.addLast(12);
dList2.addLast(24);
dList2.addLast(85);
dList2.addLast(185);
int i = 0;
int y = 0;
int dList1Size = dList1.size();
int dList2Size = dList2.size();
int list1Item = dList1.get(i);
int list2Item = dList2.get(y);
while (i < dList1Size || y < dList2Size) {
if (i < dList1Size) {
if (list1Item <= list2Item || y >= dList2Size) {
dListMerged.addLast(list1Item);
i++;
if (i < dList1Size) {
list1Item = dList1.get(i);
}
}
}
if (y < dList2Size) {
if (list2Item <= list1Item || i >= dList1Size) {
dListMerged.addLast(list2Item);
y++;
if (y < dList2Size) {
list2Item = dList2.get(y);
}
}
}
}
for(int x:dListMerged)
{
System.out.println(x);
}
Recursive way(variant of Stefan answer)
MergeList(Node nodeA, Node nodeB ){
if(nodeA==null){return nodeB};
if(nodeB==null){return nodeA};
if(nodeB.data<nodeA.data){
Node returnNode = MergeNode(nodeA,nodeB.next);
nodeB.next = returnNode;
retturn nodeB;
}else{
Node returnNode = MergeNode(nodeA.next,nodeB);
nodeA.next=returnNode;
return nodeA;
}
Consider below linked list to visualize this
2>4 list A
1>3 list B
Almost same answer(non recursive) as Stefan but with little more comments/meaningful variable name. Also covered double linked list in comments if someone is interested
Consider the example
5->10->15>21 // List1
2->3->6->20 //List2
Node MergeLists(List list1, List list2) {
if (list1 == null) return list2;
if (list2 == null) return list1;
if(list1.head.data>list2.head.data){
listB =list2; // loop over this list as its head is smaller
listA =list1;
} else {
listA =list2; // loop over this list
listB =list1;
}
listB.currentNode=listB.head;
listA.currentNode=listA.head;
while(listB.currentNode!=null){
if(listB.currentNode.data<listA.currentNode.data){
Node insertFromNode = listB.currentNode.prev;
Node startingNode = listA.currentNode;
Node temp = inserFromNode.next;
inserFromNode.next = startingNode;
startingNode.next=temp;
startingNode.next.prev= startingNode; // for doubly linked list
startingNode.prev=inserFromNode; // for doubly linked list
listB.currentNode= listB.currentNode.next;
listA.currentNode= listA.currentNode.next;
}
else
{
listB.currentNode= listB.currentNode.next;
}
}
My take on the question is as below:
Pseudocode:
Compare the two heads A and B.
If A <= B, then add A and move the head of A to the next node.
Similarly, if B < A, then add B and move the head of B to the next node B.
If both A and B are NULL then stop and return.
If either of them is NULL, then traverse the non null head till it becomes NULL.
Code:
public Node mergeLists(Node headA, Node headB) {
Node merge = null;
// If we have reached the end, then stop.
while (headA != null || headB != null) {
// if B is null then keep appending A, else check if value of A is lesser or equal than B
if (headB == null || (headA != null && headA.data <= headB.data)) {
// Add the new node, handle addition separately in a new method.
merge = add(merge, headA.data);
// Since A is <= B, Move head of A to next node
headA = headA.next;
// if A is null then keep appending B, else check if value of B is lesser than A
} else if (headA == null || (headB != null && headB.data < headA.data)) {
// Add the new node, handle addition separately in a new method.
merge = add(merge, headB.data);
// Since B is < A, Move head of B to next node
headB = headB.next;
}
}
return merge;
}
public Node add(Node head, int data) {
Node end = new Node(data);
if (head == null) {
return end;
}
Node curr = head;
while (curr.next != null) {
curr = curr.next;
}
curr.next = end;
return head;
}
/* Simple/Elegant Iterative approach in Java*/
private static LinkedList mergeLists(LinkedList list1, LinkedList list2) {
Node head1 = list1.start;
Node head2 = list2.start;
if (list1.size == 0)
return list2;
if (list2.size == 0)
return list1;
LinkedList mergeList = new LinkedList();
while (head1 != null && head2 != null) {
if (head1.getData() < head2.getData()) {
int data = head1.getData();
mergeList.insert(data);
head1 = head1.getNext();
} else {
int data = head2.getData();
mergeList.insert(data);
head2 = head2.getNext();
}
}
while (head1 != null) {
int data = head1.getData();
mergeList.insert(data);
head1 = head1.getNext();
}
while (head2 != null) {
int data = head2.getData();
mergeList.insert(data);
head2 = head2.getNext();
}
return mergeList;
}
/* Build-In singly LinkedList class in Java*/
class LinkedList {
Node start;
int size = 0;
void insert(int data) {
if (start == null)
start = new Node(data);
else {
Node temp = start;
while (temp.getNext() != null) {
temp = temp.getNext();
}
temp.setNext(new Node(data));
}
size++;
}
#Override
public String toString() {
String str = "";
Node temp=start;
while (temp != null) {
str += temp.getData() + "-->";
temp = temp.getNext();
}
return str;
}
}
LLNode *mergeSorted(LLNode *h1, LLNode *h2)
{
LLNode *h3=NULL;
LLNode *h3l;
if(h1==NULL && h2==NULL)
return NULL;
if(h1==NULL)
return h2;
if(h2==NULL)
return h1;
if(h1->data<h2->data)
{
h3=h1;
h1=h1->next;
}
else
{
h3=h2;
h2=h2->next;
}
LLNode *oh=h3;
while(h1!=NULL && h2!=NULL)
{
if(h1->data<h2->data)
{
h3->next=h1;
h3=h3->next;
h1=h1->next;
}
else
{
h3->next=h2;
h3=h3->next;
h2=h2->next;
}
}
if(h1==NULL)
h3->next=h2;
if(h2==NULL)
h3->next=h1;
return oh;
}
// Common code for insert at the end
private void insertEnd(int data) {
Node newNode = new Node(data);
if (head == null) {
newNode.next = head;
head = tail = newNode;
return;
}
Node tempNode = tail;
tempNode.next = newNode;
tail = newNode;
}
private void mergerTwoSortedListInAscOrder(Node tempNode1, Node tempNode2) {
if (tempNode1 == null && tempNode2 == null)
return;
if (tempNode1 == null) {
head3 = tempNode2;
return;
}
if (tempNode2 == null) {
head3 = tempNode1;
return;
}
while (tempNode1 != null && tempNode2 != null) {
if (tempNode1.mData < tempNode2.mData) {
insertEndForHead3(tempNode1.mData);
tempNode1 = tempNode1.next;
} else if (tempNode1.mData > tempNode2.mData) {
insertEndForHead3(tempNode2.mData);
tempNode2 = tempNode2.next;
} else {
insertEndForHead3(tempNode1.mData);
insertEndForHead3(tempNode2.mData);
tempNode1 = tempNode1.next;
tempNode2 = tempNode2.next;
}
}
if (tempNode1 != null) {
while (tempNode1 != null) {
insertEndForHead3(tempNode1.mData);
tempNode1 = tempNode1.next;
}
}
if (tempNode2 != null) {
while (tempNode2 != null) {
insertEndForHead3(tempNode2.mData);
tempNode2 = tempNode2.next;
}
}
}
:)GlbMP
public static Node merge(Node h1, Node h2) {
Node h3 = new Node(0);
Node current = h3;
boolean isH1Left = false;
boolean isH2Left = false;
while (h1 != null || h2 != null) {
if (h1.data <= h2.data) {
current.next = h1;
h1 = h1.next;
} else {
current.next = h2;
h2 = h2.next;
}
current = current.next;
if (h2 == null && h1 != null) {
isH1Left = true;
break;
}
if (h1 == null && h2 != null) {
isH2Left = true;
break;
}
}
if (isH1Left) {
while (h1 != null) {
current.next = h1;
current = current.next;
h1 = h1.next;
}
}
if (isH2Left) {
while (h2 != null) {
current.next = h2;
current = current.next;
h2 = h2.next;
}
}
h3 = h3.next;
return h3;
}
I created only one dummy node at the beginning to save myself many 'if' conditions.
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
ListNode list1Cursor = l1;
ListNode list2Cursor = l2;
ListNode currentNode = new ListNode(-1); // Dummy node
ListNode head = currentNode;
while (list1Cursor != null && list2Cursor != null)
{
if (list1Cursor.val < list2Cursor.val) {
currentNode.next = list1Cursor;
list1Cursor = list1Cursor.next;
currentNode = currentNode.next;
} else {
currentNode.next = list2Cursor;
list2Cursor = list2Cursor.next;
currentNode = currentNode.next;
}
}
// Complete the rest
while (list1Cursor != null) {
currentNode.next = list1Cursor;
currentNode = currentNode.next;
list1Cursor = list1Cursor.next;
}
while (list2Cursor != null) {
currentNode.next = list2Cursor;
currentNode = currentNode.next;
list2Cursor = list2Cursor.next;
}
return head.next;
}
public ListNode MergeTwoLists(ListNode l1, ListNode l2) {//c#
ListNode _destNode=null;//Merged List
ListNode _srcNode=null;
ListNode _resHead=null;
if(l1==null || l2==null){//for scenario l1 null or l2 null or both null
return l1??l2??null;
}
if(l1.val<=l2.val){
_destNode=l1;//finding the dest list
_srcNode=l2;
_resHead=l1;
}
else{
_destNode=l2;
_srcNode=l1;
_resHead=l2;
}
while(_destNode!=null && _srcNode!=null){
if(_destNode.val<=_srcNode.val && (_destNode.next==null ||_destNode.next.val>=_srcNode.val)) {
//appending the values to dest list , if the element from dest list is less than element from _srcNode
var _temp_l2_currentnode=_srcNode;
_srcNode=_srcNode.next;
var _temp_l1_nextnode=_destNode.next;
_destNode.next=_temp_l2_currentnode;
_temp_l2_currentnode.next=_temp_l1_nextnode;
_destNode=_destNode.next;
}
else{
_destNode=_destNode.next;
}
}
return _resHead;
}
private static Node mergeLists(Node L1, Node L2) {
Node P1 = L1.val < L2.val ? L1 : L2;
Node P2 = L1.val < L2.val ? L2 : L1;
Node BigListHead = P1;
Node tempNode = null;
while (P1 != null && P2 != null) {
if (P1.next != null && P1.next.val >P2.val) {
tempNode = P1.next;
P1.next = P2;
P1 = P2;
P2 = tempNode;
} else if(P1.next != null)
P1 = P1.next;
else {
P1.next = P2;
break;
}
}
return BigListHead;
}
void printLL(){
NodeLL cur = head;
if(cur.getNext() == null){
System.out.println("LL is emplty");
}else{
//System.out.println("printing Node");
while(cur.getNext() != null){
cur = cur.getNext();
System.out.print(cur.getData()+ " ");
}
}
System.out.println();
}
void mergeSortedList(NodeLL node1, NodeLL node2){
NodeLL cur1 = node1.getNext();
NodeLL cur2 = node2.getNext();
NodeLL cur = head;
if(cur1 == null){
cur = node2;
}
if(cur2 == null){
cur = node1;
}
while(cur1 != null && cur2 != null){
if(cur1.getData() <= cur2.getData()){
cur.setNext(cur1);
cur1 = cur1.getNext();
}
else{
cur.setNext(cur2);
cur2 = cur2.getNext();
}
cur = cur.getNext();
}
while(cur1 != null){
cur.setNext(cur1);
cur1 = cur1.getNext();
cur = cur.getNext();
}
while(cur2 != null){
cur.setNext(cur2);
cur2 = cur2.getNext();
cur = cur.getNext();
}
printLL();
}
Here is the code on how to merge two sorted linked lists headA and headB:
Node* MergeLists1(Node *headA, Node* headB)
{
Node *p = headA;
Node *q = headB;
Node *result = NULL;
Node *pp = NULL;
Node *qq = NULL;
Node *head = NULL;
int value1 = 0;
int value2 = 0;
if((headA == NULL) && (headB == NULL))
{
return NULL;
}
if(headA==NULL)
{
return headB;
}
else if(headB==NULL)
{
return headA;
}
else
{
while((p != NULL) || (q != NULL))
{
if((p != NULL) && (q != NULL))
{
int value1 = p->data;
int value2 = q->data;
if(value1 <= value2)
{
pp = p->next;
p->next = NULL;
if(result == NULL)
{
head = result = p;
}
else
{
result->next = p;
result = p;
}
p = pp;
}
else
{
qq = q->next;
q->next = NULL;
if(result == NULL)
{
head = result = q;
}
else
{
result->next = q;
result = q;
}
q = qq;
}
}
else
{
if(p != NULL)
{
pp = p->next;
p->next = NULL;
result->next = p;
result = p;
p = pp;
}
if(q != NULL)
{
qq = q->next;
q->next = NULL;
result->next = q;
result = q;
q = qq;
}
}
}
}
return head;
}

Nodes at a distance k in binary tree

You are given a function printKDistanceNodes which takes in a root node of a binary tree, a start node and an integer K. Complete the function to print the value of all the nodes (one-per-line) which are a K distance from the given start node in sorted order. Distance can be upwards or downwards.
private void printNodeAtN(Node root, Node start, int k) {
if (root != null) {
// calculate if the start is in left or right subtree - if start is
// root this variable is null
Boolean left = isLeft(root, start);
int depth = depth(root, start, 0);
if (depth == -1)
return;
printNodeDown(root, k);
if (root == start)
return;
if (left) {
if (depth > k) {
// print the nodes at depth-k level in left tree
printNode(depth - k - 1, root.left);
} else if (depth < k) {
// print the nodes at right tree level k-depth
printNode(k - depth - 1, root.right);
} else {
System.out.println(root.data);
}
} else {
// similar if the start is in right subtree
if (depth > k) {
// print the nodes at depth-k level in left tree
printNode(depth - k - 1, root.right);
} else if (depth < k) {
// print the nodes at right tree level k-depth
printNode(k - depth - 1, root.left);
} else {
System.out.println(root.data);
}
}
}
}
// print the nodes at depth - "level" from root
void printNode(int level, Node root) {
if (level == 0 && root != null) {
System.out.println(root.data);
} else {
printNode(level - 1, root.left);
printNode(level - 1, root.right);
}
}
// print the children of the start
void printNodeDown(Node start, int k) {
if (start != null) {
if (k == 0) {
System.out.println(start.data);
}
printNodeDown(start.left, k - 1);
printNodeDown(start.right, k - 1);
}
}
private int depth(Node root, Node node, int d) {
if (root == null)
return -1;
if (root != null && node == root) {
return d;
} else {
int left = depth(root.left, node, d + 1);
int right = depth(root.right, node, d + 1);
if (left > right)
return left;
else
return right;
}
}
There is at most one node at distance K which upwards - just start from the start node and move up along parents for K steps. Add this to a sorted data structure.
Then you need to add the downward nodes. To do that you can do a BFS with queue, where you store the depth together with the node when you insert it in the queue (the starting node is at level 0, it's children at level 1 and so on). Then when you pop the nodes if they are at level K add them to the sorted data structure. when you start poping nodes at level K+1 you can stop.
Finally print the nodes from the sorted data structure (they will be sorted).
EDIT: If there is no parent pointer:
Write a recursive function int Go(Node node), which returns the depth of the start node with respect to the passed in node and -1 if the subtree of node doesn't contain start. The function will find the K-th parent as a side effect. Pseudo code:
static Node KthParent = null;
static Node start = ...;
static int K = ...;
int Go(Node node) {
if (node == start) return 0;
intDepth = -1;
if(node.LeftChild != null) {
int leftDepth = Go(node.LeftChild);
if(leftDepth >= 0) intDepth = leftDepth+1;
}
if (intDepth < 0 && node.rightChild != null) {
int rightDepth = Go(node.RightChild);
if(rightDepth >= 0) intDepth = rightDepth+1;
}
if(intDepth == K) KthParent = node;
return intDepth;
}
private static int printNodeAtK(Node root, Node start, int k, boolean found){
if(root != null){
if(k == 0 && found){
System.out.println(root.data);
}
if(root==start || found == true){
int leftd = printNodeAtK(root.left, start, k-1, true);
int rightd = printNodeAtK(root.right,start,k-1,true);
return 1;
}else{
int leftd = printNodeAtK(root.left, start, k, false);
int rightd = printNodeAtK(root.right,start,k,false);
if(leftd == k || rightd == k){
System.out.println(root.data);
}
if(leftd != -1 && leftd > rightd){
return leftd+1;
}else if(rightd != -1 && rightd>leftd){
return rightd+1;
}else{
return -1;
}
}
}
return -1;
}
struct node{
int data;
node* left;
node* right;
bool printed;
};
void print_k_dist(node** root,node** p,int k,int kmax);
void reinit_printed(node **root);
void print_k_dist(node** root,node **p,int k,int kmax)
{
if(*p==NULL) return;
node* par=parent(root,p);
if(k<=kmax &&(*p)->printed==0)
{
cout<<(*p)->data<<" ";
(*p)->printed=1;
k++;
print_k_dist(root,&par,k,kmax);
print_k_dist(root,&(*p)->left,k,kmax);
print_k_dist(root,&(*p)->right,k,kmax);
}
else
return;
}
void reinit_printed(node **root)
{
if(*root==NULL) return;
else
{
(*root)->printed=0;
reinit_printed(&(*root)->left);
reinit_printed(&(*root)->right);
}
}
typedef struct node
{
int data;
struct node *left;
struct node *right;
}node;
void printkdistanceNodeDown(node *n, int k)
{
if(!n)
return ;
if(k==0)
{
printf("%d\n",n->data);
return;
}
printkdistanceNodeDown(n->left,k-1);
printkdistanceNodeDown(n->right,k-1);
}
void printkdistanceNodeDown_fromUp(node* target ,int *k)
{
if(!target)
return ;
if(*k==0)
{
printf("%d\n",target->data);
return;
}
else
{
int val=*k;
printkdistanceNodeDown(target,val-1);
}
}
int printkdistanceNodeUp(node* root, node* n , int k)
{
if(!root)
return 0;
if(root->data==n->data)
return 1;
int pl=printkdistanceNodeUp(root->left,n,k);
int pr=printkdistanceNodeUp(root->right,n,k);
if(pl )
{
k--;
if(k==0)
printf("%d\n",root->data);
else
{
printkdistanceNodeDown_fromUp(root->right,k);
printkdistanceNodeDown_fromUp(root->left,k-1);
}
return 1;
}
if(pr )
{
k--;
if(k==0)
printf("%d\n",root->data);
else
{
printkdistanceNodeDown_fromUp(root->left,k);
printkdistanceNodeDown_fromUp(root->right,k-1);
}
return 1;
}
return 0;
}
void printkdistanceNode(node* root, node* n , int k )
{
if(!root)
return ;
int val=k;
printkdistanceNodeUp(root,n,k);
printkdistanceNodeDown(n,val);
}
caller function: printkdistanceNode(root,n,k);
The output will print all the nodes at a distance k from given node upward and downward.
Here in this code PrintNodesAtKDistance will first try to find the required node.
if(root.value == requiredNode)
When we find the desired node we print all the child nodes at the distance K from this node.
Now our task is to print all nodes which are in other branches(Go up and print). We return -1 till we didn't find our desired node. As we get our desired node we get lPath or rPath >=0 . Now we have to print all nodes which are at distance (lPath/rPath) -1
public void PrintNodes(Node Root, int requiredNode, int iDistance)
{
PrintNodesAtKDistance(Root, requiredNode, iDistance);
}
public int PrintNodesAtKDistance(Node root, int requiredNode, int iDistance)
{
if ((root == null) || (iDistance < 0))
return -1;
int lPath = -1, rPath = -1;
if(root.value == requiredNode)
{
PrintChildNodes(root, iDistance);
return iDistance - 1;
}
lPath = PrintNodesAtKDistance(root.left, requiredNode, iDistance);
rPath = PrintNodesAtKDistance(root.right, requiredNode, iDistance);
if (lPath > 0)
{
PrintChildNodes(root.right, lPath - 1);
return lPath - 1;
}
else if(lPath == 0)
{
Debug.WriteLine(root.value);
}
if(rPath > 0)
{
PrintChildNodes(root.left, rPath - 1);
return rPath - 1;
}
else if (rPath == 0)
{
Debug.WriteLine(root.value);
}
return -1;
}
public void PrintChildNodes(Node aNode, int iDistance)
{
if (aNode == null)
return;
if(iDistance == 0)
{
Debug.WriteLine(aNode.value);
}
PrintChildNodes(aNode.left, iDistance - 1);
PrintChildNodes(aNode.right, iDistance - 1);
}
Here is complete java program . Inspired from geeksforgeeks Algorith
// Java program to print all nodes at a distance k from given node
class BinaryTreePrintKDistance {
Node root;
/*
* Recursive function to print all the nodes at distance k in tree (or
* subtree) rooted with given root.
*/
void printKDistanceForDescendant(Node targetNode, int currentDist,
int inputDist) {
// Base Case
if (targetNode == null || currentDist > inputDist)
return;
// If we reach a k distant node, print it
if (currentDist == inputDist) {
System.out.print(targetNode.data);
System.out.println("");
return;
}
++currentDist;
// Recur for left and right subtrees
printKDistanceForDescendant(targetNode.left, currentDist, inputDist);
printKDistanceForDescendant(targetNode.right, currentDist, inputDist);
}
public int printkdistance(Node targetNode, Node currentNode,
int inputDist) {
if (currentNode == null) {
return -1;
}
if (targetNode.data == currentNode.data) {
printKDistanceForDescendant(currentNode, 0, inputDist);
return 0;
}
int ld = printkdistance(targetNode, currentNode.left, inputDist);
if (ld != -1) {
if (ld + 1 == inputDist) {
System.out.println(currentNode.data);
} else {
printKDistanceForDescendant(currentNode.right, 0, inputDist
- ld - 2);
}
return ld + 1;
}
int rd = printkdistance(targetNode, currentNode.right, inputDist);
if (rd != -1) {
if (rd + 1 == inputDist) {
System.out.println(currentNode.data);
} else {
printKDistanceForDescendant(currentNode.left, 0, inputDist - rd
- 2);
}
return rd + 1;
}
return -1;
}
// Driver program to test the above functions
#SuppressWarnings("unchecked")
public static void main(String args[]) {
BinaryTreePrintKDistance tree = new BinaryTreePrintKDistance();
/* Let us construct the tree shown in above diagram */
tree.root = new Node(20);
tree.root.left = new Node(8);
tree.root.right = new Node(22);
tree.root.left.left = new Node(4);
tree.root.left.right = new Node(12);
tree.root.left.right.left = new Node(10);
tree.root.left.right.right = new Node(14);
Node target = tree.root.left;
tree.printkdistance(target, tree.root, 2);
}
static class Node<T> {
public Node left;
public Node right;
public T data;
Node(T data) {
this.data = data;
}
}
}

Resources