Insertion in BST - c++11

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!

Related

Valid Binary Tree

/**
* Definition for a binary tree node.
* public 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;
* }
* }
*/
class Solution {
static class ReturnData {
public boolean isBST;
public int max;
public int min;
public ReturnData(boolean is, int mi, int ma) {
isBST = is;
min = mi;
max = ma;
}
}
public boolean isValidBST(TreeNode root) {
if (root == null) {
return true;
}
ReturnData res = check(root);
if (res == null) {
return true;
}
return res.isBST;
}
private ReturnData check(TreeNode node) {
if (node == null) {
return null;
}
int min = node.val;
int max = node.val;
ReturnData left = check(node.left);
ReturnData right = check(node.right);
if (left != null) {
min = Math.min(min, left.min);
max = Math.max(max, left.max);
}
if (right != null) {
min = Math.min(min, right.min);
max = Math.max(max, right.max);
}
boolean isBST = true;
if (left != null && (!left.isBST || left.min >= node.val)) {
isBST = false;
}
if (right != null && (!right.isBST || right.min <= node.val)) {
isBST = false;
}
return new ReturnData(isBST, min, max);
}
}
I want to ask a LeetCode question, Question 98.
The question wants me to write an algorithm to check whether the given tree is a valid binary tree, so I wrote like this:
I create a constructor to initialize the return type, which contains the current node's value, max, and min value of its subtree.
I want to use recursion to check the validation.
But it doesn't work, I also check the solution but I still don't know why this way didn't work.
Hope someone could give me a hint, thanks.
The problem is in this condition:
left.min >= node.val
You'll want to see whether the maximum in the left tree exceeds the current node's value, so:
left.max >= node.val

Inaccuracy in output of deletion function in binary search tree

I am making a binary search tree code, in that 'am facing an issue in the deletion function. After executing the function, the code is showing inorder display incorrectly. Basically, it is incorrect, and I'am not able to understand where the problem is.
In the delete function, I have used a search function that will find the node which the user has to delete. And I have used inorder successor method for deletion so the minimum function will find the successor. All other functions like insertion, minimum, and inorder are working fine.
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
struct node *left;
struct node *right;
} node;
struct node *insert(struct node *tnode, int data)
{
if (tnode == NULL)
{
struct node *ptr;
ptr = (struct node *)malloc(sizeof(struct node));
ptr->data = data;
ptr->left = NULL;
ptr->right = NULL;
return ptr;
}
if (data > (tnode->data))
{
tnode->right = insert(tnode->right, data);
return tnode;
}
if (data < (tnode->data))
{
tnode->left = insert(tnode->left, data);
return tnode;
}
}
void in_order(struct node *tnode)
{
if (tnode == NULL)
return;
else
{
in_order(tnode->left);
printf("%d\t", tnode->data);
in_order(tnode->right);
}
}
struct node *search(struct node *tnode, int data)
{
if (tnode == NULL)
{
return NULL;
}
else
{
if (data == tnode->data)
{
return tnode;
}
else
{
if (data > tnode->data)
{
search(tnode->right, data);
}
else
{
search(tnode->left, data);
}
}
}
}
struct node *minimum(struct node *tnode)
{
if (tnode == NULL)
{
printf("No node present\n");
return NULL;
}
else
{
if (tnode->left == NULL)
return tnode;
else
minimum(tnode->left);
}
}
struct node *deletenode(struct node *tnode, int data)
{
struct node *s;
s = search(tnode, data);
if (s == NULL)
{
printf("Value not found\n");
return NULL;
}
else
{
if (s->left == NULL && s->right == NULL) // No child case
{
free(s);
return NULL;
}
else
{
if (s->left == NULL && s->right != NULL) // single child case(right child)
{
struct node *temp = s->right;
free(s);
return temp;
}
else if (s->right == NULL && s->left != NULL) // single child case(left child)
{
struct node *temp = s->left;
free(s);
return temp;
}
else
{
struct node *temp;
temp = minimum(s->right);
s->data = temp->data;
s->right = deletenode(s->right, temp->data);
}
}
}
return s;
}
int main()
{
struct node *root = NULL, *del;
int n, i, data, key;
printf("Enter how many nodes you have to enter in a tree\n");
scanf("%d", &n);
for (i = 0; i < n; i++)
{
printf("Enter data\n");
scanf("%d", &data);
root = insert(root, data);
}
printf("\nIN-Order display\n");
in_order(root);
int d;
printf("\nEnter data to be delete\n");
scanf("%d", &d);
del=deletenode(root, d);
printf("\nIN-Order display\n");
in_order(root);
return 0;
}
There are several places missing return (in minimum, search and deletenode). You can easily find them if you compile with -Wall -Wextra compiler options.
It is not clear, what do you want to return from deletenode. I assume that it is a tree with deleted element. Then either search should return a parent node (so it is possible to change pointers to freed node), or deletenode should move to parent node.
Also, use in_order(del) instead of in_order(root) because root can be changed while deleting.

Binary Search Tree Traversals

I have just started learning Binary Trees and went ahead and tried to implement my own in C. I am kinda lost as to why only InOrder Traversal is displaying correctly while the other two are wrong. I really can't figure this out. I even directly tried inserting nodes, and the result is the same.
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
struct Node
{
int val;
struct Node *left;
struct Node *right;
};
//Allocate Memory for New Node
struct Node* getNewNode(int val)
{
struct Node * ptr = (struct Node*)malloc(sizeof(struct Node));
ptr->val = val;
ptr->left = NULL;
ptr->right = NULL;
return ptr;
}
//Insert Node in Binary Search Tree
struct Node* insertNode(struct Node* root,int val)
{
if(root == NULL)
{
root = getNewNode(val);
}
else if(val <= root->val)
{
root->left = insertNode(root->left,val);
}
else
{
root->right = insertNode(root->right,val);
}
return root;
}
void printInorder(struct Node* root)
{
if(root == NULL) return;
printInorder(root->left);
printf("%d ",root->val);
printInorder(root->right);
}
void printPostOrder(struct Node* root)
{
if(root == NULL) return;
printInorder(root->left);
printInorder(root->right);
printf("%d ",root->val);
}
void printPreOrder(struct Node*root)
{
if(root == NULL) return;
printf("%d ",root->val);
printInorder(root->left);
printInorder(root->right);
}
bool search(struct Node* root,int val)
{
if(root == NULL)
{
return false;
}
else if(val == root->val)
{
return true;
}
else if(val < root->val)
{
return search(root->left,val);
}
else
{
return search(root->right,val);
}
}
int main(void)
{
struct Node * root = NULL; //Tree is Empty
root = insertNode(root,15);
root = insertNode(root,10);
root = insertNode(root,8);
root = insertNode(root,12);
root = insertNode(root,20);
root = insertNode(root,17);
root = insertNode(root,25);
printf("Printing In-Order: \n");
printInorder(root);
printf("\nPrinting Post-Order: \n");
printPostOrder(root);
printf("\nPrinting Pre-Order: \n");
printPreOrder(root);
// if(search(root,11))
// {
// printf("\nValue Found\n");
// }
// else
// {
// printf("\nValue Not Found\n");
// }
return 0;
}
Please help me understand if I am doing this wrong or my understanding of traversals is faulty.
The output is as follows:
output terminal
You have copy-paste errors in printPostOrder and printPreOrder - they both call printInorder where they should be calling themselves.

AVL Tree. Print element by position (when sorted)

#include<stdio.h>
#include<stdlib.h>
// An AVL tree node
struct node
{
int key;
struct node *left;
struct node *right;
int height;
};
// A utility function to get maximum of two integers
int max(int a, int b);
// A utility function to get height of the tree
int height(struct node *N)
{
if (N == NULL)
return 0;
return N->height;
}
// A utility function to get maximum of two integers
int max(int a, int b)
{
return (a > b)? a : b;
}
/* Helper function that allocates a new node with the given key and
NULL left and right pointers. */
struct node* newNode(int key)
{
struct node* node = (struct node*)
malloc(sizeof(struct node));
node->key = key;
node->left = NULL;
node->right = NULL;
node->height = 1; // new node is initially added at leaf
return(node);
}
// A utility function to right rotate subtree rooted with y
// See the diagram given above.
struct node *rightRotate(struct node *y)
{
struct node *x = y->left;
struct node *T2 = x->right;
// Perform rotation
x->right = y;
y->left = T2;
// Update heights
y->height = max(height(y->left), height(y->right))+1;
x->height = max(height(x->left), height(x->right))+1;
// Return new root
return x;
}
// A utility function to left rotate subtree rooted with x
// See the diagram given above.
struct node *leftRotate(struct node *x)
{
struct node *y = x->right;
struct node *T2 = y->left;
// Perform rotation
y->left = x;
x->right = T2;
// Update heights
x->height = max(height(x->left), height(x->right))+1;
y->height = max(height(y->left), height(y->right))+1;
// Return new root
return y;
}
// Get Balance factor of node N
int getBalance(struct node *N)
{
if (N == NULL)
return 0;
return height(N->left) - height(N->right);
}
struct node* insert(struct node* node, int key)
{
/* 1. Perform the normal BST rotation */
if (node == NULL)
return(newNode(key));
if (key < node->key)
node->left = insert(node->left, key);
else
node->right = insert(node->right, key);
/* 2. Update height of this ancestor node */
node->height = max(height(node->left), height(node->right)) + 1;
/* 3. Get the balance factor of this ancestor node to check whether
this node became unbalanced */
int balance = getBalance(node);
// If this node becomes unbalanced, then there are 4 cases
// Left Left Case
if (balance > 1 && key < node->left->key)
return rightRotate(node);
// Right Right Case
if (balance < -1 && key > node->right->key)
return leftRotate(node);
// Left Right Case
if (balance > 1 && key > node->left->key)
{
node->left = leftRotate(node->left);
return rightRotate(node);
}
// Right Left Case
if (balance < -1 && key < node->right->key)
{
node->right = rightRotate(node->right);
return leftRotate(node);
}
/* return the (unchanged) node pointer */
return node;
}
/* Given a non-empty binary search tree, return the node with minimum
key value found in that tree. Note that the entire tree does not
need to be searched. */
struct node * minValueNode(struct node* node)
{
struct node* current = node;
/* loop down to find the leftmost leaf */
while (current->left != NULL)
current = current->left;
return current;
}
struct node* deleteNode(struct node* root, int key)
{
// STEP 1: PERFORM STANDARD BST DELETE
if (root == NULL)
return root;
// If the key to be deleted is smaller than the root's key,
// then it lies in left subtree
if ( key < root->key )
root->left = deleteNode(root->left, key);
// If the key to be deleted is greater than the root's key,
// then it lies in right subtree
else if( key > root->key )
root->right = deleteNode(root->right, key);
// if key is same as root's key, then This is the node
// to be deleted
else
{
// node with only one child or no child
if( (root->left == NULL) || (root->right == NULL) )
{
struct node *temp = root->left ? root->left : root->right;
// No child case
if(temp == NULL)
{
temp = root;
root = NULL;
}
else // One child case
*root = *temp; // Copy the contents of the non-empty child
free(temp);
}
else
{
// node with two children: Get the inorder successor (smallest
// in the right subtree)
struct node* temp = minValueNode(root->right);
// Copy the inorder successor's data to this node
root->key = temp->key;
// Delete the inorder successor
root->right = deleteNode(root->right, temp->key);
}
}
// If the tree had only one node then return
if (root == NULL)
return root;
// STEP 2: UPDATE HEIGHT OF THE CURRENT NODE
root->height = max(height(root->left), height(root->right)) + 1;
// STEP 3: GET THE BALANCE FACTOR OF THIS NODE (to check whether
// this node became unbalanced)
int balance = getBalance(root);
// If this node becomes unbalanced, then there are 4 cases
// Left Left Case
if (balance > 1 && getBalance(root->left) >= 0)
return rightRotate(root);
// Left Right Case
if (balance > 1 && getBalance(root->left) < 0)
{
root->left = leftRotate(root->left);
return rightRotate(root);
}
// Right Right Case
if (balance < -1 && getBalance(root->right) <= 0)
return leftRotate(root);
// Right Left Case
if (balance < -1 && getBalance(root->right) > 0)
{
root->right = rightRotate(root->right);
return leftRotate(root);
}
return root;
}
// A utility function to print preorder traversal of the tree.
// The function also prints height of every node
void preOrder(struct node *root)
{
if(root != NULL)
{
preOrder(root->left);
printf("%d ", root->key);
preOrder(root->right);
}
}
/* Drier program to test above function*/
int main()
{
struct node *root = NULL;
/* Constructing tree given in the above figure */
root = insert(root, 9);
root = insert(root, 5);
root = insert(root, 10);
root = insert(root, 0);
root = insert(root, 6);
root = insert(root, 11);
root = insert(root, -1);
root = insert(root, 1);
root = insert(root, 2);
root = insert(root, 10);
printf("Pre order traversal of the constructed AVL tree is \n");
preOrder(root);
root = deleteNode(root, 10);
printf("\nPre order traversal after deletion of 10 \n");
preOrder(root);
return 0;
}
How can i print an element when I give a certain position?
example:
root = insert(root, 100); (add 100)
root = insert(root, 300); (add 300)
root = insert(root, 200); (add 200)
root = insert(root, 200); (add 400)
PRINT 1 -> Should print the first element (sorted). Which is 100
PRINT 3 -> Should print the third element (sorted). Which is 300
How can I implement this PRINT on my AVL Tree?
I tried to modify this function but i did not succeed
void preOrder(struct node *root)
{
if(root != NULL)
{
preOrder(root->left);
printf("%d ", root->key);
preOrder(root->right);
}
}
I couldn't use a if statment here to check what values are passing because they are all passed at the same time.
preOrder function will order the numbers. lower to biggest.
I don't understand why you can't modify preOrder to do that - you just have to "remember" that current position an update it along the way:
int findPositionPreOrder(
struct node *root,
int targetPos,
int curPos)
{
if(root != NULL)
{
int newPos = findPositionPreOrder(root->left, targetPos, curPos);
newPos++;
if (newPos == targetPos)
{
printf("%d\n", root->key);
}
return findPositionPreOrder(root->right, targetPos, newPos);
}
else
{
return curPos;
}
}
And you call it like findPositionPreOrder(root, targetPosition, 0);
This is not an optimal solution - you can break the recursion after finding your desired position instead of traversing the rest of the tree.

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