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.
Related
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.
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 .
So I have a perfectly balanced (Each node has two children, if it doesn't have any children, it is a leaf node) binary search tree
1
2 9
3 6 10 11
4 5 7 8 12 13 14 15
and I have that in an array in pre-order
[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]
now how do I convert my array to in-order or post order ?
well, somehow yesterday I misunderstood your question, or you didn't explain it well. anyway, the thing is that --
you have an array which contains the nodes of a tree, placed in
preorder traversal by the tree; now you want to 'reverse-engineer' of
it such that you can build or make a tree again from that array so that you can traverse IN or POST order, whatever you required to do!
now one thing you need to understand when you are making the array from the tree, your array should contain the nodes which have value, as well as the nodes which don't have. in another way, you have to place the null nodes of the tree inside of the array, such that you can differentiate the nodes which have value and the nodes which don't have!! pretty simple!
so, what you need to do is, while traversing the tree, you should follow this two-step--
if node has value, put it in array
else put -1 in array [-1 denotes null value]
now, after traversing the tree and make the array from that tree, you can decode the array to construct back the tree from the array.
PROCEDURE TO MAKE ARRAY FROM TREE
DO LEVEL ORDER TRAVERSAL
IF ROOT HAS A VALUE, PUT IT IN ARRAY
ELSE, PUT -1 IN ARRAY
REPEAT, UNTIL ALL NODES, BEEN TRAVERSED
PSEUDOCODE
FUNCTION encode(TREE root, Array a){
Queue q;
q->add(root);
i = 0;
a[i++] = root->node;
while(!q){
TREE temp = q->front();
q->pop();
/* if temp's left node contains value */
if(temp->left){
a[i++] = temp->left->node;
q->push(temp->left);
}else{
/* if temp's left node doesn't contains value */
a[i++] = -1;
}
/* do the same for right sub-tree */
if(temp->right){
a[i++] = temp->right->node;
q->push(temp->right);
}else{
/* if temp's left node doesn't contains value */
a[i++] = -1;
}
}
return a;
}
now you can reverse the algorithm to construct a tree from the array, and after that you can do POST or IN whatever you need!
PROCEDURE TO MAKE TREE FROM ARRAY
CREATE ROOT
1.1 PUT ROOT IN A QUEUE
TRAVERSE I-TH INDEX FROM ARRAY
2.1 IF ARRAY[INDEX] != -1 , CREATE NODE ON LEFT
2.2 ELSE PUT NULL ON LEFT
TRAVERSE I+1-TH INDEX FROM ARRAY
3.1 IF ARRAY[INDEX] != -1 , CREATE NODE ON RIGHT
3.2 ELSE PUT NULL ON RIGHT
CONTINUE UNTIL QUEUE BECOMES EMPTY
PSEUDOCODE
FUNCTION decode(Array a){
/* creating root */
TREE root;
IF (a[0] == -1)
root = createNode(a[0]);
ELSE
root = NULL;
Queue q;
q->push(root);
i = 0;
while(!q){
TREE temp = q.front();
q->pop();
/* if array's index contain value, create node */
if(a[i+1] != -1){
temp->left = createNode(a[i+1]);
q->push(temp->left);
}else{
/* else assing null */
temp->left = NULL;
}
/* do the same for right subtree */
if(a[i+2] != -1){
temp->right = createNode(a[i+2]);
q->push(temp->right);
}else{
/* else assing null */
temp->right= NULL;
}
i += 2;
}
}
Now you could able to make a tree from the array you have! and can traverse the tree to get IN or POST order traversal!!
HAPPY FRIDAY : )
Is this homework? "In/Pre/Post-Order" is a description of how the tree is to be traversed, not how it is structured.
First of all, you should know the difference between BT and BST. Binary Tree states it has two children, or one child, or doesn't have a child at all;
Where Binary Search Tree, is special Binary Tree, that has smaller value in the left part and higher value in right. This property is following each and every property/node of BST.
Now, you have a binary tree, you want to traverse the tree in - IN, PRE and POST order. And consider this is the traversing way, not the structure
of the tree.
**Rules of PRE-ORDER:**
1. Visit -> Root
2. Process -> Left Child
3. Process -> Right Child
4. Continue (until Root is Empty)
** Rules of IN-ORDER: **
1. Process -> Left Child
2. Visit -> Root
3. Process -> Right Child
4. Continue (until Root is Empty)
** Rules of POST-ORDER: **
1. Process -> Left Child
2. Process -> Right Child
3. Visit -> Root
4. Continue (until Root is Empty)
I am assuming, you already traversed in PRE-ORDER.
** IN-ORDER Traversal of your TREE **
4 -> 3 -> 5 -> 2 -> 7 -> 6 -> 8 -> 1 -> 12 -> 10 -> 13 -> 9 -> 14 -> 11 -> 15
** POST-ORDER Traversal of your TREE **
4 -> 5 -> 3 -> 7 -> 8 -> 6 -> 2 -> 12 -> 13 -> 10 -> 14 -> 15 -> 11 -> 9 -> 1
EDIT: Visit here to understanding the traversing -> https://medium.com/quick-code/data-structures-traversing-trees-9473f6d9f4ef
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
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()