Binary Search Tree node deletion error - c

I've created my binary search tree and gave the pointer to the node which I want to delete into my *p.
The delete method is supposed to be deleting the node which is pointed at by *p and should add the subtrees with addtree to my root. *pBaum is the pointer which points to my root.
However im getting an error message called "conflict types" on addtree everytime I declare
Baum = addtree(Baum, p->right);
I also get a warning "assignment makes pointer from integer without a cast"
My struct contains left & right pointer to the subtrees and a pointer to the content.
struct tnode
{
int content;
struct tnode *left; /* linker Teilbaum */
struct tnode *right; /* rechter Teilbaum */
};
// Deletes the node where *p is pointing at
struct tnode *deletenode(struct tnode *p, struct tnode *pBaum)
{
struct tnode *Baum = pBaum;
if ((p->left == NULL) && (p->right == NULL))
{
free(p);
}
if ((p->left == NULL) && (p->right != NULL))
{
Baum = addtree(Baum, p->right);
free(p);
}
if ((p->right == NULL) && (p->left !=NULL))
{
Baum = addtree(Baum, p->left);
free(p);
}
if ((p->left != NULL) && (p->right !=NULL))
{
Baum = addtree(Baum, p->right);
Baum = addtree(Baum, p->left);
free(p);
}
return Baum;
}
// Adds the Subtrees to my root
struct tnode *addtree(struct tnode *top, struct tnode *p)
{
if (p == NULL)
return top;
else
return addtree(addtree(addelement(top, p->content),p-> right), p->left);
// Adds a node to my Tree
struct tnode *addelement(struct tnode *p, int i)
{
int cond;
if (p == NULL)
{
p = talloc(); /* make a new node */ p->content = i;
p->left =p->right =NULL;
}
else if (p->content == i)
{
return p;
}
else if (i < p->content) /* goes into left subtree */ p->left =addelement(p->left, i);
else /* goes into right subtree */ p->right = addelement(p->right, i);
return p;
}
// Looks for the node which is supposed to get deleted and returns a pointer to it
struct tnode *searchnode(struct tnode *p, int nodtodelete)
{
if (p == NULL)
{
printf("Baum ist leer oder Element nicht vorhanden \n");
return NULL;
}
if ( p -> content == nodtodelete)
{
return p;
}
if (p->content < nodtodelete)
{
return searchnode (p->right, nodtodelete);
}
if (p->content > nodtodelete)
{
return searchnode(p->left, nodtodelete);
}
}
}
int main()
{
struct tnode *Baum = NULL;
struct tnode *tmpPos = NULL;
Baum = addelement (Baum, 32);
Baum = addelement(Baum, 50);
Baum = addelement(Baum, 60);
tmpPos = searchnode(Baum,50);
Baum = deletenode(tmpPos, Baum);
}

Have you declare the function before function call in code ? i declare the addtree and addelement functions on top of the file and error for conflict types is gone.

I'm not sure if this is due to you only including partial code, but you addtree function is not complete:
struct tnode *addtree(struct tnode *top, struct tnode *p)
{
if (p == NULL)
return top;
else
return addtree(addtree(addelement(top, p->content),p-> right), p->left);
This function needs to be ended with a bracket:
struct tnode *addtree(struct tnode *top, struct tnode *p)
{
if(p == NULL)
return top;
return addtree(addtree(addelement(top, p->content), p->right), p->left);
}
To make it so the compiler doesn't potentially complain about not returning a value in a non void function it's best to get rid of the else as well.

Related

why my C structure must add a weird int and it affect the pointer?

this is a binary tree queue problem
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define NUM 10
typedef struct _node
{
int value;
struct _node *left;
struct _node *right;
}TNode,*Tree;
add a *next in q_node is my purpose
other wise , we need to add in the Tree node struct
So, for the sake of doesn't modify the struct of tree
I design a q_node struct to include it
we can use define command to make it as a template.
typedef struct _q_node
{
TNode *t_node;
int length;
struct _q_node *next;
}QNode;
typedef struct _Queue
{
QNode *head;
QNode *tail;
}Queue;
Queue* init_queue()
{
Queue *queue=(Queue*)malloc(sizeof(Queue));
queue->head = queue->tail = NULL;
return queue;
}
int enQueue(Queue *pQueue,TNode *pTNode)
{
QNode *pQNode = (QNode *)malloc(sizeof(QNode));
pQNode->t_node = pTNode;
if(pQueue->head == NULL)
{//when it's empty
pQueue->head = pQNode;
pQueue->tail = pQNode;
}
else
{
pQueue->tail->next = pQNode;
pQueue->tail = pQNode;
}
}
QNode* deQueue(Queue *pQueue)
{
if(pQueue->head == NULL)
{
return NULL;
}
QNode *deNode= pQueue->head;
pQueue->head = pQueue->head->next;
return deNode;
}
TNode* init_TNode(int value)
{
TNode *new_node = (TNode*)malloc(sizeof(TNode));
new_node->value=value;
new_node->left = new_node->right = NULL;
return new_node;
}
//0:empty
int ifEmpty(Queue *pQueue)
{
if(pQueue->head == NULL)
{
//printf("empty tree\n");
return 0;
}
//printf("queue is not empty\n");
return 1;
}
int insert_tree(Tree pTree,int pValue)
{
//found NULL sub tree, then add to his father->left
if(!pTree)
{
return 0;
}
TNode *tNode = init_TNode(pValue);
if(tNode==NULL)
{
printf("create TNode error!\n");
return 0;
}
if(pValue < pTree->value)
if(insert_tree(pTree->left,pValue)==0)
{
//no left child any more,set a new left child to pTree
pTree->left = tNode;
printf("insert :%d\n",pValue);
}
if(pValue > pTree->value)
if(insert_tree(pTree->right,pValue)==0)
{
pTree->right = tNode;
printf("insert :%d\n",pValue);
}
}
Tree creatTree()
{
srand(time(NULL));
Tree root = init_TNode(rand()%100);
printf("root is %d\n",root->value);
int i ;
for(i=1;i<NUM;i++)
{
insert_tree(root,rand()%100);
}
printf("creat tree succuess!Tree heigh is:%d\n",get_tree_height(root));
return root ;
}
int get_tree_height(Tree pRoot)
{
if(!pRoot)
{
return 0;
}
int lh=0,rh=0;
lh = get_tree_height(pRoot->left);
rh = get_tree_height(pRoot->right);
return (lh<rh)?(rh+1):(lh+1);
}
int breath_travel(Tree pRoot,Queue *pQueue)
{
if(!pRoot)
{
return 0;
}
enQueue(pQueue,pRoot);
printf("_______________________\n");
printf("breath begin,enter root:\n");
while(ifEmpty(pQueue)!=0)
{
QNode *qNode = deQueue(pQueue);
//make suer every enQueue Node is not NULL
if(qNode->t_node->left!=NULL)
{enQueue(pQueue,qNode->t_node->left);}
if(qNode->t_node->right!=NULL)
{
enQueue(pQueue,qNode->t_node->right);
}
//print the tree node value
printf("%d ",qNode->t_node->value);
}
printf("\n-----------\nbreath end!\n-----------\n");
return 1;
}
int main()
{
Queue *queue=init_queue();
int i;
ifEmpty(queue);
printf("insert node to queue\n");
Tree root = creatTree();
if(!root)
{
printf("create Tree failed!\n");
return 0;
}
breath_travel(root,queue);
// free(queue);
return 0;
}
if this version can function well in my computer i have to add a unused int
"int length" in the beginning " _q_node" structure , if i don't add it the ifEmpty function cannot find the right position like "pQueue->head == NULL"
why this happen?
Your program has a bug in the insert_tree function. I have added a few comments to your code:
int insert_tree(Tree pTree,int pValue)
{
//found NULL sub tree, then add to his father->left
if(!pTree)
{
return 0;
}
TNode *tNode = init_TNode(pValue);
if(tNode==NULL)
{
printf("create TNode error!\n");
return 0;
}
if(pValue < pTree->value)
if(insert_tree(pTree->left,pValue)==0) // Here the return value is used
{
//no left child any more,set a new left child to pTree
pTree->left = tNode;
printf("insert :%d\n",pValue);
}
if(pValue > pTree->value)
if(insert_tree(pTree->right,pValue)==0) // Here the return value is used
{
pTree->right = tNode;
printf("insert :%d\n",pValue);
}
// No return value here !!
}
As you can see from my comments you miss a return value at the end of the function. Since you use that return value in other places, you program uses some uninitialized return value. That can make your program fail.
BTW: enQueue miss a return value as well.
An advice: Always compile your code with a high warning level and consider all warnings to be errors. In other words - if there are warnings they shall be fixed before running the code.
If you compile using gcc use -Wall to get all warnings
Besides that I think there is a problem with the logic in this function. It uses recursion to find where to insert the new value. In each recursive call you create a new node using TNode *tNode = init_TNode(pValue); but you only use it at the end of the recursion. In other words it seems you have memory leaks.
Further it's unclear how/where you handle the case where pValue is equal to pTree->value
BTW: pValue is a real bad name for an integer as the p makes you think it's a pointer.

C - Binary Search Tree, delete node

I have a question about my Code. "delete_single_node" does not work as it should. My procedure (to delete a node) is to find the node in the "head" tree, save the child nodes temporary, delete the node and all child nodes (in "head" tree) and merge the "head" tree with the temporary saved child nodes to a new correct binary tree.
I would like to stay with this procedure but I can't find my mistake.
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
struct tnode {
int content;
struct tnode *left;
struct tnode *right;
};
struct tnode* head;
void *malloc(size_t size);
struct tnode *talloc(void)
{
return(struct tnode*)malloc(sizeof(struct tnode));
}
/* delete a node with all child nodes*/
int deletenode(struct tnode *p)
{
if (p == NULL) return 0;
else
{
deletenode(p->left);
deletenode(p->right);
p->left = NULL;
p->right = NULL;
free(p);
return 0;
}
}
/* insert new node*/
struct tnode *addelement(struct tnode *p, int i) {
int cond;
if (p == NULL) {
p = talloc();
p->content = i;
p->left = p->right = NULL;
}
else if (p->content == i) {
return p;
}
else if (i < p->content)
p->left = addelement(p->left, i);
else
p->right = addelement(p->right, i);
return p;
}
/*merges two binary trees into one*/
struct tnode *addtree(struct tnode *top, struct tnode *p) {
if (p == NULL)
return top;
else
return addtree(addtree(addelement(top, p->content), p->right), p->left);
}
/*prints out tree*/
void showtree(struct tnode* nd)
{
if (nd == NULL)
return;
printf("ZZ %d", nd->content);
if (nd->left != NULL)
{
printf("left:%d", nd->left->content);
}
if (nd->right != NULL)
{
printf("right:%d\n", nd->right->content);
}
printf("\n");
showtree(nd->left);
showtree(nd->right);
}
/*removes connection to a node*/
void removeconnection(struct tnode *head, struct tnode *p) {
if (p->content > head->content) {
if (head->right == p)
{
head->right = NULL;
}
else
{
removeconnection(head->right, p);
}
}
if (p->content < head->content) {
if (head->left == p)
{
head->left = NULL;
}
else
{
removeconnection(head->left, p);
}
}
}
/*delete single node*/
struct tnode *delete_single_node(struct tnode *p, int content) {
struct tnode* temp2 = NULL;
struct tnode temp1;
struct tnode* temp4 = NULL;
struct tnode temp3;
if (p == NULL)
return NULL;
if (content > p->content)
{
p->right = delete_single_node(p->right, content);
}
else if (content < p->content)
{
p->left = delete_single_node(p->left, content);
}
else if (content == p->content)
{
if (p->left == NULL && p->right != NULL)
{
temp1.content = p->right->content;
temp1.right = p->right->right;
temp1.left = p->right->left;
temp2 = &temp1;
removeconnection(head, p);
deletenode(p);
head = addtree(head, temp2);
showtree(head);
}
else if (p->right == NULL && p->left != NULL)
{
temp1.content = p->left->content;
temp1.right = p->left->right;
temp1.left = p->left->left;
temp2 = &temp1;
removeconnection(head, p);
deletenode(p);
head = addtree(head, temp2);
showtree(head);
}
else if (p->right == NULL && p->left == NULL)
{
removeconnection(head, p);
deletenode(p);
showtree(head);
}
else
{
temp1.content = p->left->content;
temp1.right = p->left->right;
temp1.left = p->left->left;
temp2 = &temp1;
temp3.content = p->right->content;
temp3.right = p->right->right;
temp3.left = p->right->left;
temp4 = &temp3;
removeconnection(head, p);
deletenode(p);
head = addtree(head, temp2);
head = addtree(head, temp4);
showtree(head);
}
}
}
int main()
{
struct tnode* start = NULL;
int temp_int;
start = addelement(start, 5);
start = addelement(start, 6);
start = addelement(start, 2);
start = addelement(start, 9);
start = addelement(start, 3);
start = addelement(start, 2);
start = addelement(start, 1);
start = addelement(start, 7);
start = addelement(start, 8);
showtree(start);
printf("Which node to delete?\n");
scanf_s("%d", &temp_int);
head = start;
delete_single_node(start, temp_int);
return 0;
}

Pointer in function to linked list not updating element in 1 case

I am using a struct like this
struct infoM {
char* direction;
int key;
};
typedef struct nodeM{
struct infoM nodeInfo;
struct nodeM *next;
struct nodeM *prev;
} node;
typedef node list;
I have one function that returns the wanted node by a specific field
node * search(list *l, char* direction) {}
And this is my function to remove elements from the list
int delete(list *l, char* direction) {
node *tmp = search(l, direction);
if (tmp != NULL) {
node *ant = tmp->prev;
node *seg = tmp->next;
if (seg != NULL) {
if (ant != NULL) {
ant->next = seg;
seg->prev = ant;
free(tmp);
return 1;
} else { //prev null
seg->prev = NULL;
*l = *seg;
tmp = NULL;
free(tmp);
return 1;
}
} else { //next null
if (ant == NULL) {
l->nodeInfo.key = somevalue;
l->next = NULL;
l->prev = NULL;
return 1;
} else {
printf("Here is the problem\n");
ant->next = NULL;
free(tmp);
return 1;
}
}
} else { //tmp nulo
perror("Error delete : node null\n");
return 0;
}
}
If I have 4 elements in the list, 1234 and I delete first first element everything is okay and returns 234. If I delete the last element it returns 23 seems to work great. But if I try to delete the last element now the function does nothing despite being the same case that when it is 234 and I don't understand why. The list is not being updated.
In the main I am using the list like this :
list a;
delete(&a, "whatever");
What am I doing wrong ?
This is the code for search
node * createnode(){
node *tmp = (node *) malloc (sizeof(node));
return tmp;
}
node * search(list *l, char* direction) {
node *tmp = createnode();
if (l->nodeInfo.key == 777) {
perror("Error search: empty list\n");
return NULL;
}
tmp=l;
while((strcmp(direction, tmp->nodeInfo.direction) !=0) && (tmp->next != NULL)) {
tmp = tmp->next;
}
if (strcmp(direction, tmp->nodeInfo.direction) == 0) {
return tmp;
} else {
perror("Error search: element not found\n");
return NULL;
}
}

Binary Search Tree

so i coded a binary search tree in C which looks with this struct:
struct tnode {
int content;
struct tnode *left; /* left tree part */
struct tnode *right; /* right tree part */
};
My main method:
int main() {
struct tnode *Baum = NULL;
struct tnode *tmpPos = NULL;
Baum = addelement (Baum, 32);
Baum = addelement(Baum, 50);
Baum = addelement(Baum, 60);
tmpPos = searchnode(Baum,50);
}
So basicly this creates me a Binary search tree with 3 elements (32,50,60). My searchnode method is supposed to move a pointer to the "50" so i can delete it afterwards. However my searchnode Method only returns the pointer if the element im searching is the root of my binary search tree.
searchnode:
struct tnode *searchnode(struct tnode *p, int nodtodelete) {
if (p == NULL) {
printf("Baum ist leer oder Element nicht vorhanden \n");
}
if ( p -> content == nodtodelete) {
return p;
}
if (p->content > nodtodelete) {
searchnode (p->right, p->content);
}
if (p->content < nodtodelete) {
searchnode(p->left, p->content);
}
}
Maybe you guys can help me.
Your function has undefined behavior since it doesn't have any return statements in the recursive calls.
Also, the recursive calls need to be fixed to use the right input.
struct tnode *searchnode(struct tnode *p, int nodtodelete)
{
if (p == NULL)
{
printf("Baum ist leer oder Element nicht vorhanden \n");
return NULL;
}
if ( p -> content == nodtodelete)
{
return p;
}
// This is copied from OP's question but it seems suspect.
// It should probably be:
// if (p->content < nodtodelete)
if (p->content > nodtodelete)
{
return searchnode (p->right, nodtodelete);
}
return searchnode(p->left, nodtodelete);
}
You should pass the value you're searching for, not the value of the node:
searchnode (p->right, nodtodelete);
^
Make the same change to the other recursive call.
searchnode(p->left, nodtodelete);

Binary Search tree, node deletion crash

I coded a Binary Search tree. Every function works just fine, but the "deletenode". This method is supposed to delete the node which *p is pointing at.
However if the node is a leaf it prints the tree without the node and crashes.
If the node is no leaf it doesnt even print the tree and crashes.
I dont see any possible way to recreate the problem in less code, because i dont know where the problem is supposed to be. I'm Sorry.
Maybe someone can load it up and see where the problem is, because im really desperate.
#include <stdio.h>
void *malloc(size_t size);
void free(void *ptr);
struct tnode {
int content;
struct tnode *left; /* left subtree */
struct tnode *right; /* right subtree */
};
struct tnode *talloc(void) /* reserves memory*/
{
return (struct tnode *) malloc(sizeof(struct tnode));
}
struct tnode *addelement(struct tnode *p, int i) /* addelement: adds new node */
{
int cond;
if(p == NULL) {
p = talloc(); /* make a new node */ p->content = i;
p->left = p->right = NULL;
} else if(p->content == i) {
return p;
} else if(i < p->content) /* goes to the left side */ p->left = addelement(p->left, i);
else /* goes to the right side */ p->right = addelement(p->right, i);
return p;
}
struct tnode *addtree(struct tnode *top, struct tnode *p) /* adds subtree to main tree*/
{
if(p == NULL)
return top;
else
return addtree(addtree(addelement(top, p->content), p->right), p->left);
}
int printtree_preorder(struct tnode *p) /* prints tree in preorder*/
{
if(p != NULL) {
printf("%d \n", p->content);
printtree_preorder(p->left);
printtree_preorder(p->right);
}
return 0;
}
int printtree_inorder(struct tnode *p) /* prints tree in inorder*/
{
if(p != NULL) {
printtree_inorder(p->left);
printf("%d \n", p->content);
printtree_inorder(p->right);
}
return 0;
}
int printtree_postorder(struct tnode *p) /* prints tree in postorder*/
{
if(p != NULL) {
printtree_postorder(p->left);
printtree_postorder(p->right);
printf("%d \n", p->content);
}
return 0;
}
struct tnode *searchnode(struct tnode *p, int nodtodelete) /* pointer is set on the node which is supposed to be deleted */
{
if(p == NULL) {
printf("Baum ist leer oder Element nicht vorhanden \n");
return 0;
}
if(p->content == nodtodelete) {
return p;
}
if(p->content < nodtodelete) {
return searchnode(p->right, nodtodelete);
}
if(p->content > nodtodelete) {
return searchnode(p->left, nodtodelete);
}
}
struct tnode *deletenode(struct tnode *p, struct tnode *pBaum) /* Is supposed to delete the node which the *p is pointing at */
{
if((p->left == NULL) && (p->right == NULL)) {
free(p);
printf("Ist Blatt \n");
return pBaum;
}
if((p->left == NULL) && (p->right != NULL)) {
struct tnode *rechterTeilbaum = p->right;
free(p);
pBaum = addtree(pBaum, rechterTeilbaum);
return pBaum;
}
if((p->right == NULL) && (p->left != NULL)) {
struct tnode *linkerTeilbaum = p->left;
free(p);
pBaum = addtree(pBaum, linkerTeilbaum);
return pBaum;
}
if((p->left != NULL) && (p->right != NULL)) {
struct tnode *rechterTeilbaum = p->right;
struct tnode *linkerTeilbaum = p->left;
free(p);
pBaum = addtree(pBaum, rechterTeilbaum);
pBaum = addtree(pBaum, linkerTeilbaum);
return pBaum;
}
}
int main() {
struct tnode *Baum = NULL;
struct tnode *tmpPos = NULL;
Baum = addelement(Baum, 10);
Baum = addelement(Baum, 30);
Baum = addelement(Baum, 20);
Baum = addelement(Baum, 35);
tmpPos = searchnode(Baum, 35);
if(tmpPos != 0) {
printf("Zu loeschendes Element: %d \n", tmpPos->content);
Baum = deletenode(tmpPos, Baum);
}
printf("Inorder Ausgabe\n");
printtree_inorder(Baum);
printf("Postorder Ausgabe\n");
printtree_postorder(Baum);
printf("Preorder Ausgabe\n");
printtree_preorder(Baum);
}
In the deletenode function, you aren't checking to see if p is NULL before you try to dereference it. Are you segfaulting?

Resources