Binary Search Tree can't delete the root - c

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

Related

Issue while removing elements in Binary Search Tree

When I remove the nodes which have zero children, it removes the entire branch starting from the head i.e. if I remove a leaf node from the right subtree, it removes the right branch and same for the left.
If I remove any child with 2 children, it replaces it with the leftmost node of the right subtree and then removes the entire right branch from where I am taking the leftmost node.
struct Node{
struct Node *left;
int value;
struct Node *right;
};
typedef struct Node node;
node * removeEle(node **root, int value){
if((*root) == NULL){
return NULL;
}else{
if(value < (*root)->value && (*root)->left != NULL){
(*root)->left = removeEle(&(*root)->left, value);
}else if(value > (*root)->value && (*root)->right != NULL){
(*root)->right = removeEle(&(*root)->right, value);
}else{
if((*root)->left == NULL && (*root)->right == NULL){
return NULL;
}else if((*root)->left == NULL && (*root)->right != NULL){
return (*root)->right;
}else if((*root)->left != NULL && (*root)->right == NULL){
return (*root)->left;
}
else{
node * check = leftMost(&(*root)->right);
(*root)->value = check->value;
(*root)->right = removeEle(&(*root)->right, check->value);
return (*root);
}
}
if((*root) == NULL){
printf("Helloworld");
exit(1);
}
}
}
node * leftMost(node **root){
while((*root)->left != NULL){
(*root) = (*root)->left;
}
return (*root);
}
void traversal(node *root){
if(root == NULL)return;
printf("%d\n", root->value);
if(root->left != NULL) traversal(root->left);
if(root->right != NULL) traversal(root->right);
}
void add(node **root, int value){
if((*root) == NULL){
(*root) = createNode();
(*root)->value = value;
}
if((*root)->value > value){
if((*root)->left == NULL){
(*root)->left = createNode();
(*root)->left->value = value;
}else{
add(&((*root)->left), value);
}
}else if((*root)->value < value){
if((*root)->right == NULL){
(*root)->right = createNode();
(*root)->right->value = value;
}else{
add(&((*root)->right), value);
}
}
}
node *createNode(){
node *node = malloc(sizeof(struct Node));
node->left = NULL;
node->right = NULL;
return node;
}
This is my test case.
int main(){
node *root = NULL;
add(&root, 10);
add(&root, 20);
add(&root, 5);
add(&root, 6);
add(&root, 2);
add(&root, 23);
add(&root, 12);
removeEle(&root, 10);
traversal(root);
}
All the functions except removal, works fine.

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

Binary search tree delete not working, why?

I am trying to implement Binary search tree in C.
But I am stuck at the delete operation, when I run the code it doesn't delete the value specified.
Before calling delete:(calling inorder())
16 19 23
After calling delete:(calling inorder())
16 19 23
code:
void deleteNode(struct node *n, int data)
{
struct node *temp;
if(n->data==data)
{
if(n->left == NULL && n->right == NULL)
{
n=NULL;
}
else if(n->left == NULL && n->right!=NULL)
{
n->data = (n->right)->data;
n->right = NULL;
}
else if(n->left!=NULL && n->right == NULL)
{
n->data = (n->left)->data;
n->left=NULL;
}
else if(n->left != NULL && n->right != NULL)
{
temp = findMax(root);
n->data = temp->data;
temp = NULL;
}
}
else if(n->data > data)
{
deleteNode(n->left, data);
}
else if(n->data < data)
{
deleteNode(n->right, data);
}
}
I have other code which is working, but I want to know what is wrong with this code?
Edit:
I have edited the code with a few changes in it.
Now, When I try to delete the ROOT node.
I end up with this:
(inorder traversal)-> 16 23 23
Now,
Why is this happening when temp = NULL is making the maximum node NULL.
Note: I am not initializing temp as the code has been changed and it is initialized just before its use (temp = findMax(root)).
code inorder():
void inorder(struct node *root)
{
if(root!=NULL)
{
inorder(root->left);
printf("%d\n", root->data);
inorder(root->right);
}
}
Use this alternative code or use your temp tree in your method
struct node *temp = n; //then use temp tree in code
Alternative method
struct node *delete(struct node *tree, int data)
{
if(find(tree,data)==-1 || tree == NULL)
return tree;
if(tree->data == data)
{
if(tree->left==NULL && tree->right==NULL)
return NULL;
if(tree->right != NULL){
tree->data = min(tree->right);
tree->right = delete(tree->right,min(tree->right));
return tree;
}
tree->data = madata(tree->left);
tree->left = delete(tree->left,madata(tree->left));
return tree;
}
if(tree->data < data)
{
tree->right= delete(tree->right,data);
return tree;
}
tree->left= delete(tree->left,data);
return tree;
}
This is what worked for me,
struct node* deleteNode(struct node *n, int data)
{
struct node *temp;
temp = n;
if(n->data==data)
{
if(n->left == NULL && n->right == NULL)
{
n=NULL;
return NULL;
}
else if(n->left == NULL && n->right!=NULL)
{
n = n->right;
temp = NULL;
}
else if(n->left!=NULL && n->right == NULL)
{
n = n->left;
temp = NULL;
}
else if(n->left != NULL && n->right != NULL)
{
temp = findMax(root);
n->data = temp->data;
temp = NULL;
}
}
else if(n->data > data)
{
n->left = deleteNode(n->left, data);
}
else if(n->data < data)
{
n->right = deleteNode(n->right, data);
}
return n;
}

deleting an element in AVL trees in 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.

Resources