I wanted to delete all nodes of a Linked List that contain some value, but the algorithm that I have implemented doesn't work as I hoped!
when I execute the program it shows that all the nodes have been deleted!
output :
The List is empty
can someone help me to detect the problem ?
typedef struct node
{
int data;
struct list* next;
}node;
typedef struct list
{
node* start,*end;
}list;
void delete(list** ptr,int element)
{
if((*ptr)->start==NULL) return;
node* previous=NULL;
list* new_ptr=(list*)malloc(sizeof(list));
new_ptr->start=(*ptr)->start;
new_ptr->end=(*ptr)->end;
while(new_ptr->start)
{
if(new_ptr->start->data==element)
{
if(previous==NULL)
{
node* temp=new_ptr->start;
new_ptr->start=new_ptr->start->next;
(*ptr)->start=new_ptr->start;
free(temp);
}
else
{
node* temp=new_ptr->start;
new_ptr->start=new_ptr->start->next;
previous->next=new_ptr->start;
free(temp);
}
}
else
{
previous=new_ptr->start;
new_ptr->start=new_ptr->start->next;
}
}
}
Related
Here are the codes I have to create a list and elements in the list. Now I want to implement a function to delete the entire list rather than just emptying the list. How do I do that?
struct node
{
int number;
struct node* next;
};
struct forward_list
{
struct node* head;
};
typedef struct node node;
node* create_node(int number, node* next)
{
node* result = (node*)malloc(sizeof(node));
result->number = number;
result->next = next;
return result;
}
//edit
void destroy_node(node* const this)
{
free(this);
}
void destroy_list(forward_list* const this)
{
/* TODO */
}
Seeing your edit, I think you just have to call destroy_node iteratively in destroy_list to empty your list, thus destroying it.
[EDIT]
I had to set the head of the list to NULL at the end. Thanks for the comment!
Something like this:
void destroy_list(forward_list* const this)
{
node* temp = this->head;
node* to_delete;
while(temp != NULL){
to_delete = temp;
temp = temp->next;
destroy_node(to_delete);
}
this->head = NULL;
}
This is the function which I am using for BST inorder Traversal
void inOrder(struct node* root)
{
if(root==NULL)
{
return;
}
inOrder(root->left);
printf("Key:%d,Pointer:%p\n",root->key,root);
inOrder(root->right);
}
The structure for the same is
struct node{
int key;
struct node *left,*right;
};
When I run the function I get two 0 extra elements for the following inserts:
root=insert(root,7);
insert(root,4);
insert(root,10);
insert(root,3);
insert(root,5);
insert(root,1);
insert(root,2);
insert(root,0);
insert(root,8);
insert(root,14);
insert(root,6);
insert(root,9);
insert(root,16);
insert(root,12);
insert(root,15);
insert(root,17);
inOrder(root);printf("\n");
And the insert function is given below:
struct node *insert(struct node * root,int ele)
{
struct node *temp=newNode(ele);
struct node *tree=root;
struct node *saver;
if(root==NULL)
{
root=temp;
}
else
{
while(tree!=NULL)
{
saver=tree;
if(ele<tree->key)
tree=tree->left;
else
tree=tree->right;
}
if(ele<saver->key)
{
saver->left=temp;
}
else
{
saver->right=temp;
}
}
return saver;
}
The output shows two 0s apart from the main elements, which I added. I have recently learned the Binary-Search-Tree, and I tried to implement it, Can someone please help me rectify this error. Thank you in advance
in insert
if(root==NULL)
{root=temp;
}
must be
if(root==NULL)
{
saver=temp;
}
because you return saver (not initialized in your version)
I suppose also in your main the code is not what you give but something like
struct node * root = NULL;
root=insert(root,7);
insert(root,4);
...
If I define newNode like that :
struct node * newNode(int ele)
{
struct node * r = malloc(sizeof(struct node));
r->key = ele;
r->left = r->right = NULL;
return r;
}
and I do the other changes :
pi#raspberrypi:/tmp $ gcc -g -pedantic -Wextra n.c
pi#raspberrypi:/tmp $ ./a.out
Key:0,Pointer:0xf04078
Key:1,Pointer:0xf04058
Key:2,Pointer:0xf04068
Key:3,Pointer:0xf04038
Key:4,Pointer:0xf04018
Key:5,Pointer:0xf04048
Key:6,Pointer:0xf040a8
Key:7,Pointer:0xf04008
Key:8,Pointer:0xf04088
Key:9,Pointer:0xf040b8
Key:10,Pointer:0xf04028
Key:12,Pointer:0xf040d8
Key:14,Pointer:0xf04098
Key:15,Pointer:0xf040e8
Key:16,Pointer:0xf040c8
Key:17,Pointer:0xf040f8
The full code is :
#include <stdio.h>
#include <stdlib.h>
struct node{
int key;
struct node *left,*right;
};
void inOrder(struct node* root)
{
if(root==NULL)
{return;}
inOrder(root->left);
printf("Key:%d,Pointer:%p\n",root->key,root);
inOrder(root->right);
}
struct node * newNode(int ele)
{
struct node * r = malloc(sizeof(struct node));
r->key = ele;
r->left = r->right = NULL;
return r;
}
struct node *insert(struct node * root,int ele)
{
struct node *temp=newNode(ele);
struct node *tree=root;
struct node *saver;
if(root==NULL)
{
saver=temp;
}
else
{
while(tree!=NULL)
{
saver=tree;
if(ele<tree->key)
tree=tree->left;
else
tree=tree->right;
}
if(ele<saver->key)
{
saver->left=temp;
}
else
{
saver->right=temp;
}
}
return saver;
}
int main()
{
struct node * root = NULL;
root=insert(root,7);
insert(root,4);
insert(root,10);
insert(root,3);
insert(root,5);
insert(root,1);
insert(root,2);
insert(root,0);
insert(root,8);
insert(root,14);
insert(root,6);
insert(root,9);
insert(root,16);
insert(root,12);
insert(root,15);
insert(root,17);
inOrder(root);printf("\n");
}
#include<stdio.h>
#include<conio.h>
#include<malloc.h>
#include<string.h>
struct node{
char *name;
struct node *lchild;
struct node *rchild;
};
void find(char *str,struct node **root,struct node **loc,struct node **par)
{
struct node *ptr,*ptrsave;
*loc=NULL;
*par=NULL;
if(*root==NULL)
{
return;
}
if(!strcmp((*root)->name,str))
{
*loc=*root;
return;
}
ptrsave=NULL;
ptr=*root;
while(ptr!=NULL)
{
if(!strcmp(ptr->name,str)) break;
ptrsave=ptr;
if(strcmp(ptr->name,str)>0)
ptr=ptr->lchild;
else
ptr=ptr->rchild;
}
*loc=ptr;
*par=ptrsave;
}
void insert(struct node **p,char *str)
{
struct node *location,*parent,*temp;
find(str,&(*p),&location,&parent);
if(location!=NULL)
{
printf("Element already exists\n");
return;
}
temp=(struct node *)malloc(sizeof(struct node));
temp->name=strdup(str);
temp->lchild=NULL;
temp->rchild=NULL;
if(parent==NULL)
{
*p=temp;
return;
}
else
{
if(strcmp(parent->name,str)>0)
parent->lchild=temp;
else
parent->rchild=temp;
}
}
void inorder(struct node *root)
{
if(root!=NULL)
{
preorder(root->lchild);
printf("[%30s]\n",root->name);
preorder(root->rchild);
}
}
int main()
{
struct node *root=NULL;
insert(&root,"Crocin");
insert(&root,"Acetyl");
insert(&root,"Colchichine");
insert(&root,"Diclofenac_50mg");
insert(&root,"Diclofenac_25mg");
insert(&root,"Morphine Sulphate");
insert(&root,"Fentanyl");
insert(&root,"Dolo");
insert(&root,"Ibuprofen");
insert(&root,"Tramadol");
insert(&root,"Paracetamol");
inorder(root);
getchar();
return 0;
}
This is the code i am using for creating and inserting nodes in a binary search tree. After that i created recursive inorder function. but this is not giving the right ouput. I am not able to find error that is creating discrepancy. Can someone suggest where i am going wrong?
Change
void inorder(struct node *root)
{
if(root!=NULL)
{
preorder(root->lchild);
printf("[%30s]\n",root->name);
preorder(root->rchild);
}
to
void inorder(struct node *root)
{
if(root!=NULL)
{
inorder(root->lchild);
printf("[%30s]\n",root->name);
inorder(root->rchild);
}
You are using another function (preorder) (not listed in your code)
Here i have written a code which inserts numbers in Binary tree. But it gives segmentation fault error.
And also it says " note: expected ‘struct tree *’ but argument is of type ‘struct node *’" in line 8.
Here is the code :-
#include<stdio.h>
#include<stdlib.h>
struct tree{
int data;
struct tree *left;
struct tree *right;
};
struct tree* insert(struct tree* node, int data)
{
if(!node){
node=malloc(sizeof(struct tree));
node->data=data;
node->left=node->right=NULL;
return node;
}
else {
if(data>node->data){
node->right= insert(node->right,data);
return node;
}
else{
node->left= insert(node->left,data);
}
return node;
}
}
printtree(struct tree* node)
{
if(node){
printf("%d",node->data);
}
printtree(node->left);
printtree(node->right);
}
main()
{
int i,n;
struct tree *NODE;
NODE= insert(NODE,5);
NODE= insert(NODE,3);
NODE= insert(NODE,8);
printtree(NODE);
}
You use if( node ) but better to use if( node != NULL )
You use if( !node ) but better to use if( node == NULL )
It make code more readable.
You have so many mistakes - so ... I make it in my way (my code formating, etc.).
printtree(node->left); printtree(node->right); was outside if( node != NULL ){} so it try to get NULL->left and NULL->right
Tested - code works.
#include<stdio.h>
#include<stdlib.h>
struct tree{
int data;
struct tree *left;
struct tree *right;
};
struct tree* insert(struct tree* node, int data)
{
if( node == NULL ) {
node = malloc( sizeof(struct tree) );
node->data = data;
node->left = node->right = NULL;
} else {
if( data > node->data ){
node->right = insert(node->right, data);
} else {
node->left = insert(node->left, data);
}
}
return node;
}
void printtree(struct tree* node)
{
if( node != NULL ){
printf("%d\n", node->data);
printtree(node->left);
printtree(node->right);
}
}
int main()
{
struct tree *NODE = NULL;
NODE = insert(NODE, 5);
NODE = insert(NODE, 3);
NODE = insert(NODE, 8);
printtree(NODE);
return 0;
}
The local variable: struct tree* node; is not initialized, so the if (!node) test will have undefined behavior. Unless you assign it something or use it to hold a malloc'd node, the expression in the else block tries to dereference an uninitialized pointer.
You should also get used to idea that a tree can be considered a 'recursive' structure, so any node is a tree, and the top-level tree is simply a node. There's no good reason for two separate types here.
You are still making the error of passing NODE by value. If you want to modify it, you must use a pointer to that pointer.
#include<stdio.h>
#include<stdlib.h>
typedef struct t
{
int data;
struct t *left;
struct t *right;
}tree;
tree* insert(tree **node, int data)
{
if(!(*node))
{
*node=malloc(sizeof(tree));
(*node)->data=data;
(*node)->left=(*node)->right=NULL;
return *node;
}
else
{
if(data>(*node)->data)
{
(*node)->right = insert(&((*node)->right),data);
return *node;
}
else
{
(*node)->left = insert(&((*node)->left),data);
return *node;
}
}
}
void printtree(tree *node)
{
if(node)
{
printf("%d",node->data);
printtree(node->left);
printtree(node->right);
}
}
void freeMemory(tree *node)
{
if(node)
{
freeMemory(node->left);
freeMemory(node->right);
free(node);
}
}
int main()
{
tree *NODE = NULL;
NODE= insert(&NODE,5);
NODE= insert(&NODE,3);
NODE= insert(&NODE,8);
printtree(NODE);
freeMemory(NODE);
return 0;
}
Link: http://ideone.com/OpZWiC
I am trying to insert node in a binary search tree, I am getting an access voilation error at line if(ptr->data== item) in searchNode() function. How can I remove it. I am new to debugging.
I am first trying to insert few nodes and then display them using display function. During insertion the program searches for the appropriate position of the node to be inserted and then inserts it. Program simply returns if node already exists.
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
struct node
{
int data;
struct node* left;
struct node* right;
};
void searchNode(struct node* root,int item,struct node* loc,struct node *par)
{
struct node * ptr,*save;
if(root==NULL)
{
loc=NULL;
par=NULL;
return;
}
else
{
if(item==root->data)
{
par=NULL;loc=root; return;
}
else if(item < root->data)
{
save=root;ptr=root->left;
}
else if(item > root->data)
{
save=root;ptr=root->right;
}
while(ptr!=NULL)
{
if(ptr->data == item )
{
loc=ptr;
par=save;
return;
}
else if(ptr->data > item )
{
save=ptr;
ptr=ptr->left;
}
else
{
save=ptr;ptr=ptr->right;
}
}
loc=NULL;
par=save;
}
}
void insertNode(struct node* root,int item, struct node * loc)
{
struct node* par,*newNode;
searchNode(root,item,loc,par);
if(loc!=NULL)
return;
newNode=(struct node *)malloc(sizeof(struct node));
newNode->left=NULL;newNode->right=NULL;
if(par==NULL)
{
root=newNode;
}
else if(item< par->data)
{
par->left=newNode;
}
else if(item> par->data)
{
par->right=newNode;
}
}
void display(struct node* t, int level)
{
int i;
if(t)
{
display(t->right,level+1);
printf("\n");
for(i=0;i<level;i++)
printf(" ");
printf("%d",t->data);
display(t->left,level+1);
}
}
int main()
{
int n,data,i;
struct node* root,*loc;
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%d",&data);
insertNode(root,data,loc);
}
display(root,1);
getch();
return 0;
}
You are calling your insert method as:
insertNode(root,data,loc);
and the root is passed by value as a result, any changes made to root in the insertNode method will not be visible in main. Since your root in main is uninitialized, the same gets passed to display where you try to dereference the uninitialized pointer leading to undefined behavior.
To fix this you either pass the address of root to insertNode function or return the changed root from the function.