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
Related
I am trying to delete a node having 2 chidren in a binary search tree. However i am facing little problem here. While deleting node(node with data=30) with children (left->data=20,right->data=40), I am replacing the node with its inorder successor (which is node with data=40) and then deleting the inorder successor. After deletion the node's data is successfully replaced (new value being 40) but the inorder successor is not being deleted/freed properly.
Expected Output [inorder traversal]: 20->40->50->60->70->80->
Output[inorder traversal]: 20->40->0->50->60->70->80->
After 40, why is the value 0 appearing?
#include<stdio.h>
#include<stdlib.h>
struct Node
{
int data;
struct Node *left;
struct Node *right;
};
struct Node* temp = NULL,*temp1 = NULL;
struct Node *newNode(int data)
{
struct Node *node = (struct Node*)malloc(sizeof(struct Node));
node->data = data;
node->left = node->right = NULL;
return node;
}
struct Node* insert(struct Node* root,int data)
{
if(root == NULL)
{
return newNode(data);
}
if(data < root->data)
root->left = insert(root->left,data);
else
root->right = insert(root->right,data);
}
void inorder(struct Node* root)
{
if(root!=NULL)
{
inorder(root->left);
printf("%d->",root->data);
inorder(root->right);
}
else
{
return;
}
}
/*to find the inorder successor*/
struct Node *minVal(struct Node *root)
{
while(root->left !=NULL)
{
temp = root;
root = root->left;
}
return root;
}
void deleteNode(struct Node *root,int data)
{
if(data < root->data)
{
temp = root;
deleteNode(root->left,data);
}
else if(data > root->data)
{
temp = root;
deleteNode(root->right,data);
}
else if(data == root->data)
{ /*deleting leaf nodes*/
if(root->left == NULL && root->right == NULL)
{
if(temp->left == root)
temp->left = NULL;
else
if(temp->right == root)
temp->right = NULL;
free(root);
root = NULL;
return;
}
/*deleting nodes having single child*/
else if(root->left !=NULL && root->right == NULL)
{
temp1 = root->left;
temp->left = temp1;
free(root);
root = NULL;
}
else if(root->left ==NULL && root->right != NULL)
{
temp1 = root->right;
temp->right = temp1;
free(root);
root = NULL;
}
/*deleting nodes having 2 children*/
else if(root->left !=NULL && root->right !=NULL)
{
struct Node *temp2 = minVal(root->right);
root->data = temp2->data;
deleteNode(root->right,temp2->data);
}
}
}
int main()
{
struct Node *root = NULL;
printf("\n\n");
root = insert(root, 50);
insert(root, 30);
insert(root, 20);
insert(root, 40);
insert(root, 70);
insert(root, 60);
insert(root, 80);
inorder(root);
//deleteNode(root,40);
deleteNode(root,30);
printf("\n\n");
inorder(root);
printf("\n\n");
}
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;
}
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);
}
}
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;
}
}
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.