How to find Number of Nodes in binary tree having only left child?
LeftNode(root)
{
if(root==NULL)
return 0;
if(root->left!=null && root-right==null)
return (1+LeftNode(root->left));
return (LeftNode (root->left) + LeftNode (root->right))
}
I would do so (C++):
int leftNode(Node * root)
{
if (root == nullptr)
return 0;
// c is 1 if root has a left child and has not a right one
int c = root->left != nullptr and root->right == nullptr ? 1 : 0;
return c + leftNode(root->left) + leftNode(root->right);
}
Since no specific language is required I am going to write my solutions in Swift
func nodesWithOnlyLeftChild(node:Node?) -> UInt {
guard let node = node else { return 0 }
let count: Uint = (node.left != nil && node.right == nil) ? 1 : 0
return nodesWithOnlyLeftChild(node.left) + nodesWithOnlyLeftChild(node.right) + count
}
Explaination
1: The signature
func nodesWithOnlyLeftChild(node:Node?) -> UInt
The function accepts a parameter of type Node?. This does mean the parameter can be a Node or nil.
The function does return an unsigned integer.
2: Checking the parameter
guard let node = node else { return 0 }
The first line verify that the input param is not nil. If it is not nil then the next line is executed, otherwise 0 is returned.
3: Evaluating the current node
let count: UInt = (node.left != nil && node.right == nil) ? 1 : 0
The constant count is created. It is populated with 1 if this node has only a left child. 0 otherwise.
4: Recursive calls
return nodesWithOnlyLeftChild(node.left) + nodesWithOnlyLeftChild(node.right) + count
The function does return the result of nodesWithOnlyLeftChild applied to the left child + nodesWithOnlyLeftChild applied to the right child + the constant count
Considerations
The time complexity of this function is O(n) where n is the nodes in the three.
The space complexity is O(1).
Infact although we can have max n recursive calls, the Tail Recursion (supported by LLVM and other compilers) does use the same stack frame when some conditions are met.
Related
I have an expression tree where each leaf node contains 0 or 1 as value, and all the internal nodes contain "&" or "||" as operator. Now I need to evaluate the tree; the result will be either 0 or 1.
The question is minimum number of swap of internal node required to complement the result of original expression tree. Any internal node can be flipped; e.g. if it is a "&", we can make it "||", and vice versa.
To solve this I tried the following technique but I didn't succeed in it:
My approach was that I would check the root whether it is a "&" or "||" operator and whether the result of evaluation tree 0 or 1, depending on that I went forward with the evaluation.
i'm not sure if i understood you question. if it's how do evaluate the whole tree my answer is:
try a recursion.
something like this:
evalute() {
if_the_root_is_an_operator() {
l= evaluate(left operant)
r= evaluate(right operant)
return calculate(l,r) // depending on what operator it was
}
// not an operator, so it'S a leaf
return value;
}
optimizations could be, to check if l or r are values, and skip the evaluation if their values already define the final result.
"0 AND (subtree)" is surely 0,
"1 OR (subtree)" is 1, so subtree doesn't need to be evaluated
evalute() {
if (the_root_is_an_operator()) {
if ( operator_is_and() &&
(left_is_leaf() && value(left)==0) ||
(right_is_leaf() && value(right)==0))
return 0;
if ( operator_is_or() &&
(left_is_leaf() && value(left)==1) ||
(right_is_leaf() && value(right)==1))
return 1;
l= evaluate(left operant)
r= evaluate(right operant)
return calculate(l,r) // depending on what operator it was
}
// not an operator, so it'S a leaf
return value;
}
This is an example of problem asked in question.
OR
/ \
OR AND
/ \ / \
1 0 1 1
Output is 1. Need to found min numbers of operands to be changed to change the output to 0.
Min number of operators required to be changed are 2.
class A {
int min=Integer.max;
int minNumber(Tree node) {
if(node==null) return Math.max;
if(node.left==null && node.right==null) return Math.max;
String c = node.data;
int l = evaluate(node.left);
int r = evaluate(node.right);
if(l || r==0) { min_number = 1; }
else {
if(l && r == 1 )
{
min_number = 0;
}
else if(l && r == 0)
{
min_number = 0;
}
int left = min_number + minNumber(node.left)
int right = min_number + minNumber(node.right);
min_number = Math.min(left,right);
}
if(min_number<min) min = min_number; return min;
}
Here's my code
public int getDist(Node root, int value)
{
if (root == null && value !=0)
return -1;//
if(root.value == value)// we have a match
return 0;
if(root.getLeft()!=null)
int left =1+ getDist(root.getLeft(),value);
int right = 1+getDist(root.getRight(),value);
if(left ==-1 && right== -1)
return -1;//not found
return Math.max(left,right);
}
I would appreciate any feedback on the correctness of the above approach or any optimizations.
As it stands your code won't work as intended. Consider this on the other hand:
public int getDist(Node root, int value) {
// value is never in an empty subtree
if (root == null)
return -1;
// found value, distance from root is 0
if(root.value == value)
return 0;
// find distance from root of left subtree
int left = getDist(root.getLeft(),value);
// find distance from root of right subtree
int right = getDist(root.getRight(),value);
// value not found in either subtree
if(left == -1 && right == -1)
return -1;
// if the value was found,
// return the distance from the root of the subtree + 1
return 1 + Math.max(left,right);
}
All I changed was remove some superfluous checks and move the +1 after the check for "value not in either subtree". The effect this has is the following: if the recursion finds that the value is not in a subtree, then the return statements will ripple up the value -1 all the way to the root of the subtree without changing it, keeping the information "value not here" intact. If the value was found in at least one subtree, then it can't be that both left and right are -1 so that check will fail and the return statement at the end will give back the intended value.
Let int? indicate a variant type that is either an int or null. In C# this is Nullable<int>, in C++11 this is std::optional<int>, etc.
Then the following code will work. It is only slightly modified from your code, with the key difference being the use of min instead of max.
int? dist(Node root, int value)
{
if (root == null) return null;
if (root.value == value) return 0;
int? left = dist(root.left, value);
int? right = dist(root.right, value);
if (left == null && right == null) return null;
if (left != null && right != null) return 1 + min(left, right);
if (left != null) return 1 + left;
return 1 + right;
}
If you want, you can just use int and replace the appropriate occurrences of null with some special value like -1. It's my personal preference to use a nullable/optional value because it seems clearer, but it's by no means required for this problem.
I'm trying this question for sometime but couldn't figure out the algorithm. My preference is to do it iteratively. Till now, I've figure out something but not sure on some point.
Currently, My algorithm looks like:
First traverse the tree to find the node
While traversing the tree, keep track of the previous node.
if you find the node, check if left child is present then that is successor return.
if left child is not present then check if right child is present the that is successor and return.
if the node(is left to the parent) and don't have left or right child then we've saved the prev node earlier then either prev or prev's right child is the successor.
But what if the node we found is in the right to parent and don't have left or right child how to find successor of this node?
May be there are many flaws in this algorithm as still I've not understand all the cases properly. If anyone has any idea or algorithm please share.
Thanks in advance.
when you find a node in preorder, to find its successor is just travesing to its next node.
what I was thinking first is the relationship of a node and its successor's values in pre-oder, but I found that it seems not very clear like the relationship in in-order. I think there is only one step beteen a node and its successor(if exists) : just move on travesing. So I design this algorithm.
my algorithm below is based on preorder travesal, it can run on a binary tree,not only BST.
#define NOT_FOUND -1
#define NEXT 0
#define FOUND 1
struct node {
struct node *p;//parent,but useless here
struct node *l;//left child
struct node *r;//right child
int value;
};
int travese(struct node* bnode, int* flag,int value)
{
if(bnode == NULL)
return 0;
else
{
if(*flag == FOUND)
//when the successor is found,do pruning.
return 1;
else if(*flag == NEXT) {
printf("successor:%d\n",bnode->value);
*flag = FOUND;
return 1;
}
else if(*flag == NOT_FOUND && bnode->value == value)
*flag = NEXT;
travese(bnode->l,flag,value);
travese(bnode->r,flag,value);
}
return 0;
}
and use it by:
int flag = NOT_FOUND;
travese(root,&flag,value);
if(flag == NEXT || flag == NOT_FOUND)
printf("no successor.\n");
EDIT:
turning a recurrence algorithm to a iterative one is not difficult by using a stack like below:
int preorder_travese_with_stack(struct node* bnode, int* flag,int value)
{
if(bnode == NULL)
return 0;
struct stack s;//some kind of implement
push(s,bnode);
while(NotEmpty(s) && *flag) {
struct node *curNode = pop(s);
if(*flag == NEXT) {
printf("successor:%d\n",curNode->value);
*flag = FOUND;
return 1;
}
else if(*flag == NOT_FOUND && curNode->value == value)
*flag = NEXT;
push(s,curNode->r);
push(s,curNode->l);
}
return 0;
}
but according to your comment and original description, I think the one you want is iterative algorithm without a stack.here it is.
After thinking ,searching and trying, I wrote one. When travse the tree iteratively without stack , the parent of a node is not useless any more. In a path, some nodes is visited not only once, and you need to record its direction at that time.
int preorder_travese_without_stack(struct node *root,int value,int *flag)
{
int state=1;
//state: traveral direction on a node
//1 for going down
//2 for going up from its left chlid
//3 for going up from its right child
struct node *cur = root;
while(1) {
if(state == 1) //first visit
{
//common travese:
//printf("%d ",cur->value);
if(cur->value == value && *flag == NOT_FOUND)
*flag = NEXT;
else if (*flag==NEXT) {
*flag = FOUND;
printf("successor:%d\n",cur->value);
break;
}
}
if((state == 1)&&(cur->l!=NULL))
cur = cur->l;
else if((state==1)&&(cur->l==NULL))
{
state = 2;
continue;
}
else if(state==2) {
if(cur->r != NULL ) {
cur=cur->r;
state = 1;
}
else
{
if(cur->p!=NULL)
{
if(cur==cur->p->r)
state = 3;
//else state keeps 2
cur=cur->p;
}
else //cur->p==NULL
{
if(cur->p->r!=NULL)
{
cur=cur->p->r;
state = 1;
}
else
break;
//end up in lchild of root
//because root's rchild is NULL
}
}
continue;
}
else //state ==3
{
if(cur->p!=NULL)
{
if(cur==cur->p->l)
state = 2;
else
state = 3;
cur=cur->p;
continue;
}
else
break;
}
}
}
the usage is the same as the first recurrence one.
If you are confused yet,mostly about the direction of a node , you can draw a tree and draw the path of pre-order traverse on paper,it would help.
I'm not sure there are bugs left in the code,but it works well on the tree below:
0
/ \
1 2
/ \ / \
3 4 5 6
btw,"wirte down pre-order (or else) travese algorithm of a tree both by recurrence and iteration" is a common interview problem, although solving the latter by a stack is permitted.but I think the BST requirement is unnecessary in pre-order travese.
My implementation of the algorithm does not use the key. Therefore it is possible to use it in any kind of binary tree, not only in Binary search trees.
The algorith I used is this:
if given node is not present, return NULL
if node has left child, return left child
if node has right child, return right child
return right child of the closest ancestor whose right child is present and not yet processed
Bellow there is my solution.
TreeNode<ItemType>* CBinaryTree<ItemType>::succesorPreOrder(TreeNode<ItemType> *wStartNode)
{
//if given node is not present, return NULL
if (wStartNode == NULL) return NULL;
/* if node has left child, return left child */
if (wStartNode->left != NULL) return wStartNode->left;
/* if node has right child, return right child */
if (wStartNode->right != NULL) return wStartNode->right;
/* if node isLeaf
return right child of the closest ancestor whose right child is present and not yet processed*/
if (isLeaf(wStartNode)) {
TreeNode<ItemType> *cur = wStartNode;
TreeNode<ItemType> *y = wStartNode->parent;
while (y->right == NULL && y->parent!=NULL){
cur = y;
y = y->parent;
}
while (y != NULL && cur == y->right) {
cur = y;
y = y->parent;
}
return y->right;
}
}
bool CBinaryTree<ItemType>::isLeaf(TreeNode<ItemType> *wStartNode){
if (wStartNode->left == NULL && wStartNode->right == NULL) return true;
else return false;
};
I know the recursive code could be written for finding the minimum height. But for a very large tree (like million nodes in leftside vs 1 node in right side) - the approach isn't good. So please let me know if following code is fine, it uses BFS:-
if (root == null)
{
return 0;
}
Queue<Node> queue = new Queue<Node>();
queue.Enqueue(root);
int min = 0;
while (queue.Count > 0)
{
Node temp = queue.Dequeue();
if (temp.LeftChild == null)
{
return ++min;
}
if (temp.LeftChild != null)
{
++min;
queue.Enqueue(temp.LeftChild);
}
if (temp.RightChild == null)
{
return ++min;
}
if (temp.RightChild != null)
{
++min;
queue.Enqueue(temp.RightChild);
}
}
return 0;
So for a tree like
1
/ \
2 3
/
4
/
6
The above returns 1, (as per Floor(Log(n))?
Thanks.
The idea is perfect. But the code still can be bettered a bit.
Why do you increase min every time you dequeue item? And you do it twice, it is two times worse :) If you supose this variable to be nodes counter then it is incorrect too because you did not count root element. And hence it must be called in the other way, not min.
Why do you check if children are null twice? If statements spoil the pipe, their count must be minimized.
The idea is next. Let`s call the row of the nodes of the equal level full if every node in it has both children. Then min height is the count of full rows in the tree. It equals closest power index of 2 to the items count in all the full rows + 1.
A code:
if (root == null)
{
return 0;
}
Queue<Node> queue = new Queue<Node>();
queue.Enqueue(root);
int nodesCount = 0;
while (queue.Count > 0)
{
Node temp = queue.Dequeue();
if (temp.LeftChild == null || temp.RightChild == null)
{
return Floor(Log(nodesCount + 1)/Log(2)); // It can be made much better using, for example, bitwise operations but this is not the question`s topic
}
++nodesCount;
queue.Enqueue(temp.LeftChild);
queue.Enqueue(temp.RightChild);
}
return Infinity; // :)
Use 2 stacks to do a "Zig-zag" traversal. Count the number of times where you need to flip the "leftToRight" flag.
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;
}