deleting an element in AVL trees in C - c

struct node *delete(struct node *root, int key)
{
struct node *remove_node;
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 {
if ((root->left == NULL) && (root->right != NULL)){
remove_node = root->right;
*root = *remove_node;
deletetree(remove_node); // this is for free-ing the memory
} else if ((root->right == NULL) && (root->left != NULL)){
remove_node = root->left;
*root = *remove_node;
deletetree(remove_node);
} else if ((root->right == NULL) && (root->left == NULL)){
remove_node = root;
root = NULL;
} else {
remove_node = successor(root);
root->key = remove_node->key;
root->right = delete(root->right, remove_node->key);
}
}
if (root == NULL) {
return root;
if (balance_factor(root) == 2){
if (balance_factor(root->left) == -1) {
return single_right_rotation(root);
} else if (balance_factor(root->left) == 1) {
return double_left_rotation(root);
}
}
if (balance_factor(root) == -2) {
if (balance_factor(root->right) == -1) {
return single_left_rotation(root);
}
else if (balance_factor(root->right) == 1) {
return double_right_rotation(root);
}
}
}
return root;
}
Here's my code for deleting an element in an AVL tree. Everything seems to work fine, it handles all the case when node n has no children, one children and two children. But for some odd reason it does not balance the tree nor does it reaches that block of code.
Hopefully someone can help me debug the code cause I cannot find where "exactly" the error is coming from.
Thanks in Advance
PS: the successor function just returns the minimum element on the right tree of the node to be deleted and the deletetree deals with free-ing memory allocation stuffs.
Also i am 100% that my rotations work because it worked perfectly in my insert function.

You can use temp root, as reference and you can change like this:
struct node *localRoot = root;
And you change roots to localRoot, probably the problem is solved.
I hope it is helpfull.

Related

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();
}
}

Deleting node in C BST

I have a problem with deleting node when I have two children, i don't have any idea what to do, cuz I have solved problem with no children, left child and right child
struct Node* deleteNode(Node *root, int val)
{
if(root == NULL) return root;
else if(val < root->data)
root->left = deleteNode(root->left,val);
else if(val > root->data)
root->right = deleteNode(root->right, val);
else
{
if(root->left == NULL && root->right == NULL)
{
free(root);
root = NULL;
}
else if(root->left == NULL)
{
Node *temp = root;
root = root->right;
free(temp);
}
else if(root->right == NULL)
{
Node *temp = root;
root = root->left;
free(temp);
}
}
If I understand your question correctly, you must make one sub-node a child of the other. You'll have to do another recursive function for the add, in case neither sub node has degree < 1

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;
}

How to find a leaf node in a binary NOT SORTED tree

I want to find a leaf node in an unsorted binary tree and be able to use it in other functions.
i have this as an idea
UPDATED****
node * leaf(node* root)
{
if(root==NULL)
return NULL;
if(root->left==NULL && root->right==NULL)
return root;
else
{ leaf(root->left);
leaf(root->right);
}
}
Try this:
If root has no children, then root is leaf node.
If root has left child, then the left child must have a leaf node.
Same as right child.
node* leaf(node* root) {
if(root == NULL)
return NULL;
if(root->left == NULL && root->right == NULL) {
return root;
} else if(root->left != NULL) {
return leaf(root->left);
} else {
return leaf(root->right);
}
}

Binary Search Tree can't delete the root

Everything is working fine in this function, but the problem is that I can't delete the root, I couldn't figure out what's the bug here.I've traced the "else part" it works fine until the return, it returns the old value I don't know why. Plz Help!
node *removeNode(node *Root, int key) {
node *tmp = new node;
if(key > Root->value)
Root->right = removeNode(Root->right,key);
else if(key < Root->value)
Root->left = removeNode(Root->left, key);
else if(Root->left != NULL && Root->right != NULL) {
node *minNode = findNode(Root->right);
Root->value = minNode->value;
Root->right = removeNode(Root->right,Root->value);
}
else {
tmp = Root;
if(Root->left == NULL)
Root = Root->right;
else if(Root->right == NULL)
Root = Root->left;
delete tmp;
}
return Root;
}
Change
removeNode(Root, key);
To
Root = removeNode(Root, key);
Root wasn't modify by removeNode because you pass a copy of the variable.
Using this style, where the result is the new tree, never forget to update the root:
Root = removeNode(Root, key);
Futhermore an empty tree must be tested for (Root == NULL)
node *removeNode(node *Root, int key) {
if(Root == NULL) // Or if(!Root) return Root;
return NULL;
if(key > Root->value)
Root->right = removeNode(Root->right,key);
else if(key < Root->value)
Root->left = removeNode(Root->left, key);
else if(Root->left != NULL && Root->right != NULL) {
node *minNode = findNode(Root->right); // Left most leaf
Root->value = minNode->value;
Root->right = removeNode(Root->right,Root->value);
}
else {
node *found = Rppt;
if(Root->left == NULL)
Root = Root->right;
else if(Root->right == NULL)
Root = Root->left;
delete found;
}
return Root;
}
Alternative style: using variable aliases
removeNode(&Root, key);
void removeNode(node **ptr_var, int key) {
node *ptr = *ptr_var;
if (!ptr)
return;
if (key > ptr->value)
removeNode(&ptr->right,key);
else if(key < ptr->value)
removeNode(&ptr->left, key);
else if(ptr->left && ptr->right) {
node **minNode = &ptr->right;
while (*minNode) {
minNode = &(*minNode)->left;
}
ptr->value = (*minNode)->value;
delete *minNode;
*minNode = NULL;
}
else {
if(! ptr->left)
*ptr_var = ptr->right;
else if(!ptr->right)
*ptr_var = ptr->left;
delete ptr;
}
}

Resources