Function to add node to a tree - algorithm

This question is related to a Binary Search tree. Here is the definition of a node that I am using
struct _Node
{
_Node *Parent;
int Data;
_Node *Left;
_Node *Right;
};
Now here is the definition of the function to add a node once a root is created
void AddNode(_Node *Incoming, _Node *currentNode)
{
if(!currentNode)
{
currentNode = Incoming;
}
else if(currentNode->Data >= Incoming->Data)
{
Incoming->Parent = currentNode;
AddNode(Incoming, currentNode->Left);
}
else if(currentNode->Data < Incoming->Data)
{
Incoming->Parent = currentNode;
AddNode(Incoming, currentNode->Right);
}
}
AddNode function is based on a recursive approach. Main code is
_Node *Root= new _Node;
Root->Data = 50;
Root->Parent = nullptr;
Root->Left = nullptr;
Root->Right = nullptr;
_Node *Node2 = new _Node;
Node2->Data = 25;
Node2->Parent = nullptr;
Node2->Left = nullptr;
Node2->Right = nullptr;
_Node *Node3 = new _Node;
AddNode(Node2, Root);
Problem:
Once I come out of the add node function I find that Root node doesnot have a Left or Right Child set to Node2. According to me as pointer to a node is passed each time I should have got the node added to the Root correctly. this is not happening. Can you please help me out here to understand what mistake I am making?

Try
AddNode(Incoming, currentNode->Left);
instead of
AddNode(Incoming, Incoming->Left);
Same for Right.

Related

Why is my create function of binary search tree not working?

The create function is supposed to ask the user how many nodes they want to enter and then insert that many elements one by one.
I am using the pre order traversal function to check the creation of the binary search tree
The code runs fine for the input part, where it is asking the user for data to enter, but when it is supposed to show the tree in pre order traversal manner, it does not do anything and exits.
#include <stdio.h>
#include <stdlib.h>
struct Node
{
int data;
struct Node* left;
struct Node* right;
};
void insert(struct Node* root, int x)
{
if(root -> left == NULL && x < root -> data)
{
struct Node* new_node = (struct Node* )malloc(sizeof(struct Node));
new_node -> data = x;
new_node -> left = NULL;
new_node -> right = NULL;
root -> left = new_node;
}
else if(root -> right == NULL && x > root -> data)
{
struct Node* new_node = (struct Node* )malloc(sizeof(struct Node));
new_node -> data = x;
new_node -> left = NULL;
new_node -> right = NULL;
root -> right = new_node;
}
else
{
if(x < root -> data)
{
insert(root -> left, x);
}
else if(x > root -> data)
{
insert(root -> right, x);
}
}
}
void create(struct Node* root)
{
root = (struct Node*)malloc(sizeof(struct Node));
printf("\nHow many nodes do you want to create: ");
int tree_size;
scanf("%d", &tree_size);
printf("\nEnter data for root node: ");
int ent_data;
scanf("%d", &ent_data);
root -> data = ent_data;
root -> left = NULL;
root -> right = NULL;
for(int i=1; i<tree_size; i++)
{
printf("\nEnter data for node: ");
scanf("%d", &ent_data);
insert(root, ent_data);
}
}
void preOrderTraversal(struct Node *root)
{
if(root != NULL)
{
printf("%d, ", root -> data);
preOrderTraversal(root -> left);
preOrderTraversal(root -> right);
}
}
int main()
{
struct Node* root = NULL;
create(root);
preOrderTraversal(root);
return 0;
}
The problem is that create is not going to modify your main's variable root. C arguments are passed by value, so you should do one of the following:
Pass the address of root to the create function, or
Don't pass root as argument at all, but let create return the root pointer.
The second option is to be preferred, because root does not serve as input value for create, but as output.
Not related to your issue, but try to avoid code repetition. There are three places in your code where you call malloc and initialise a node. instead create a function for that and call it at those three places.
Here is the adapted code:
#include <stdio.h>
#include <stdlib.h>
struct Node
{
int data;
struct Node* left;
struct Node* right;
};
// Function to call whenever you need a node instance
struct Node * create_node(int x)
{
struct Node* new_node = (struct Node*) malloc(sizeof(struct Node));
new_node -> data = x;
new_node -> left = NULL;
new_node -> right = NULL;
return new_node;
}
void insert(struct Node* root, int x)
{
if(root -> left == NULL && x < root -> data)
{
root -> left = create_node(x); // Use function
}
else if(root -> right == NULL && x > root -> data)
{
root -> right = create_node(x); // Use function
}
else
{
if(x < root -> data)
{
insert(root -> left, x);
}
else if(x > root -> data)
{
insert(root -> right, x);
}
}
}
struct Node* create() // No parameter, but return type
{
printf("\nHow many nodes do you want to create: ");
int tree_size;
scanf("%d", &tree_size);
printf("\nEnter data for root node: ");
int ent_data;
scanf("%d", &ent_data);
struct Node* root = create_node(ent_data); // Use function
for(int i=1; i<tree_size; i++)
{
printf("\nEnter data for node: ");
scanf("%d", &ent_data);
insert(root, ent_data);
}
return root; // Return the root
}
void preOrderTraversal(struct Node *root)
{
if(root != NULL)
{
printf("%d, ", root -> data);
preOrderTraversal(root -> left);
preOrderTraversal(root -> right);
}
}
int main()
{
struct Node* root = create(); // No argument, but return value
preOrderTraversal(root);
return 0;
}

Insertion in BST

I was doing a problem on insertion. This is the right answer.
/*
Node is defined as
typedef struct node
{
int data;
node * left;
node * right;
}node;
*/
node * insert(node * root, int value)
{
if(root == NULL)
{
node *temp = new node();
temp->left = NULL;
temp->right = NULL;
temp->data = value;
root = temp;
return root;
}
if(value > root->data)
{
root->right = insert(root->right, value);
}
else
root->left = insert(root->left, value);
return root;
}
The only difference with the solution I made is that in the if/else statements I did not assign anything. This is my code.
Node is defined as
typedef struct node
{
int data;
node * left;
node * right;
}node;
*/
node * insert(node * root, int value)
{
if(root == NULL)
{
node *temp = new node();
temp->left = NULL;
temp->right = NULL;
temp->data = value;
root = temp;
return root;
}
if(value > root->data)
{
insert(root->right, value);
}
else
insert(root->left, value);
return root;
}
I am not sure I understand why this is necessary because basically calling this function recursively will find a right place for the node with the data value.
Then, I create node with right data and just insert it there.
I will leave a link to the problem. https://www.hackerrank.com/challenges/binary-search-tree-insertion
Thanks for help!

Traverse binary tree - no recursion, no stack, no tree modification

So for an application I am building I need to be able to traverse a binary tree without using recursion, stack or modifying the tree in any way after it's been created. My node struct is as follows:
typedef struct
{
ValueType value; //Data stored in node
int left_index; //Left child
int right_index; //Right child
int parent_index; //Parent node
}
I am storing my tree as a 1D array where the left child of each node is at index 2*i + 1, the right child is at 2*i + 2 and the parent is at [i-1]/2. If a node doesn't have a parent or child, it's associated index is -1.
The only iterative non-stack based algorithm I found was something called "Morris Traversal" as seen here: http://www.geeksforgeeks.org/inorder-tree-traversal-without-recursion-and-without-stack/
However Morris Traversal modifies the tree during the traversal which I cannot do.
I am willing to add whatever information is needed to each node just as long as I can write the algorithm given the above constraints.
Is what I'm asking for even possible? And if so, how would I go about doing it? Not really sure how to even begin.
Wouldn't a "while(!done)" loop be suffcient?
What you want is a threaded binary tree. The right pointer of all leaf nodes points to the node's in-order successor.
It's easy to create such a thing, and not difficult at all to update it when you insert or delete a node. If you have control of the node structure, then this is almost certainly what you want.
public class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode parent;
public void traverse() {
TreeNode current = this.leftMost();
while (current != null) {
System.out.println("Current at " + current.val);
current = current.inOrderNext();
}
}
public TreeNode inOrderNext() {
if (right != null) {
return right.leftMost();
} else {
TreeNode current = this;
TreeNode above = this.parent;
while (true) {
if (above == null) {
return null;
} else {
if (above.left == current) {
return above;
} else {
current = above;
above = above.parent;
}
}
}
}
}
public TreeNode leftMost() {
TreeNode result = this;
while (result.left != null) {
result = result.left;
}
return result;
}
public static void main(String args[]) {
TreeNode first = new TreeNode();
first.val = 4;
TreeNode second = new TreeNode();
second.val = 2;
second.parent = first;
first.left = second;
TreeNode third = new TreeNode();
third.val = 1;
third.parent = second;
second.left = third;
third = new TreeNode();
third.val = 3;
third.parent = second;
second.right = third;
second = new TreeNode();
second.val = 6;
second.parent = first;
first.right = second;
third = new TreeNode();
third.val = 5;
third.parent = second;
second.left = third;
third = new TreeNode();
third.val = 7;
third.parent = second;
second.right = third;
first.traverse();
}
}

I don't know what's wrong with my code - Binary Tree

I'm now making a Binary Tree in C++, using friend class.
But, something is wrong, and I cannot know what should I change
template <class Type>
class BinaryTree{
public:
BinaryTree(){
root = new BTNode<Type>();
currentNode = NULL;
}
~BinaryTree(){
delete root, currentNode;
};
void insertItem(Type data){
if(currentNode==NULL){
Item = data;
currentNode = root;
}
if(data<currentNode){
if(currentNode->Left.is_empty()){
currentNode->Left = new BTNode(data);
currentNode = root;
return;
}
else{
currentNode = currentNode->Left;
return insertItem(data);
}
}
if(data>currentNode){
if(currentNode->Right.is_empty()){
currentNode->Right = new BTNode(data);
currentNode = root;
return;
}
else{
currentNode = currentNode->Right;
return insertItem(data);
}
}
currentNode = root;
return;
}
void deleteItem(Type data){}
void is_empty(){
if (this == NULL) return 1;
else return 0;
}
void printInOrder(){
if(!(currentNode->Left).is_empty()){
currentNode = currentNode->Left;
}
}
private:
BTNode<Type>* currentNode;
BTNode<Type>* root;
};
and here the BTNode class that store the item of BinaryTree, and point the next Node:
template <class Type>
class BTNode{
public:
friend class BinaryTree<Type>;
BTNode(){}
BTNode(Type data){
Item = data;
}
~BTNode(){}
private:
Type Item;
BTNode<Type> *Left, *Right;
};
The Binary Tree class's BTNode*root point the first Node, and currentNode will point the 'current node' while doing something like insertion or merging the nodes.
But when I compile, the Compiler Error C2143 occurs in the BinaryTree class,
here:
BTNode<Type>* root;
BTNode<Type>* currentNode;
The error says that there is no toke ; in front of <
but I cannot know what is wrong
It appears as though BTNode isn't correctly defined inside the BinaryTree class. The compiler is not understanding that BTNode is a type. Make sure you're including and linking the files correctly.

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)

Resources