C Function to Convert a Binary Tree into its Mirror Tree - c

How to convert a tree to its mirror tree. For eg.
1 1
/ \ / \
2 3 to 3 2
/ \
4 4

Perform post order traversal.
void mirror(struct node* node)
{
if (node!=NULL)
{
struct node* temp;
/* do the subtrees */
mirror(node->left);
mirror(node->right);
/* swap the pointers in this node */
temp = node->left;
node->left = node->right;
node->right = temp;
}
}

Solution uses recursion to convert a tree to its mirror tree.
If root of both trees are null, then they are same. Return true.
If roots of both the trees are not null, check if the data in the two nodes is same and recursively check if left and right subtrees are identical.
If the roots of only one of the trees is null, then the trees are not identical, so return false.
Source: http://www.ideserve.co.in/learn/mirror-a-tree

Related

leetcode 110. Balanced Binary Treeļ¼ŒProblems with balanced tree code

I am working on LeetCode problem 110. Balanced Binary Tree:
Given a binary tree, determine if it is height-balanced.
For this problem, a height-balanced binary tree is defined as:
a binary tree in which the left and right subtrees of every node differ in height by no more than 1.
I've seen solutions for this question, including this one:
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
int max(int a, int b){
return (a > b) ? a:b;
}
int height(struct TreeNode* root){
if(root == NULL) return 0;
return 1 + max(height(root->left),height(root->right));
}
bool isBalanced(struct TreeNode* root){
if(root == NULL) return 1;
int left = height(root->left);
int right = height(root->right);
return abs(left - right) <= 1 && isBalanced(root->left) && isBalanced(root->right);
}
My question is: why should this code be added?
isBalanced(root->left) && isBalanced(root->right);
It seems to be working fine when I delete this from the code. However, when the test case is [1,2,2,3,null,null,3,4,null,null,4], the code will return true, while the expected answer is false.
I am full of doubts about this test, because both ends of the test tree are the same depth, so abs(left-right) should be 0, and 0<=1, so shouldn't the answer for this test be true!?
the test case is [1,2,2,3,null,null,3,4,null,null,4],
So let's visualise that tree:
1
/ \
2 2
/ \
3 3
/ \
4 4
the code will return true, while the expected answer is false,
The expected answer is false: the above tree is not a balanced tree.
I am full of doubts about this test, because both ends of the test tree are the same depth, so abs(left-right) should be 0, and 0<=1, so shouldn't the answer for this test be true!?
You are right that abs(left-right) is 0 and that's within the bounds [-1,1], but in a balanced tree, this condition must be true in every node. So your code must also check that abs(left-right) is within the limits for other nodes. And then you can see that the first node with value 2, has a left-subtree that is 2 levels higher than its right-subtree (which is empty). So there we have a violation of the rule, and the correct answer is false.
This explains why you really need those two recursive calls to isBalanced.
a binary tree in which the left and right subtrees of every node differ in height by no more than 1.
Here you have already mentioned why your implementation is throwing up an error. Your code only checks the height balancing at the root node(topmost node).
The difference of heights in every node must be [-1,0,1] in a balanced tree. An easier visualization will be considering each node has a small tree itself.
Let this be the testcase [1,2,2,3,null,null,3,4,null,null,4].
1
/ \
2 2
/ \
3 3
/ \
4 4
If you only check the root node, the abs(left-right) is 0. But consider the left node 2. And visualize it a smaller tree or a subtree.
2
/
3
/
4
If this is a tree on its own then it's not balanced since abs(left-right) == 2.Since we have found a node that is not balanced we return false.
Thus to solve this problem, we have to consider each node as a separate tree itself. Such problems require recursive algorithms that checks the isBalanced property from the highest to the lowest nodes by calling their child nodes recursively.

Find and delete wrong node in a BST in C

I have a C problem which i need to check if a given Tree is a Binary Search Tree or not and then find which node is incorrect and delete it (from the problem definition, it will always be just one wrong node). For instance:
10
|
|
9 12
| |
| |
7 3 11 14
In this tree, element 3 is incorrect and should be deleted. In case of given tree is already a BST, algorithm should do nothing. I'm trying to adapt a solution from CodeForGeeks which verifies if a tree is a BST or not to instead returning a boolean, returning a pointer for the node which is wrong, but this isn't working well. Here's the method i came up with:
NODE* verifyBinaryTree(NODE* root, NO** previous){
if(node != NULL){
NODE* left= verifyBinaryTree(root->left, previous);
if(left != NULL){
return left;
}
if(*previous && root->data <= (*previous)->data) return root;
*previous = root;
return(verifyBinaryTree(root->right, previous));
}
return NULL;
}
I would enjoy if someone could help me to find the right logic behind this problem.
Here is an easy way to approach this problem . If you do inorder traversal on a valid BST , you will get the nodes sorted in increasing order .
You can do this inorder traversal and after storing them serially in a data structure (perhaps array) , check if the adjacent elements are not in increasing order . If you find such elements , you need to delete them .

Placing a new node into the next available position in a binary tree heap?

Let's say I have this data structure for a minimum heap:
struct node{
int height;
struct node *parent;
struct node *left;
struct node *right;
};
What I want to do is add a new node into the next available position (keeping the min heap property does not matter at this point.) What I have so far is in the case of an empty tree (the root is instantiated earlier to NULL earlier in the code). I am having trouble figuring out the logic in the case that a root already exists. I need to add the elements in one by one. I understand how to do this using a heap as an array, but I need to do it using a heap as a binary tree.
void insert(int number)
{
struct node *nodeToInsert;
nodeToInsert=(struct node*)malloc(sizeof(struct node));
nodeToInsert->value = number;
if(root == NULL)
{
root = nodeToInsert;
root->left = NULL;
root->right = NULL;
}
}
If I understand correctly, you want to know how to descend a complete binary tree to insert the next node. All you need for this is to know how many nodes are already in the bottom level. The bits of this number tell you how to turn (left or right) as you move down the tree to the next available position. Happliy, you can get the number of nodes in the bottom level from the total number of items in the tree, which you normally want to track anyway.
// Let n be the current number of nodes in the tree.
// Subtract sizes of levels until we're at the last.
for (ls = 1, n_levels = 0; ; ls *= 2, n_levels++) {
if (n - ls < 0) break;
n -= ls;
}
// n now contains number of nodes in bottom level
// n_levels contains the number of complete levels above.
struct node *p = root;
for (bit = 1 << (n_levels - 1); bit != 1; bit >>= 1)
if (n & bit)
p = p->right;
else
p = p->left;
if (n & 1)
p->right = new_node();
else
p->left = new_node();
For example say n = 10. So we have a perfect tree of 7 nodes plus 3 on the lowest, incomplete level. The first loop subtracts 1, 2, then 4, so finishes with n = 3 = 011_2 and n_levels = 3. Consequently, the second loop creates the bit mask 1 << 2 = 4 = 100_2. The loop therefore moves down the tree with p = p->left for the high order bit 0 of n, then p = p->right for the 1. The final bit is a 1, therefore it puts the new node at p->right. This is the correct place (11) as you can see in this picture:
=== 1 ---
// \
2 3
/ \\ / \
4 5 6 7
/ \ / \\
8 9 10 11
Note the pseudocode above does not handle the n=0 case, but your code already does that.
Oof, it's not easy. You basically need to count the depth of each non-full node, and insert under the leftmost one with minimal depth.
It gets a lot easier if you know how many nodes are in the tree already. Once you have that, you can just traverse down to the n+1 position and put the node there.
There are many ways you could tackle this. One possible solution is using a queue.
Here is an example implementation in python:
def insert(self,node):
if self.root is None:
self.root = node
return node
else:
q = Queue()
x = self.root
while x is not None:
if x.left is None:
x.left = node
return node
elif x.right is None:
x.right = node
return node
else:
q.add(x.left)
q.add(x.right)
x = q.remove()

Inserting an element in Binary Tree

Tried exploring a lot over the net, but could get any help,
Everywhere its like adding a node to the Binary Search tree.
Question: Requesting for algorithm and code snippet for adding a node to the Binary tree. ( or point me to correct URL )
Assumption:
As per my understanding, Binary Tree and Binary Search Tree is different? Correct me if I am wrong.
( request: if you are writing your code snippet please use proper variable name, that helps in understanding )
Eg: Binary Tree
5 7 3 x1 x2 x3
5
7 3
x1 x2 x3
Binary Search Tree 5 7 3 2 4 6
5
3 7
2 4 6
insert(int key, struct node **root)
{
if( NULL == *root )`
{
*root = (struct node*) malloc( sizeof( struct node ) );`
(*root)->data = key;
(*root)->left = NULL;
(*root)->right = NULL;
}
else if(key < (*root)->data)
{
insert( key, &(*root)->left );
}
else if(key > (*root)->data)
{
insert( key, &(*root)->right );
}
}
The difference between a Binary Tree and a Binary Search Tree is that though they both have restrictions that each node can have at most 2 child nodes, a Binary Search Tree (BST) also must have its left child be of equal or lesser value and the its right child must be of greater or equal value. This is why it is called a "Search" tree because everything is ordered numerically and it has an O(logn) run time for searching.
Because there isn't the requirement of being a BST, a Binary Tree can be stored in a vector (array). As you insert into the vector you build the Binary Tree in level-order fashion. The code is below:
// typedef the node struct to NODE
// nodeVector similar to STL's vector class
insert(int key, NODE** nodeVector)
{
NODE *newNode = (NODE*) malloc( sizeof( NODE ) );
newNode->data = key;
newNode->left = NULL;
newNode->right = NULL;
// add newNode to end of vector
int size = nodeVector->size();
nodeVector->push_back(newNode);
// if newNode is not root node
if(nodeVector->size() > 1)
{
// set parent's child values
Node* parent = (size/2)-1; // take advantage of integer division instead of using floor()
if (parent->left == NULL)
{
parent->left = newNode;
}
else
{
parent->right = newNode;
}
}
}
A Queue data structure can be used for inserting element in to a Binary Tree, since in Binary Tree the order of nodes is not maintained so we will insert the node as soon as we find any null.
Using Queue we will be traversing the Binary Tree in Level Order Traversal.
struct Treenode* temp;
Q = CreateQueue();
EnQueue(Q,root);
while(!IsEmptyQueue(Q))
{
temp = DeQueue(Q);
if(temp->left)
EnQueue(Q,temp->left);
else
{
temp->left=newNode;
DeleteQueue(Q);
return;
}
if(temp->right)
EnQueue(Q,temp->right);
else
{
temp->right=newNode;
DeleteQueue(Q);
return;
}
}
Since, I cannot comment I am writing this.
The above answer for binary tree insert function is wrong.
Suppose for 0, 1, 2 , 3, 4 , 5 passed in sequence to insert function,
its generating tree like
0
/
1
\
2
/
3
\
4
/
5`<br/>
of which inorder traversal will be 1 3 5 4 2 0
while answer should be
0
/ \
1 2
/ \ /
3 4 5
of which inorder traversal will be 3 1 4 0 5 2.
Since I also face the same problem, I came up with following solution over the net :-
You can use a queue to store the current node where we want to place the new node as we do in level order traversal and then we insert the nodes level by level.
Following link might help you :-
http://www.geeksforgeeks.org/linked-complete-binary-tree-its-creation/
I am posting this as answer because I dont have the necessary reputation to post a comment. Except for bagelboy all others have misunderstood the tree as either Binary Search Tree or Complete Binary Tree. The question is simple Binary Tree and Bagelboy's answer looks correct.

Center of Binary Tree

How can we find center of a binary tree?
What shall be the most efficient algorithm. Though center of binary tree will be the mid point of the path corresponding to the diameter of tree. We can find the diameter of tree without actually knowing the path, is there any similar technique for finding center of binary tree?
If you know the diameter : D
and you know the max depth of the tree : M
then your center will be at the (M-(D/2)) th node(from the root) on the deepest path.(it might be M - (D-1)/2 depending on parity, you need to check yourself)
If you have more than on 1 paths from root to leaf with M nodes then the center is the root. (only true when the longest path goes through the root)
EDIT:
To answer your remark.
if it doesn't go through the root. Let's take the D/2th node on the diameter it will still be on the longest side of the diameter path (wich is in all the cases the longest path from root to leaf). and therefore M-D/2 still represent this point from the root.
Taking M-D/2nth from the root is the same as talking D/2nth from the leaf of the longest path.
Am I clear enough ? You might just want to draw it to check it .
You could calculate this in linear time O(N) by storing a list of the nodes that you have traversed if you are using a recursive method where you calculate the diameter by using the height of the tree (see this website here).
For instance, adapt the linear-time diameter function at the link I posted above so that you are also collecting a list of the nodes you have visited, and not just distance information. On each recursive call, you would select the list that went along with the longer traversed distance. The middle of the list that represented the diameter of the tree would be the "center" of the tree.
Your setup would look like the following:
typedef struct linked_list
{
tree_node* node;
linked_list* next;
} linked_list;
typedef struct list_pair
{
linked_list* tree_height;
linked_list* full_path;
} list_pair;
//some standard functions for working with the structure data-types
//they're not defined here for the sake of brevity
void back_insert_node(linked_list** tree, tree_node* add_node);
void front_insert_node(linked_list** tree, tree_node* add_node);
int list_length(linked_list* list);
void destroy_list(linked_list* list);
linked_list* copy_list(linked_list* list);
linked_list* append_list(linked_list* first, linked_list* second);
//main function for finding the diameter of the tree
list_pair diameter_path(tree_node* tree)
{
if (tree == NULL)
{
list_pair return_list_pair = {NULL, NULL};
return return_list_pair;
}
list_pair rhs = diameter_path(tree->right);
list_pair lhs = diameter_path(tree->left);
linked_list* highest_tree =
list_length(rhs.tree_height) > list_length(lhs.tree_height) ?
rhs.tree_height : lhs.tree_height;
linked_list* longest_path =
list_length(rhs.full_path) > list_length(lhs.full_path) ?
rhs.full_path : lhs.full_path;
//insert the current node onto the sub-branch with the highest height
//we need to make sure that the full-path, when appending the
//rhs and lhs trees, will read from left-to-right
if (highest_tree == rhs.tree_height)
front_insert_node(highest_tree, tree);
else
back_insert_node(highest_tree, tree);
//make temporary copies of the subtrees lists and append them to
//create a full path that represents a potential diameter of the tree
linked_list* temp_rhs = copy_list(rhs.tree_height);
linked_list* temp_lhs = copy_list(lhs.tree_height);
linked_list* appended_list = append_list(temp_lhs, temp_rhs);
longest_path =
list_length(appended_list) > list_length(longest_path) ?
appended_list : longest_path;
list_pair return_list_pair;
return_list_pair.tree_height = copy_list(highest_tree);
return_list_pair.full_path = copy_list(longest_path);
destroy_list(rhs.tree_height);
destroy_list(rhs.full_path);
destroy_list(lhs.tree_height);
destroy_list(lhs.full_path);
return return_list_pair;
}
Now the function returns a series of pointers in the full_path structure member that can be used to cycle though and find the middle-node which will be the "center" of the tree.
P.S. I understand that utilizing copying functions is not the fastest approach, but I wanted to be clearer rather than make something that was faster but had too much pointer-twiddling.
Optimized implementation: The above implementation can be optimized by calculating the
height in the same recursion rather than calling a height() separately.
/*The second parameter is to store the height of tree.
Initially, we need to pass a pointer to a location with value
as 0. So, function should be used as follows:
int height = 0;
struct node *root = SomeFunctionToMakeTree();
int diameter = diameterOpt(root, &height); */
int diameterOpt(struct node *root, int* height)
{
/* lh --> Height of left subtree
rh --> Height of right subtree */
int lh = 0, rh = 0;
/* ldiameter --> diameter of left subtree
rdiameter --> Diameter of right subtree */
int ldiameter = 0, rdiameter = 0;
if(root == NULL)
{
*height = 0;
return 0; /* diameter is also 0 */
}
/* Get the heights of left and right subtrees in lh and rh
And store the returned values in ldiameter and ldiameter */
ldiameter = diameterOpt(root->left, &lh);
rdiameter = diameterOpt(root->right, &rh);
/* Height of current node is max of heights of left and
right subtrees plus 1*/
*height = max(lh, rh) + 1;
return max(lh + rh + 1, max(ldiameter, rdiameter));
}
Time Complexity: O(n)

Resources