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.
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 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;
}
I'm having a problem when using linked list to build a queue program. Here's the full code.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#define ERROR_VALUE -300000
typedef struct LinkedNode {
int data;
struct LinkdedNode* link;
}Node;
Node* front;
Node* rear;
void init_queue() { front = rear = NULL; }
int is_empty() { return (front = NULL && rear == NULL); }
int size() {
Node* p;
int count = 0;
if (is_empty())
return 0;
for (p = front; p != rear; p = p->link) {
count++;
return count + 1;
}
}
void enqueue(int e) {
Node* p = (Node*)malloc(sizeof(Node));
p->data = e;
p->link = NULL;
if (is_empty())
front = rear = p;
else {
rear->link = p;
rear = p;
}
}
int dequeue() {
Node* p = front;
int e;
if (is_empty()) {
printf("Queue Empty Error!\n");
return ERROR_VALUE;
}
else if (size() == 1) {
front = rear = NULL;
}
else
front = p->link;
e = p->data;
free(p);
return e;
}
int peek() {
if (is_empty()) {
printf("Queue Empty Error!\n");
return ERROR_VALUE;
}
return front->data;
}
void print_queue() {
Node* p;
printf("QUEUE STATUS: size=%d\n", size());
if (is_empty())
return;
for (p = front; p != NULL; p = p->link)
printf("[%2d] ", p->data);
printf("\n");
}
int main(void) {
int val, sel;
init_queue();
while (1) {
do {
printf("1.ENQUEUE 2.DEQUEUE 3.PEEK 4.STATUS 0.EXIT :");
scanf("%d", &sel);
} while (sel < 0 || sel > 4);
if (sel == 1) {
printf("1.ENQUEUE VALUE ? ");
scanf("%d", &val);
enqueue(val);
}
else if (sel == 2) {
val = dequeue();
if (val != ERROR_VALUE)
printf("2.DEQUEUE VALUE = %d\n", val);
}
else if (sel == 3) {
val = peek();
if (val != ERROR_VALUE)
printf("3.PEEK VALUE = %d\n", val);
}
else if (sel == 4)
print_queue();
else if (sel == 0) break;
}
return 0;
}
I didn't made is_full() function because linked list is "dynamic". When debugging, the program stops when I try enqueuing value. My guess is that there is something wrong in enqueue function, but cannot find what.
This is wrong:
int is_empty() { return (front = NULL && rear == NULL); }
Note the front = NULL. That means every time you call is_empty(), front gets set to NULL, which then causes is_empty() to return 0 because front = NULL evaluates to NULL.
You need to change is_empty() to
int is_empty() { return (front == NULL && rear == NULL); }
And this is exactly why many programmers use "Yoda conditions" like NULL == front - they prevent this type of bug because if you write = instead of == the code will fail to compile.
And, as you've noticed, such bugs are very hard to spot in your own code.
I simply want to delete a node from the BST and this gives me an error that new is undefined.
The ADT is like this:
typedef struct BSTNode *BSTree;
struct BSTNode {
int value;
BSTree left;
BSTree right;
};
BSTree Delete(BSTree t, int item) {
if (item < t->value) {
t->left = Delete(t->left, item);
} else if (item > t->value) {
t->right = Delete(t->right, item);
} else {
// deleting item
if (t->left == NULL && t->right == NULL) {
BSTree new = NULL;
} else if (t->left == NULL) {
BSTree new = t->right;
} else if (t->right == NULL) {
BSTree new = t->left;
// } else {
//BSTree new = joinTrees(t->left, t->right);
}
free(t);
t = new;
}
The problem is that you are declaring multiple variables that only exist within each containing conditional block. Declare the variable at the top of the function or top of the else block. Then set that same variable in each conditional block of code.
BSTree Delete(BSTree t, int item) {
BSTree new_item;
if (item < t->value) {
t->left = Delete(t->left, item);
} else if (item > t->value) {
t->right = Delete(t->right, item);
} else {
// deleting item
if (t->left == NULL && t->right == NULL) {
new_item = NULL;
} else if (t->left == NULL) {
new_item = t->right;
} else if (t->right == NULL) {
new_item = t->left;
// } else {
//BSTree new = joinTrees(t->left, t->right);
}
free(t);
t = new_item;
}
I am trying to write a function to delete a node(any node) from a binary search tree. For some reason, the delete function deletes multiple nodes. It is a recursive function and I am somewhat confused when it comes to resursion. below is my code, can somebody help me figure out what went wrong.
Thanks in advance
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct node *nodeP;
typedef struct StudentRoster *StudentRosterP;
struct node
{
nodeP left;
char name[30];
int ID;
nodeP right;
};
struct StudentRoster
{
nodeP root;
int size;
};
//create a new student roster
StudentRosterP newStudentRoster()
{
StudentRosterP new;
new = NULL;
new = malloc(sizeof(struct StudentRoster));
if (new == NULL)
{
fprintf(stderr, "Error: Memory allocation for Student Roster failed\n");
return NULL;
}
else
{
new->root = NULL;
new->size = 0;
return new;
}
}
//creates a new node to store student information
nodeP newNode(char *name, int ID)
{
nodeP new;
new = NULL;
new = malloc(sizeof(struct node));
if(new == NULL)
{
fprintf(stderr, "Memory allocation for the node failed.\n");
return NULL;
}
else
{
new->left = NULL;
new->right = NULL;
new->ID = ID;
strcpy(new->name, name);
return new;
}
}
//function to insert student. this is a helper function, recursive call
void insert(nodeP root, int ID, char * name)
{
if (ID == root->ID)
{
printf("Duplicate IDs not allowed\n");
return;
}
else {
if(ID < root->ID)
{
if(root->left == NULL)
{
root->left = newNode(name, ID);
}
else
{
root = root->left;
insert(root, ID, name);
}
}
else
{
if(root->right == NULL)
{
root->right = newNode(name, ID);
}
else
{
root = root->right;
insert(root, ID, name);
}
}
}
}
//to insert new student
void insertStudentRoster(StudentRosterP roster, char * name, int ID)
{
nodeP root = roster->root;
if(roster->root == NULL) // its empty
{
roster->root = newNode(name, ID);
}
else {
if (ID == roster->root->ID)
{
printf("Duplicate IDs not allowed\n");
return;
}
else
{
insert(roster->root, ID, name);
}
}
}
/*
* Helper function for removeStudentRoster
* finds a node to be deleted and returns its pointer
*/
nodeP findMin(nodeP node)
{
while(node->left != NULL)
{
node = node->left;
}
return node;
}
//removes the node to be deleted
//returns null pointer to the parent function
//This is where I am having problem
nodeP delete(nodeP root, int ID)
{
if(root == NULL)
{
return root;
}
else if(ID < root->ID)
{
root->left = delete(root->left, ID);
}
else if(ID > root->ID)
{
root->right = delete(root->right, ID);
}
else
{
if (root->left == NULL && root->right == NULL)
{
free(root);
root = NULL;
}
else if(root->left == NULL)
{
nodeP temp = root;
root = root->right;
free(temp);
}
else if(root->right == NULL)
{
nodeP temp = root;
root = root->left;
free(temp);
}
else
{
nodeP temp = findMin(root->right);
root->ID = temp->ID;
strcpy(root->name, temp->name);
root->right = delete(root->right, temp->ID);
}
return root;
}
}
/*
* Removes the node containing the matching names
* Parameters: StudentRoster, id
*/
void removeStudentRoster(StudentRosterP roster, int ID)
{
if(roster == NULL)
{
printf("The Student roster does not exist\n");
return;
}
else if(roster->root == NULL)
{
printf("The Student roster is empty\n");
return;
}
else{
//find the node to be deleted
roster->root = delete(roster->root, ID);
}
}
//for printing in ordered
void inOrder(nodeP node)
{
if (node == NULL)
return;
inOrder(node->left);
printf("ID #: %i, Name: %s \n", node->ID, node->name);
inOrder(node->right);
}
/*
* Displays all the entries in the Phone book in order
* Display one person per line, ID followed by first name
*/
void displayStudentRoster(StudentRosterP roster)
{
if (roster->root == NULL) {
printf("The Roster is empty");
return;
}
else
{
inOrder(roster->root);
return;
}
}
int main()
{
StudentRosterP newRoster;
newRoster = newStudentRoster();
insertStudentRoster(newRoster, "Alice", 10);
insertStudentRoster(newRoster, "Jake", 8);
insertStudentRoster(newRoster, "josh", 12);
insertStudentRoster(newRoster, "Alen", 9);
insertStudentRoster(newRoster, "Joe", 11);
removeStudentRoster(newRoster, 11); //it removes the whole roster when removing a node that has no childrens
//when removing the root, it also removes the right child
displayStudentRoster(newRoster);
return (EXIT_SUCCESS);
}
In your delete function, your return is misplaced (only reached when ID matches root->ID). You need to move it past the next closing brace to place it after the else it's in:
}
/* "return root;" was here... */
}
return root; /* ..but should be here. */
}
Additionally, the logic seems wrong for deleting the node when ID does match (in that last else). What you need to do is either move the right branch to the rightmost node in the left branch, or the left branch to the leftmost node of the right branch... then return that branch. So using your findMin() to find the leftmost part of the right branch, we can do:
else
{
nodeP temp = findMin(root->right);
temp->left = root->left;
temp = root;
root = root->right;
free(temp);
}