Find the least common parent in a binary tree? - algorithm

This question might have been asked by a lot of guys but, it is kinda different. We have a binary tree. And you are given two nodes p & q. We have to find the least common parent. But you dont have root node pointer which points to the root. You are provided with two inbuilt functions which are:
1) BOOL same(node *p, node *q); -> returns true if the nodes are same or else false.
2) node* parentNode(node *c); -> returns a node which is the parent of the current node.
If the node c is actually root then parentNode function will return you with aNULL value.
Using the functions we have to find the least common parent of the tree.

Step1: Using parentNode function find the distance d1 of the node p from root. similarly find distance d2 of node q from the root. (say, d2 comes out ot be greater than d1)
Step 2: Move the farther node(whose ever d-value was greater) pointer d2-d1 steps towards root.
Step3: Simultaneously move pointers p and q towards root till they point to same node and return that node.
Basically it will be like finding the merge point of two linked-lists. Check the below link:
Check if two linked lists merge. If so, where?
Time complexity: O(N)
Your code would look somewhat along the lines:
node* LCP(node* p, node *q){
int d1=0, d2=0;
for(node* t= p; t; t = parentNode(p), ++d1);
for(node* t= q; t; t = parentNode(q), ++d2);
if(d1>d2){
swap(d1, d2);
swap(p, q);
}
for(int i=0; i<(d2-d1); ++i)
q = parentNode(q);
if( same(p, q)){
return parentNode(p);
}
while( !same(p, q)){
p = parentNode(p);
q = parentNode(q);
}
return p;
}

Assuming C++:
node* leastCommonParent(node *p, node *q)
{
node *pParent = parentNode(p);
while(pParent != 0)
{
node *qParent = parentNode(q);
while(qParent != 0)
{
if (0 == same(pParent, qParent))
return pParent;
qParent = parentNode(qParent);
}
pParent = parentNode(pParent);
}
return 0;
}
UPDATE: A version without explicitly declared variables using recursion follows. I'm sure it can be improved and would probably never use it in production code in the current form.
node* qParent(node *p, node *q)
{
if (p == 0 || q == 0)
return 0;
if (same(p, q) == 0)
return p;
return qParent(p, q->parent);
}
node* pParent(node *p, node *q)
{
return qParent(p, q) ? qParent(p, q) : pParent(p->parent, q);
}
node * result = pParent(p, q);

Related

Balanced tree with constant-time successor and predecessor given node pointers?

I was asked this question, which I personally find hard:
Create a data structure that can:
Insert elements,
Remove elements,
Search Elements,
In time O(log n)
In addition,
It should have the following two functions which work in time O(1):
next(x):
given a pointer to the node of value x, return a pointer to the node with the smallest bigger value than x.
previous(x)
given a pointer to the node of value x, return a pointer to the node with the biggest smallest value than x.
If each node contains a pointer to its successor and a pointer to its predecessor, or equivalently - if you maintain both a doublely linked list and a tree, where each node in the tree points to its equivalent node in the list and vice versa - you'll get want you want. Updating the list on insert/delete is O(1) (after locating the closest node in the tree). Searching is performed on the tree. Succesor / predecessor are performed on the list.
#RogerLindsjö's idea from the comments is a good one. Essentially, keep a regular, balanced BST, then thread a doubly-linked list through the nodes keeping them in sorted order. That way, given a pointer to a node in the tree, you can find the largest value smaller than it or the smallest value greater than it simply by following the next or previous pointers in each node.
You can maintain this list through insertions and deletions without changing the overall runtime of an insert or delete. For example, here's how you might do an insertion of an element x:
Do a standard BST successor query to find the smallest value larger than x in the tree, and a standard BST predecessor query to find the largest value smaller than x in the tree. Each search takes time O(log n) to complete.
Do a regular BST insertion to insert x. Then, set its next and previous pointers to the two elements you found in the previous step, and update those nodes to point to your new node x. This also takes time O(log n).
The total time for the insertion is then O(log n), matching what a balanced tree can provide.
I'll leave it to you to figure out deletion, which can similarly maintain the linked list pointers without changing the overall cost of the operation.
Like most self-balancing trees, a B+ tree provides Insert, Remove, and Search operations with O(log n) time complexity.
In a B+ tree, a leaf node hosts multiple keys in an array, so the concept of "pointer to node with value x" does not really exist, but we could define it as the tuple (pointer, index), where the pointer is to the node, and index is the slot in which x is stored.
In a B+ tree the nodes at the bottom level contain all the keys, and these nodes are often linked, usually only in forward direction (i.e. to the right), but it is quite possible to also maintain a link in the opposite direction, without increasing the time complexity of the above operations.
With those two remarks in mind, prev-next operations can clearly be executed in O(1) time.
If your elements are integers you can use y-fast trie that supports all mentioned operations in O(log log m). Also, almost any search tree will allow doing these operations in O(log n) time by just going first up and then down (it will require a lot of concentration to not mess up with the order, though)
You can use two pointers in the node of the balanced tree, namely pred - predecessor and succ - successor. While inserting a node into the tree or deleting a node from the tree you just have to do some pointer manipulations, equivalent to those in doubly linked list.
The time complexity will be O(1) in each case.
I have provided my implementation for the insertion and deletion in case of AVL Tree below. The complete implementation is available here.
Structure of node
template<typename T>
struct node {
T key;
int freq;
node<T> *left;
node<T> *right;
node<T> *pred;
node<T> *succ;
int height;
node(T key): key(key), freq(1),
left(nullptr),
right(nullptr),
height(1),
pred(nullptr),
succ(nullptr) {}
};
insert function
node<T> *insert(node<T> *root, T key) {
if(root == nullptr)
return new node<T>(key);
if(!comp(key, root->key) && !comp(root->key, key)) {
++root->freq;
} else if(comp(key, root->key)) {
if(root->left == nullptr) {
node<T> *new_node = new node<T>(key);
/* set the pred and succ ptrs*/
new_node->succ = root;
new_node->pred = root->pred;
if(root->pred != nullptr)
root->pred->succ = new_node;
root->pred = new_node;
root->left = new_node;
} else {
root->left = insert(root->left, key);
}
} else {
if(root->right == nullptr) {
node<T> *new_node = new node<T>(key);
/* set the pred and succ ptrs*/
new_node->pred = root;
new_node->succ = root->succ;
if(root->succ != nullptr)
root->succ->pred = new_node;
root->succ = new_node;
root->right = new_node;
} else {
root->right = insert(root->right, key);
}
}
root->height = max(height(root->left), height(root->right)) + 1;
int bf = balance_factor(root);
node<T> *left = root->left;
node<T> *right = root->right;
if(bf > 1 && left != nullptr && comp(key, left->key)) {
/*
node was inserted at left subtree of left child
fix - right rotate root
*/
root = rotate_right(root);
} else if(bf > 1 && left != nullptr && comp(left->key, key)) {
/*
node was inserted at right subtree of left child
fix - left rotate left child
- right rotate root
*/
root->left = rotate_left(root->left);
root = rotate_right(root);
} else if(bf < -1 && right != nullptr && comp(right->key, key)) {
/*
node was inserted at right subtree of right child
fix - left rotate root
*/
root = rotate_left(root);
} else if(bf < -1 && right != nullptr && comp(key, right->key)) {
/*
node was inserted at left subtree of right child
fix - right rotate right child
- left roatate root
*/
root->right = rotate_right(root->right);
root = rotate_left(root);
}
return root;
}
erase function
node<T> *erase(node<T> *root, T key) {
if(root == nullptr)
return nullptr;
if(comp(key, root->key)) {
root->left = erase(root->left, key);
} else if(comp(root->key, key)) {
root->right = erase(root->right, key);
} else {
if(root->left == nullptr || root->right == nullptr) {
/* update pred and succ ptrs */
if(root->succ != nullptr)
root->succ->pred = root->pred;
if(root->pred != nullptr)
root->pred->succ = root->succ;
if(root->right == nullptr) {
node<T> *temp = root->left;
delete root;
root = temp;
} else {
node<T> *temp = root->right;
delete root;
root = temp;
}
} else {
// node<T> *succ = minVal(root->right);
root->key = root->succ->key;
root->freq = root->succ->freq;
root->right = erase(root->right, root->succ->key);
}
}
if(root != nullptr) {
root->height = max(height(root->left), height(root->right)) + 1;
int bf_root = balance_factor(root);
if(bf_root > 1) {
/*
case R
*/
int bf_left = balance_factor(root->left);
if(bf_left >= 0) {
/*
case R0 and R1
*/
root = rotate_right(root);
} else {
/*
case R -1
*/
root->left = rotate_left(root->left);
root = rotate_right(root);
}
} else if(bf_root < -1) {
/*
Case L
*/
int bf_right = balance_factor(root->right);
if(bf_right <= 0) {
/*
case L0 and L -1
*/
root = rotate_left(root);
} else {
/*
case L1
*/
root->right = rotate_right(root->right);
root = rotate_left(root);
}
}
}
return root;
}

How to calculate a height of a tree

I am trying to learn DSA and got stuck on one problem.
How to calculate height of a tree. I mean normal tree, not any specific implementation of tree like BT or BST.
I have tried google but seems everyone is talking about Binary tree and nothing is available for normal tree.
Can anyone help me to redirect to some page or articles to calculate height of a tree.
Lets say a typical node in your tree is represented as Java class.
class Node{
Entry entry;
ArrayList<Node> children;
Node(Entry entry, ArrayList<Node> children){
this.entry = entry;
this.children = children;
}
ArrayList<Node> getChildren(){
return children;
}
}
Then a simple Height Function can be -
int getHeight(Node node){
if(node == null){
return 0;
}else if(node.getChildren() == null){
return 1;
} else{
int childrenMaxHeight = 0;
for(Node n : node.getChildren()){
childrenMaxHeight = Math.max(childrenMaxHeight, getHeight(n));
}
return 1 + childrenMaxHeight;
}
}
Then you just need to call this function passing the root of tree as argument. Since it traverse all the node exactly once, the run time is O(n).
1. If height of leaf node is considered as 0 / Or height is measured depending on number of edges in longest path from root to leaf :
int maxHeight(treeNode<int>* root){
if(root == NULL)
return -1; // -1 beacuse since a leaf node is 0 then NULL node should be -1
int h=0;
for(int i=0;i<root->childNodes.size();i++){
temp+=maxHeight(root->childNodes[i]);
if(temp>h){
h=temp;
}
}
return h+1;
}
2. If height of root node is considered 1:
int maxHeight(treeNode<int>* root){
if(root == NULL)
return 0;
int h=0;
for(int i=0;i<root->childNodes.size();i++){
temp+=maxHeight(root->childNodes[i]);
if(temp>h){
h=temp;
}
}
return h+1;
Above Code is based upon following class :
template <typename T>
class treeNode{
public:
T data;
vector<treeNode<T>*> childNodes; // vector for storing pointer to child treenode
creating Tree node
treeNode(T data){
this->data = data;
}
};
In case of 'normal tree' you can recursively calculate the height of tree in similar fashion to a binary tree but here you will have to consider all children at a node instead of just two.
To find a tree height a BFS iteration will work fine.
Edited form Wikipedia:
Breadth-First-Search(Graph, root):
create empty set S
create empty queues Q1, Q2
root.parent = NIL
height = -1
Q1.enqueue(root)
while Q1 is not empty:
height = height + 1
switch Q1 and Q2
while Q2 is not empty:
for each node n that is adjacent to current:
if n is not in S:
add n to S
n.parent = current
Q1.enqueue(n)
You can see that adding another queue allows me to know what level of the tree.
It iterates for each level, and for each mode in that level.
This is a discursion way to do it (opposite of recursive). So you don't have to worry about that too.
Run time is O(|V|+ |E|).

How to construct a binary tree using a level order traversal sequence

How to construct a binary tree using a level order traversal sequence, for example from sequence {1,2,3,#,#,4,#,#,5}, we can construct a binary tree like this:
1
/ \
2 3
/
4
\
5
where '#' signifies a path terminator where no node exists below.
Finally I implement Pham Trung's algorithm by c++
struct TreeNode
{
TreeNode *left;
TreeNode *right;
int val;
TreeNode(int x): left(NULL), right(NULL), val(x) {}
};
TreeNode *build_tree(char nodes[], int n)
{
TreeNode *root = new TreeNode(nodes[0] - '0');
queue<TreeNode*> q;
bool is_left = true;
TreeNode *cur = NULL;
q.push(root);
for (int i = 1; i < n; i++) {
TreeNode *node = NULL;
if (nodes[i] != '#') {
node = new TreeNode(nodes[i] - '0');
q.push(node);
}
if (is_left) {
cur = q.front();
q.pop();
cur->left = node;
is_left = false;
} else {
cur->right = node;
is_left = true;
}
}
return root;
}
Assume using array int[]data with 0-based index, we have a simple function to get children:
Left child
int getLeftChild(int index){
if(index*2 + 1 >= data.length)
return -1;// -1 Means out of bound
return data[(index*2) + 1];
}
Right child
int getRightChild(int index){
if(index*2 + 2 >= data.length)
return -1;// -1 Means out of bound
return data[(index*2) + 2];
}
Edit:
Ok, so by maintaining a queue, we can build this binary tree.
We use a queue to maintain those nodes that are not yet processed.
Using a variable count to keep track of the number of children added for the current node.
First, create a root node, assign it as the current node.
So starting from index 1 (index 0 is the root), as the count is 0, we add this node as left child of the current node.
Increase count. If this node is not '#', add it to the queue.
Moving to the next index, the count is 1, so we add this as right child of current node, reset count to 0 and update current node (by assigning the current node as the first element in the queue). If this node is not '#', add it to the queue.
int count = 0;
Queue q = new Queue();
q.add(new Node(data[0]);
Node cur = null;
for(int i = 1; i < data.length; i++){
Node node = new Node(data[i]);
if(count == 0){
cur = q.dequeue();
}
if(count==0){
count++;
cur.leftChild = node;
}else {
count = 0;
cur.rightChild = node;
}
if(data[i] != '#'){
q.enqueue(node);
}
}
class Node{
int data;
Node leftChild, rightChild;
}
Note: this should only work for a binary tree and not BST.
we can build this binary tree from level order traversal by maintaining a queue. Queue is used to maintain those nodes that are not yet processed.
Using a variable count(index variable) to keep track of the number of children added for the current node.
First, create a root node, assign it as the current node. So starting from index 1,
index value is 1 means, we will add the next value as left node.
index value is 2 means we will add the next value as right node and index value 2 means that we have added left and right node, then do the same for the remaining nodes.
if arr value is -1
3.a. if index value is 1,i.e., there is no left node then change the index variable to add right node.
3.b. if index value is 2, i.e, there is no right node then we have repeat this step for the remaining.
static class Node{
int data;
Node left;
Node right;
Node(int d){
data=d;
left=null;
right=null;
}
}
public static Node constBT(int arr[],int n){
Node root=null;
Node curr=null;
int index=0;
Queue<Node> q=new LinkedList<>();
for(int i=0;i<n;i++){
if(root==null){
root=new Node(arr[i]);
q.add(root);
curr=q.peek();
index=1;
}else{
if(arr[i]==-1){
if(index==1)
index=2;
else{
q.remove();
curr=q.peek();
index=1;
}
}
else if(index==1){
curr.left=new Node(arr[i]);
q.add(curr.left);
index=2;
}else if(index==2){
curr.right=new Node(arr[i]);
q.add(curr.right);
q.remove();
curr=q.peek();
index=1;
}
}
}
return root;
}
My approach is similar to Pham Trung yet intutive. We would maintain an array of Nodes of given data instead of using a queue. We would do reverse engineering on BFS using queue. because BFS for a tree is basically its Level Order Traversal (LOT).
It is important to note that we should have the NULL childs of an node for the LOT to be unique and the reconstruction of Tree from LOT to be possible.
In this case LOT : 1,2,3,-1,-1,4,-1,-1,5
where I have used -1 instead of '#' to represent NULLs
And Tree is
1
/ \
2 3
/ \ /
-1 -1 4
/ \
-1 5
Here, we can easily see that when 1 is popped from the BFS queue, it pushed its left child
(2) and right child (3) in the queue. Similary, for 2 it pushed -1 (NULL) for both of its children. And the process is continued.
So, we can follow the following pseudo code to generate the tree rooted at LOT[0]
j = 1
For every node in LOT:
if n<=j: break
if node != NULL:
make LOT[j] left child of node
if n<=j+1: break
make LOT[j+1] right child of node
j <- j+2
Finally, C++ code for the same
Class Declaration and Preorder traversal
class Node{
public:
int val;
Node* lft, *rgt;
Node(int x ):val(x) {lft=rgt=nullptr;}
};
void preorder(Node* root) {
if(!root) return;
cout<<root->val<<" ";
preorder(root->lft);
preorder(root->rgt);
}
Restoring Tree from LOT Logic
int main(){
int arr[] = {1,2,3,-1,-1,4,-1,-1,5};
int n = sizeof(arr)/sizeof(int);
Node* brr[n];
for(int i=0;i<n;i++) {
if(arr[i]==-1) brr[i] = nullptr;
else brr[i] = new Node(arr[i]);
}
for(int i=0,j=1;j<n;i++) {
if(!brr[i]) continue;
brr[i]->lft = brr[j++];
if(j<n) brr[i]->rgt = brr[j++];
}
preorder(brr[0]);
}
Output: 1 2 3 4 5

Binary tree level order traversal

Three types of tree traversals are inorder, preorder, and post order.
A fourth, less often used, traversal is level-order traversal. In a
level-order traveresal, all nodes at depth "d" are processed before
any node at depth d + 1. Level-order traversal differs from the other
traversals in that it is not done recursively; a queue is used,
instead of the implied stack of recursion.
My questions on above text snippet are
Why level order traversals are not done recursively?
How queue is used in level order traversal? Request clarification with Pseudo code will be helpful.
Thanks!
Level order traversal is actually a BFS, which is not recursive by nature. It uses Queue instead of Stack to hold the next vertices that should be opened. The reason for it is in this traversal, you want to open the nodes in a FIFO order, instead of a LIFO order, obtained by recursion
as I mentioned, the level order is actually a BFS, and its [BFS] pseudo code [taken from wikipedia] is:
1 procedure BFS(Graph,source):
2 create a queue Q
3 enqueue source onto Q
4 mark source
5 while Q is not empty:
6 dequeue an item from Q into v
7 for each edge e incident on v in Graph:
8 let w be the other end of e
9 if w is not marked:
10 mark w
11 enqueue w onto Q
(*) in a tree, marking the vertices is not needed, since you cannot get to the same node in 2 different paths.
void levelorder(Node *n)
{ queue < Node * >q;
q.push(n);
while(!q.empty())
{
Node *node = q.front();
cout<<node->value;
q.pop();
if(node->left != NULL)
q.push(node->left);
if (node->right != NULL)
q.push(node->right);
}
}
Instead of a queue, I used a map to solve this. Take a look, if you are interested. As I do a postorder traversal, I maintain the depth at which each node is positioned and use this depth as the key in a map to collect values in the same level
class Solution {
public:
map<int, vector<int> > levelValues;
void recursivePrint(TreeNode *root, int depth){
if(root == NULL)
return;
if(levelValues.count(root->val) == 0)
levelValues.insert(make_pair(depth, vector<int>()));
levelValues[depth].push_back(root->val);
recursivePrint(root->left, depth+1);
recursivePrint(root->right, depth+1);
}
vector<vector<int> > levelOrder(TreeNode *root) {
recursivePrint(root, 1);
vector<vector<int> > result;
for(map<int,vector<int> >::iterator it = levelValues.begin(); it!= levelValues.end(); ++it){
result.push_back(it->second);
}
return result;
}
};
The entire solution can be found here - http://ideone.com/zFMGKU
The solution returns a vector of vectors with each inner vector containing the elements in the tree in the correct order.
you can try solving it here - https://oj.leetcode.com/problems/binary-tree-level-order-traversal/
And, as you can see, we can also do this recursively in the same time and space complexity as the queue solution!
My questions on above text snippet are
Why level order traversals are not done recursively?
How queue is used in level order traversal? Request clarification with Pseudo code will be helpful.
I think it'd actually be easier to start with the second question. Once you understand the answer to the second question, you'll be better prepared to understand the answer to the first.
How level order traversal works
I think the best way to understand how level order traversal works is to go through the execution step by step, so let's do that.
We have a tree.
We want to traverse it level by level.
So, the order that we'd visit the nodes would be A B C D E F G.
To do this, we use a queue. Remember, queues are first in, first out (FIFO). I like to imagine that the nodes are waiting in line to be processed by an attendant.
Let's start by putting the first node A into the queue.
Ok. Buckle up. The setup is over. We're about to start diving in.
The first step is to take A out of the queue so it can be processed. But wait! Before we do so, let's put A's children, B and C, into the queue also.
Note: A isn't actually in the queue anymore at this point. I grayed it out to try to communicate this. If I removed it completely from the diagram, it'd make it harder to visualize what's happening later on in the story.
Note: A is being processed by the attendant at the desk in the diagram. In real life, processing a node can mean a lot of things. Using it to compute a sum, send an SMS, log to the console, etc, etc. Going off the metaphor in my diagram, you can tell the attendant how you want them to process the node.
Now we move on to the node that is next in line. In this case, B.
We do the same thing that we did with A: 1) add the children to the line, and 2) process the node.
Hey, check it out! It looks like what we're doing here is going to get us that level order traversal that we were looking for! Let's prove this to ourselves by continuing the step through.
Once we finish with B, C is next in line. We place C's children at the back of the line, and then process C.
Now let's see what happens next. D is next in line. D doesn't have any children, so we don't place anything at the back of the line. We just process D.
And then it's the same thing for E, F, and G.
Why it's not done recursively
Imagine what would happen if we used a stack instead of a queue. Let's rewind to the point where we had just visited A.
Here's how it'd look if we were using a stack.
Now, instead of going "in order", this new attendant likes to serve the most recent clients first, not the ones who have been waiting the longest. So C is who is up next, not B.
Here's where the key point is. Where the stack starts to cause a different processing order than we had with the queue.
Like before, we add C's children and then process C. We're just adding them to a stack instead of a queue this time.
Now, what's next? This new attendant likes to serve the most recent clients first (ie. we're using a stack), so G is up next.
I'll stop the execution here. The point is that something as simple as replacing the queue with a stack actually gives us a totally different execution order. I'd encourage you to finish the step through though.
You might be thinking: "Ok... but the question asked about recursion. What does this have to do with recursion?" Well, when you use recursion, something sneaky is going on. You never did anything with a stack data structure like s = new Stack(). However, the runtime uses the call stack. This ends up being conceptually similar to what I did above, and thus doesn't give us that A B C D E F G ordering we were looking for from level order traversal.
https://github.com/arun2pratap/data-structure/blob/master/src/main/java/com/ds/tree/binarytree/BinaryTree.java
for complete can look out for the above link.
public void levelOrderTreeTraversal(List<Node<T>> nodes){
if(nodes == null || nodes.isEmpty()){
return;
}
List<Node<T>> levelNodes = new ArrayList<>();
nodes.stream().forEach(node -> {
if(node != null) {
System.out.print(" " + node.value);
levelNodes.add(node.left);
levelNodes.add(node.right);
}
});
System.out.println("");
levelOrderTreeTraversal(levelNodes);
}
Also can check out
http://www.geeksforgeeks.org/
here you will find Almost all Data Structure related answers.
Level order traversal implemented by queue
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
def levelOrder(root: TreeNode) -> List[List[int]]:
res = [] # store the node value
queue = [root]
while queue:
node = queue.pop()
# visit the node
res.append(node.val)
if node.left:
queue.insert(0, node.left)
if node.right:
queue.insert(0, node.right)
return res
Recursive implementation is also possible. However, it needs to know the max depth of the root in advance.
def levelOrder(root: TreeNode) -> List[int]:
res = []
max_depth = maxDepth(root)
for i in range(max_depth):
# level start from 0 to max_depth-1
visitLevel(root, i, action)
return res
def visitLevel(root:TreeNode, level:int, res: List):
if not root:
return
if level==0:
res.append(node.val)
else:
self.visitLevel(root.left, level-1, res)
self.visitLevel(root.right, level-1, res)
def maxDepth(root: TreeNode) -> int:
if not root:
return 0
if not root.left and not root.right:
return 1
return max([ maxDepth(root.left), maxDepth(root.right)]) + 1
For your point 1) we can use Java below code for level order traversal in recursive order, we have not used any library function for tree, all are user defined tree and tree specific functions -
class Node
{
int data;
Node left, right;
public Node(int item)
{
data = item;
left = right = null;
}
boolean isLeaf() { return left == null ? right == null : false; }
}
public class BinaryTree {
Node root;
Queue<Node> nodeQueue = new ConcurrentLinkedDeque<>();
public BinaryTree() {
root = null;
}
public static void main(String args[]) {
BinaryTree tree = new BinaryTree();
tree.root = new Node(1);
tree.root.left = new Node(2);
tree.root.right = new Node(3);
tree.root.left.left = new Node(4);
tree.root.left.right = new Node(5);
tree.root.right.left = new Node(6);
tree.root.right.right = new Node(7);
tree.root.right.left.left = new Node(8);
tree.root.right.left.right = new Node(9);
tree.printLevelOrder();
}
/*Level order traversal*/
void printLevelOrder() {
int h = height(root);
int i;
for (i = 1; i <= h; i++)
printGivenLevel(root, i);
System.out.println("\n");
}
void printGivenLevel(Node root, int level) {
if (root == null)
return;
if (level == 1)
System.out.print(root.data + " ");
else if (level > 1) {
printGivenLevel(root.left, level - 1);
printGivenLevel(root.right, level - 1);
}
}
/*Height of Binary tree*/
int height(Node root) {
if (root == null)
return 0;
else {
int lHeight = height(root.left);
int rHeight = height(root.right);
if (lHeight > rHeight)
return (lHeight + 1);
else return (rHeight + 1);
}
}
}
For your point 2) If you want to use non recursive function then you can use queue as below function-
public void levelOrder_traversal_nrec(Node node){
System.out.println("Level order traversal !!! ");
if(node == null){
System.out.println("Tree is empty");
return;
}
nodeQueue.add(node);
while (!nodeQueue.isEmpty()){
node = nodeQueue.remove();
System.out.printf("%s ",node.data);
if(node.left !=null)
nodeQueue.add(node.left);
if (node.right !=null)
nodeQueue.add(node.right);
}
System.out.println("\n");
}
Recursive Solution in C++
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
vector<vector<int>> levels;
void helper(TreeNode* node,int level)
{
if(levels.size() == level) levels.push_back({});
levels[level].push_back(node->val);
if(node->left)
helper(node->left,level+1);
if(node->right)
helper(node->right,level+1);
}
vector<vector<int>> levelOrder(TreeNode* root) {
if(!root) return levels;
helper(root,0);
return levels;
}
};
We can use queue to solve this problem in less time complexity. Here is the solution of level order traversal suing Java.
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> levelOrderTraversal = new ArrayList<List<Integer>>();
List<Integer> currentLevel = new ArrayList<Integer>();
Queue<TreeNode> queue = new LinkedList<TreeNode>();
if(root != null)
{
queue.add(root);
queue.add(null);
}
while(!queue.isEmpty())
{
TreeNode queueRoot = queue.poll();
if(queueRoot != null)
{
currentLevel.add(queueRoot.val);
if(queueRoot.left != null)
{
queue.add(queueRoot.left);
}
if(queueRoot.right != null)
{
queue.add(queueRoot.right);
}
}
else
{
levelOrderTraversal.add(currentLevel);
if(!queue.isEmpty())
{
currentLevel = new ArrayList<Integer>();
queue.add(null);
}
}
}
return levelOrderTraversal;
}
}

How to count the number of right children in a binary tree?

How to count the number of right children in a binary tree?
This means that I only want the children marked as right.
Ex.
(Left | Right)
F(Root)
G | H
T U | I J
The right children would be U,H,and J.
What would be the algorithm to find these.
int count(Tree *r){
if(r == NULL) return 0;
int num_l=0, num_r=0;
if(r->left != NULL)
num_l = count(r->left);
if(r->right != NULL)
num_r = count(r->right)+1;
return num_l+num_r
}
In recursive approach,
You would be calling a function to traverse your tree,
for current node, you need to:
check if current node has right child (then increment the counter), and then call the function recursively for right node.
check if current node has left child, call the function recursively for left node.
This should work.
Do a simple traversal on the tree (i.e. post order, in order) and for each node do +1 if it has right child.
Example (didn't try to compile and check it):
int countRightChildren(Node root)
{
if (root == null) return 0;
int selfCount = (root.getRightChild() != null) ? 1 : 0;
return selfCount + countRightChildren(root.getLeftChild()) + countRightChildren(root.getRightChild());
}
You can do it recursively as:
If tree does not exist, there are no
R children.
If tree exists, then # R children = #
R children in R-subtree + # R
children in L-subtree
.
int countRChildren(Node *root) {
if(!root) // tree does not exist.
return 0;
// tree exists...now see if R node exits or not.
if(root->right) // right node exist
// return 1 + # of R children in L/R subtree.
return 1 + countRChildren(root->right) + countRChildren(root->left);
else // right nodes does not exist.
// total count of R children will come from left subtree.
return countRChildren(root->left);
}
This is include how i build the struct
struct Item
{
int info;
struct Item* right;
struct Item* left;
};
typedef struct Item* Node;
int countRightSons(Node tree)
{
if(!tree)
return 0;
if(tree->right != NULL)
return 1 + countRightSons(tree->right) + countRightSons(tree->left);
return countRightSons(tree->left);
}
Simple recursive approach,
check (even if not needed) for all the 4 possibilities:
left and right does not exists
left and right exists
left exists and right doesnt
right exists and left doesnt
public static int countRightChildren(BST tree) {
if (tree.root==null) return Integer.MIN_VALUE;
return countRightChildren(tree.root);}
public static int countRightChildren(Node curr) {
if (curr.right==null&&curr.left==null) return 0;
else if (curr.right!=null&&curr.left==null)
return curr.right.data+countRightChildren(curr.right);
else if (curr.right==null&&curr.left!=null)
return countRightChildren(curr.left);
else if (curr.right!=null&&curr.left!=null)
return curr.right.data+countRightChildren(curr.left)+countRightChildren(curr.right);
return Integer.MIN_VALUE;
}

Resources