Delete function of a binary search tree not working properly - c

This is a delete function of a binary search tree coded in C, but this is not working properly. The node which is supposed to be deleted is replaced by a garbage value.
void delete(struct node* root,int data)
{
{
struct node* t1;
if(root==0) {
printf("element not found\n");
} else if(data>root->data) {
delete(root->right,data);
} else if(data<root->data) {
delete(root->left,data);
} else {
if(root->right&&root->left) {
t1=findmin(root->right);
root->data=t1->data;
free(t1);
} else {
t1=root;
if(root->right) {
root=root->right;
} else if(root->left) {
root=root->left;
}
free(t1);
}
}
}
it is working per se, but the node is not getting deleted and is replaced by some garbage value.
struct node* findmin(struct node* t) {
if(t==NULL) {
return NULL;
} else if(t->left) {
findmin(t->left);
} else
return t;
}

You are passing root in the function parameters and then inside the following block of your code you are reassigning it.
else
{
t1=root;
if(root->right)
{
root=root->right;
}
else if(root->left)
{
root=root->left;
}
free(t1);
}
This reassignment is temporary to current function call (because it's been passed by value).
alternatively you can do the same is by returning the new root of the tree after deletion of the specified node.
struct node* delete(struct node* root, int key)
{
if (root == NULL) return root;
if (key < root->key)
root->left = delete(root->left, key);
else if (key > root->key)
root->right = delete(root->right, key);
else
{
// node with only one child or no child
if (root->left == NULL)
{
struct node *temp = root->right;
free(root);
return temp;
}
else if (root->right == NULL)
{
struct node *temp = root->left;
free(root);
return temp;
}
struct node* temp = findmin(root->right);
root->key = temp->key;
root->right = delete(root->right, temp->key);
}
return root;
}

Related

%s is skipping the entire print line - no user input

What's wrong in my code? I successfully created a tree and everything is working fine except printInorder function and print statement in void main. When I try to print with %s its skipping the entire line.
Can you please help me in resolving this? I even tried fflush but it doesn't help me in my case and I don't try any scanf statement in my code.
struct Tree
{
char data[10];
struct Tree *left;
struct Tree *right;
} * root;
struct Tree *createNode(char data[])
{
struct Tree *node = malloc(sizeof(struct Tree));
strcpy(node->data, data);
node->left = node->right = NULL;
insertTree(node, root, data);
}
void insertTree(struct Tree *currentNode, struct Tree *temp, char data[])
{
char fletter=data[0];
if (fletter=='a'||fletter=='e'||fletter=='o'||fletter=='i'||fletter=='u')
{
if (root == NULL)
{
root = currentNode;
printf("inserted at root");
}
else if (temp->left == NULL)
{
temp->left = currentNode;
printf("data inserted successfully at left");
}
else
{
insertTree(currentNode, temp->left,data);
}
}
else
{
if (root == NULL)
{
root = currentNode;
printf("inserted at root");
}
else if (temp->right == NULL)
{
temp->right = currentNode;
printf("data inserted successfully at right");
}
else
{
insertTree(currentNode, temp->right,data);
}
}
}
void printInorder(struct Tree *tmp)
{
if (tmp == NULL)
return;
printInorder(tmp->left);
printf("%s ",tmp->data);
printInorder(tmp->right);
}
void main()
{
struct Tree *root = createNode("saish");
struct Tree *d1 = createNode("ansha");
struct Tree *d2 = createNode("shish");
printf("%s",root->data);
printInorder(root);
}
createNode function doesn't return anything even though it is defined to do so.
void insertTree(struct Tree *currentNode, struct Tree *temp, char data[])
{
char fletter=data[0];
if (fletter=='a'||fletter=='e'||fletter=='o'||fletter=='i'||fletter=='u')
{
if (root == NULL)
{
root = currentNode;
printf("inserted at root");
}
else if (temp->left == NULL)
{
temp->left = currentNode;
printf("data inserted successfully at left");
}
else
{
insertTree(currentNode, temp->left,data);
return node;
}
}

Deleting a node from a binary search tree without recursion

I have a binary search tree. I want to delete a node from it:
void deleteANode(struct node *head, int value) {
//let us find the node
struct node *temp = head;
struct node *parent = NULL;
//let us find the node
while (temp != NULL) {
if (value > temp->data) {
parent = temp;
temp = temp->right;
} else
if (value < temp->data) {
parent = temp;
temp = temp->left;
} else {
//let us check for child nodes
//
if (temp->left == NULL && temp->right == NULL) {
printf("Deleting a leaf.\n");
temp = NULL;
printf("Set temp null.\n");
free(temp);
break;
} else
if (temp->left == NULL || temp->right == NULL) {
printf("Deleting a one child.\n");
//one of the child is null
if (temp->left != NULL) {
parent->left = temp->left;
} else {
parent->right = temp->right;
}
free(temp);
} else {
printf("Deleting two child parent.\n");
//both of them are not NULL
//need to find the pre-order successor
struct node *temp2 = temp->right;
while (temp2->left != NULL) {
temp2 = temp2->left;
}
//found the successor.
temp->data = temp2->data;
free(temp);
}
break;
}
}
}
I am trying to delete a leaf node in this block:
if (temp->left == NULL && temp->right == NULL) {
printf("Deleting a leaf.\n");
temp->data = NULL;
printf("Set temp null.\n");
free(temp);
break;
}
But the above code doesn't work.
I am calling the above method:
deleteANode(head, 3);
The preorder traversal is remains same before and after:
5 4 3 10 7 20 Deleting a leaf. Set temp null.
=============== 5 4 3 10 7 20
What am I doing wrong.
Updated as per #pstrjds comments:
if (temp->left == NULL && temp->right == NULL ) {
printf("Deleting a leaf.\n");
parent->left = NULL;
parent->right = NULL;
free(temp);
temp = NULL;
printf("Set temp null.\n");
break;
}
It's working fine for leaf node. Need to work for node with two children.
In the block of code which is deleting a leaf you are not actually freeing the node nor are you updating the parent node to no longer point to it.
if ( temp -> left == NULL && temp -> right == NULL )
{
printf("Deleting a leaf.\n");
if (parent->left == temp)
{
parent->left = NULL;
}
else
{
parent->right = NULL;
}
free(temp);
temp = NULL;
printf("Set temp null.\n");
break;
}
You could actually remove the line temp = NULL and change the break; to a return statement.
Does your code really work?
It should be like this:
printf("Deleting two child parent.\n");
Node* temp2 = temp->right;
while(temp2->left != NULL)
{
parent = temp2;
temp2 = temp2->left;
}
temp->data = temp2->data;
parent->left = NULL;
delete temp2;
return;
Java Solution
// Java program to demonstrate delete operation in binary search tree
class BinarySearchTree
{
/* Class containing left and right child of current node and key value*/
class Node
{
int key;
Node left, right;
public Node(int item)
{
key = item;
left = right = null;
}
}
// Root of BST
Node root;
// Constructor
BinarySearchTree()
{
root = null;
}
// This method mainly calls deleteRec()
void deleteKey(int key)
{
root = deleteRec(root, key);
}
/* A recursive function to insert a new key in BST */
Node deleteRec(Node root, int key)
{ Node x=root;
Node parent =null;
/* Base Case: If the tree is empty */
while(x!=null)
{
if(x.key>key)
{ parent=x;
x=x.left;
}
else if(x.key<key)
{parent=x;
x=x.right;
}
else
{
if(x.left==null&&x.right==null)
{
System.out.println(x.key+"y1");
if(parent.left==x)
parent.left=null;
else if(parent.right==x)
parent.right=null;
x=null;
break;
}
else
{
System.out.println(x.key+"y2");
if(x.left==null)
{
if(parent.right==x)
parent.right=x.right;
else if(parent.left==x)
parent.left=x.right;
System.out.println(x.key+"yes");
x=null;
break;
}
else if(x.right==null)
{
if(parent.left==x)
parent.left=x.left;
else if(parent.right==x)
parent.right=x.left;
x=null;
break;
}
else
{
Node temp=x;
Node px=null;
temp=temp.right;
while(temp.left!=null)
{ px=temp;
temp=temp.left;
}
x.key=temp.key;
if(px.left==temp)
px.left=null;
else if(px.left==temp)
px.right=null;
temp=null;
break;
}
}
}
}
return root;
}
int minValue(Node root)
{
int minv = root.key;
while (root.left != null)
{
minv = root.left.key;
root = root.left;
}
return minv;
}
// This method mainly calls insertRec()
void insert(int key)
{
root = insertRec(root, key);
}
/* A recursive function to insert a new key in BST */
Node insertRec(Node root, int key)
{
/* If the tree is empty, return a new node */
if (root == null)
{
root = new Node(key);
return root;
}
/* Otherwise, recur down the tree */
if (key < root.key)
root.left = insertRec(root.left, key);
else if (key > root.key)
root.right = insertRec(root.right, key);
/* return the (unchanged) node pointer */
return root;
}
// This method mainly calls InorderRec()
void inorder()
{
inorderRec(root);
}
// A utility function to do inorder traversal of BST
void inorderRec(Node root)
{
if (root != null)
{
inorderRec(root.left);
System.out.print(root.key + " ");
inorderRec(root.right);
}
}
// Driver Program to test above functions
public static void main(String[] args)
{
BinarySearchTree tree = new BinarySearchTree();
/* Let us create following BST
50
/ \
30 70
/ \ / \
20 40 60 80 */
tree.insert(50);
tree.insert(30);
tree.insert(20);
tree.insert(40);
tree.insert(70);
tree.insert(60);
tree.insert(80);
System.out.println("Inorder traversal of the given tree");
tree.inorder();
System.out.println("\nDelete 20");
tree.deleteKey(20);
System.out.println("Inorder traversal of the modified tree");
tree.inorder();
System.out.println("\nDelete 30");
tree.deleteKey(30);
System.out.println("Inorder traversal of the modified tree");
tree.inorder();
System.out.println("\nDelete 50");
tree.deleteKey(50);
System.out.println("Inorder traversal of the modified tree");
tree.inorder();
}
}

How do I find the minimum value in the right subtree of a Binary Search Tree

I am trying to make a deletion function in Binary Search Tree.
I have finished with the deletion function, but I'm having some trouble with the FindMin() function as follows:
BST* delete_node(BST* root, int key)
{
BST* temp;
if (root == NULL)
return root;
else if (key < root->key)
root->left_child = delete_node(root->left_child, key);
else if (key > root->key)
root->right_child = delete_node(root->right_child, key);
else //If the key is found delete it according to the following cases
{
if (root->left_child == NULL && root->right_child == NULL)
{
free(root);
root = NULL;
}
else if (root->left_child == NULL){ //right child exists
temp = root;
root = root->right_child;
free(temp);
}
else if (root->right_child == NULL){ //left child exists
temp = root;
root = root->left_child;
free(temp);
}
else{
temp = FindMin(root->right_child);
root->key = temp->key;
root->right_child = delete_node(root->right_child, temp->key);
}
}
return root; /*Returning the address of node to be reattached to
the parent of the deleted node*/
}
BST* FindMin(BST* root) //This functions finds the minimum key value in the
right subtree
{
BST* temp = NULL;
if (root->left_child != NULL)
{
temp = FindMin(root->left_child);
return temp;
}
else
return root;
}
I'm pretty sure that I'm going to need to fix the FindMin() function to make this work. But I am having trouble with my delete function because every time I delete one node, it gives an error, and I think it's because of FindMin().
This is how I am doing Binary Search Tree.
This is the structure:
struct _Node;
typedef struct _Node* Position;
struct _Node
{
int element;
Position left;
Position right;
};
And this is the function for searching min value:
Position SearchMin(Position P)
{
while(P->left != NULL)
{
P = P->left;
}
return P;
}

Delete function in Binary Tree in C

I'm writing the basic functions for binary tree and everything seems to compile and run, but when i try to use my delete function it doesn't do anything.
After executing i get the same sequence of numbers, so i'm trying to figure out what's wrong with the Delete function, is it logically correct?
#include <stdio.h>
#include <stdlib.h>
typedef struct treeNode
{
int data;
struct treeNode *left;
struct treeNode *right;
}treeNode;
treeNode *Insert(treeNode *node, int data)
{
if(node == NULL)
{
treeNode *temp;
temp = malloc(sizeof(treeNode));
temp->data = data;
temp->left = temp->right = NULL;
return temp;
}
if(data > (node->data))
{
node->right = Insert(node->right, data);
}
else if(data < (node->data))
{
node->left = Insert(node->left, data);
}
return node;
}
treeNode *Delete(treeNode *node, int data)
{
if(node == NULL)
{
printf("element not found\n");
}
else if(data < node->data)
{
node->left = Delete(node->left, data);
}
else if(data > node->data)
{
node->right = Delete(node->right, data);
}
return node;
}
treeNode *Find(treeNode *node, int data)
{
if(node == NULL)
{
return NULL;
}
if(data > node->data)
{
return Find(node->right, data);
}
else if(data < node->data)
{
return Find(node->left, data);
}
else
{
return node;
}
}
void Print(treeNode *node)
{
if(node == NULL)
{
return;
}
Print(node->left);
printf("%d", node->data);
Print(node->right);
}
int main()
{
treeNode *root = NULL;
root = Insert(root, 5);
root = Insert(root, 8);
root = Insert(root, 6);
root = Insert(root, 4);
root = Insert(root, 3);
root = Insert(root, 9);
root = Insert(root, 10);
root = Insert(root, 19);
Print(root);
printf("\n");
root = Delete(root, 5);
root = Delete(root, 8);
Print(root);
printf("\n");
treeNode *temp;
temp = Find(root, 8);
if(temp == NULL)
{
printf("Element 8 not found\n");
}
else
{
printf("Element 8 found\n");
}
temp = Find(root, 5);
if(temp == NULL)
{
printf("element 5 not found\n");
}
else
{
printf("element 5 found\n");
}
}
Basically i was only replacing the node with itself, but this can be solved by replacing the deleted node with the minimum element in the right subtree or the maximum element in the left subtree.
The function that works:
treeNode * Delete(treeNode *node, int data)
{
treeNode *temp;
if(node==NULL)
{
printf("Element Not Found");
}
else if(data < node->data)
{
node->left = Delete(node->left, data);
}
else if(data > node->data)
{
node->right = Delete(node->right, data);
}
else
{
/* Now We can delete this node and replace with either minimum element
in the right sub tree or maximum element in the left subtree*/
if(node->right && node->left)
{
/* Here we will replace with minimum element in the right sub tree */
temp = FindMin(node->right);
node -> data = temp->data;
/* As we replaced it with some other node, we have to delete that node */
node -> right = Delete(node->right,temp->data);
}
else
{
/* If there is only one or zero children then we can directly
remove it from the tree and connect its parent to its child */
temp = node;
if(node->left == NULL)
node = node->right;
else if(node->right == NULL)
node = node->left;
free(temp); /* temp is longer required */
}
}
return node;
}

Iteratively inserting into a binary tree

I came across some threads on StackOverflow but none of them quite cleared my doubts.
So the problem is simple. I need to iteratively insert elements into a binary tree. And this is my code.
BST newNode(int x)
{
BSTNodePtr node = (BSTNodePtr) malloc(sizeof(struct TreeNode));
node->Element = x;
node->Left = NULL;
node->Right = NULL;
return node;
}
BST Insert(int x, BST T)
{
BST temp_node = T;
while( T != NULL) {
if (x < T->Element)
T = T->Left;
else if (x >= T->Element)
T = T->Right;
}
T = newNode(x);
return temp_node;
}
However, when I'm finding the height of this tree I am always getting 0. The height code is
int Height(BST T)
{
if (T == NULL)
return 0;
return 1+(max(Height(T->Left), Height(T->Right)));
}
and this works perfectly fine when I do insertion recursively (using a function with the exact same signature)
What am I missing?
Here:
BST Insert(int x, BST T)
{
BST temp_node = T;
while( T != NULL) {
if (x < T->Element)
T = T->Left;
else if (x >= T->Element)
T = T->Right;
}
T = newNode(x);
return temp_node;
}
You navigate the tree until you hit T == NULL. Then you create a node and assign the pointer to it to T. Then you return the original value of T. You don't modify your tree at all. No node in it is made to point to the newly created node. T is just a local variable.
Couldn't solve the problem that way. This code, however, seems to work.
BST Insert(int x, BST T)
{
BST temp=T;
BST node=(BST)malloc(sizeof(struct TreeNode));
node->Element=x;
node->Left=NULL;
node->Right=NULL;
if (T==NULL)
{
T=node;
return(T);
//printf("%d\n",T->Element);
}
else
{
while(1)
{
if (temp->Element>=node->Element && temp->Left==NULL)
{
temp->Left=node;
break;
}
else if (temp->Element>=node->Element && temp->Left!=NULL)
{
temp=temp->Left;
}
else if (temp->Element<node->Element && temp->Right==NULL)
{
temp->Right=node;
break;
}
else
{
temp=temp->Right;
}
}
return(T);
}
}
Here's My implementation of the aforementioned problem:
bst* newNode(int x)
{
bst* T = new bst;
T->value = x;
T->left_child = T->right_child = NULL;
return T;
}
bst* bst_insert_iter(bst* T,int val)
{
if (T == NULL)
T = newNode(val);
else
{
bst *temp_node = T;
bool flag = true;
while(flag)
{
if (val <= temp_node->value)
{
if (temp_node->left_child == NULL)
{
temp_node->left_child=newNode(val);
flag = false;
}
else
temp_node = temp_node->left_child;
}
else
{
if (temp_node->right_child == NULL)
{
temp_node->right_child=newNode(val);
flag = false;
}
else
temp_node = temp_node->right_child;
}
}
}
return T;
}
You have the bug in your insert function. As I may assume, initially your tree is empty. so the first time you insert a node, the second argument is NULL, right? Then this function always returns NULL to you as you always pass a NULL value.
template <class T>
class TreeNode{
private:
T data;
TreeNode<T>* right,*left;
public:
void setData(T d){
this->data =d;
}
T getData(){
return this->data;
}
void setRight(TreeNode<T>* r){
this->right =r;
}
TreeNode<T>* getRight(){
return this->right;
}
void setLeft(TreeNode<T>* r){
this->left =r;
}
TreeNode<T>* getLeft(){
return this->left;
}
static TreeNode<T>* newNode(T data){
TreeNode<T>* n = new TreeNode<T>();
n->setData(data);
n->setRight(NULL);
n->setLeft(NULL);
return n;
}
};
template <class T>
class BinaryTree{
private:
TreeNode<T>* root;
public:
void insert(T data){
TreeNode<T>* n = TreeNode<T>::newNode(data);
if(root==NULL)
root = n;
else{
TreeNode<T>* t = root;
while(t!=NULL){
if(n->getData() >= t->getData()){
if(t->getRight()==NULL){
t->setRight(n); //newnode attached as right child in tree
t = NULL;
}
else
t = t->getRight();
}
else{
if(t->getLeft()==NULL){
t->setLeft(n); //newnode attached as left child in tree
t=NULL;
}
else
t = t->getLeft();
}
}
}
}
void preorder(){
TreeNode<T>* t = root;
preorderUtil(t);
}
void preorderUtil(TreeNode<T>* node){
if(node==NULL)
return;
preorderUtil(node->getLeft());
cout<<node->getData()<<" ";
preorderUtil(node->getRight());
}
};
Your changes are not reflected in the tree. I followed this way to insert data iteratively and it works fine. The point is making a node inside your binarytree to point the newly created node such that it gets attached to the tree.
Here is my version , it seems to be working.
struct tree{
tree *left;
tree *right;
int key;
};
void insertBst(int k,tree *t)
{
tree *newK = new tree[sizeof(tree)];
newK->key = k;
newK->left = NULL;
newK->right = NULL;
if((t)->key == NULL)
{
t=newK;
return;
}
else{
bool found = false;
tree *root = t;
tree *parent = NULL;
while(root != NULL)
{
parent = root;
if(root->key < newK->key)
{
root=root->right;
}
else if(root->key > newK->key)
{
root=root->left;
}
else{
//Here we have duplicates!! so do nothing
root = root;
}
}
if(parent->key > newK->key) parent->left = newK;
else parent->right = newK;
}
}

Resources