I have a binary tree. I'm trying to delete one of the node and all of his "children". But, my function deletes just the children and the "father" is still remaining there. whats wrong with my code? why the "father" isnt Deleted??
BinTree* familyGotVaccin(BinTree* root)
{
int isFather = 1;
BinTree* father = NULL;
BinTree* gotVaccinated = NULL;
int ID;
if (root == NULL)
return NULL;
printf("Who got vaccinated (ID)?\n");
scanf("%d", &ID);
if (checkIfExist(root, ID) == 0)
{
printf("There is no ID %d\n", ID);
return root;
}
if (root->ID == ID)
{
gotVaccinated = root;
isFather=0;
}
else
{
father = findNode(root, ID);
if (father == NULL)
return root;
if (father->left != NULL && father->left->ID == ID)
gotVaccinated = father->left;
if (father->middle != NULL && father->middle->ID == ID)
gotVaccinated = father->middle;
if (father->right != NULL && father->right->ID == ID)
gotVaccinated = father->right;
}
gotVaccinated=deleteVaccinated(gotVaccinated);
free(gotVaccinated);
if (isFather == 0)
root = NULL;
return root;
}
BinTree* deleteVaccinated(BinTree* root)
{
if (root == NULL)
return NULL;
if (root->left == NULL && root->middle == NULL && root->right == NULL)
{
printf("%s ID: %d Survived!\n", root->name, root->ID);
root = NULL;
free(root);
return NULL;
}
if (root->left != NULL)
root->left=deleteVaccinated(root->left);
if (root->middle != NULL)
root->middle=deleteVaccinated(root->middle);
if (root->right != NULL)
root->right=deleteVaccinated(root->right);
printf("%s ID: %d Survived!\n", root->name, root->ID);
root = NULL;
free(root);
return NULL;
}
Related
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 1 year ago.
Improve this question
B_S_T.c:38:17: error: implicit declaration of function 'elseif' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
elseif(ptr == parptr->left)
^
B_S_T.c:38:44: error: expected ';' after expression
elseif(ptr == parptr->left)
^
;
B_S_T.c:42:17: error: expected expression
else
^
3 errors generated.
Why this code is giving me these 3 errors?
#include <stdio.h>
#include <stdlib.h>
struct BST
{
struct BST *left;
int item;
struct BST *right;
};void del(struct BST **r, int data)
{
struct BST *ptr, *parptr, *pred, *parpred;
if (*r == NULL)
printf("Underflow");
else
{
parptr = NULL;
ptr = *r;
while (ptr->item != data && ptr != NULL)
{
if (ptr->item > data)
{
parptr = ptr;
}
else
{
parptr = ptr;
ptr = ptr->right;
}
}
if (ptr == NULL)
printf("Data not found");
else
{
if (ptr->left == NULL && ptr->right == NULL)
{
if (parptr == NULL)
*r = NULL;
elseif(ptr == parptr->left)
{
parptr->left = NULL;
}
else
{
parptr->right = NULL;
}
free(ptr);
}
else if (ptr->left == NULL || ptr->right == NULL)
{
if (parptr == NULL)
{
if (ptr->left != NULL)
*r = ptr->left;
else
*r = ptr->right;
}
if (ptr == parptr->left)
{
if (ptr->left != NULL)
parptr->left = ptr->left;
else
parptr->left = ptr->right;
}
else
{
if (ptr->left != NULL)
parptr->right = ptr->left;
else
parptr->right = ptr->right;
}
free(ptr);
}
else
{
pred = ptr->left;
parpred = ptr;
while (pred->right != NULL)
{
parpred = pred;
pred = pred->right;
}
ptr->item = pred->item;
if (pred == parpred->left)
{
parpred->left = pred->left;
}
else
{
parpred->right = pred->left;
}
free(pred);
}
}
}
}
void insert(struct BST **r, int data)
{
struct BST *n, *ptr;
n = (struct BST *)malloc(sizeof(struct BST));
n->item = data;
n->left = NULL;
n->right = NULL;
if (*r == NULL)
*r = n;
else
{
ptr = *r;
while (1)
{
if (ptr->item == data)
{
printf("Duplicate item cannot be inserted");
free(n);
break;
//duplicate data
}
else if (ptr->item > data)
{
if (ptr->left == NULL)
{
ptr->left = n;
break;
}
else
ptr = ptr->left;
//insert in left sub tree
}
else
{
if (ptr->right == NULL)
{
ptr->right = n;
break;
}
else
ptr = ptr->right;
//insert in right sub tree
}
}
}
}
//traversing
void postorder(struct BST *root)
{
if (root != NULL)
{
if (root->left != NULL)
postorder(root->left);
if (root->right != NULL)
postorder(root->right);
printf("%d ", root->item);
}
}
void preorder(struct BST *root)
{
if (root != NULL)
{
printf("%d ", root->item);
if (root->left != NULL)
preorder(root->left);
if (root->right != NULL)
preorder(root->right);
}
}
void inorder(struct BST *root)
{
if (root != NULL)
{
if (root->left != NULL)
inorder(root->left);
printf("%d ", root->item);
if (root->right != NULL)
inorder(root->right);
}
}
int main()
{
struct BST *root = NULL;
int data = 50;
insert(&root, 50);
insert(&root, 70);
insert(&root, 30);
insert(&root, 60);
insert(&root, 40);
insert(&root, 10);
del(&root, data);
printf("\nPreorder: ");
preorder(root);
printf("\nIorder: ");
inorder(root);
printf("\nPostorder: ");
postorder(root);
return 0;
}
Replace "elseif" with "else if".
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;
}
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;
}
}
I am trying to create a Tree data structure which stores information about the Olympic Venues. I have just run into a roadblock and I have realized that my delete function always returns "Element Not Found" and my DFS will find the correct node, but then continue to print out the right side of the tree.
Tree * preorder_find(char * find_city, Tree* T)
{
if(T)
{
//if(strcmp(T->Element->city, find_city) == 0)
//return T;
printf("%s, %s ... %d\n", T->Element->city, T->Element->country,
T->Element->year);
if(strcmp(T->Element->city, find_city) != 0)
{
preorder_find(find_city, T->Left);
preorder_find(find_city, T->Right);
}
}
return T;
}
Tree* delete(char * venue, Tree* T)
{
Tree* tmp_node;
if(T==NULL)
fprintf(stderr, "Element not Found\n");
else
if(strcmp(venue, T->Element->city) < 0)
T->Left = delete(venue, T->Left);
else
if(strcmp(venue, T->Element->city) > 0)
T->Right = delete(venue, T->Left);
else
if(T->Left && T->Right)
{
tmp_node = find_min(T->Right);
T->Element = tmp_node->Element;
T->Right = delete(T->Element->city, T->Right);
}
else
{
tmp_node = T;
if(T->Left == NULL)
T = T->Right;
else if(T->Right == NULL)
T = T->Left;
free(tmp_node);
}
return T;
}
Please try this preorder_find()
Tree * preorder_find(char * find_city, Tree* T)
{
Tree *temp;
if(T)
{
if(strcmp(T->Element->city, find_city) == 0)
return T;
printf("%s, %s ... %d\n", T->Element->city, T->Element->country,
T->Element->year);
if(strcmp(T->Element->city, find_city) != 0)
{
if ((temp = preorder_find(find_city, T->Left))
|| (temp = preorder_find(find_city, T->Right)))
return temp;
}
}
return T;
}
my delete function always returns "Element Not Found"
According to your delete(), this means the argument T of delete() always is NULL.
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.