Reputation: 33
I just started getting into nodes and simple linked lists. While I find linked lists confusing I still start to understand them more and can code them following different tutorials.
But to remove nodes I tried a piece of code that didn't quite work and found another one that did. Except I don't quite get why one works and the other doesn't.
Here is what doesn't work:
void remove_character(Character **head)
{
Character *current=*head,
*temp=malloc(sizeof(Character));//temporary node to
//remove node
char *name=malloc(100);
if(current!=NULL)//if there is at least one node
{
printf("Enter name: ");
scanf("%s", name);
}
if(!strcmp(name, (*head)->name))//removes head and
//makes next node head
{
temp=(*head);
(*head)=(*head)->next;
free(temp->name);
free(temp);
current=*head;
}
while(current!=NULL)
{
if(!strcmp(name, current->name))
{
temp=current;//assign node to be removed
current=current->next;//move to next node
free(temp->name);
free(temp);//free removed node
}
current=current->next;
}
}
But this works:
void remove_character(Character **head)
{
Character *current=*head,
*temp=malloc(sizeof(Character));
char *name=malloc(100);
if(current!=NULL)
{
printf("Enter name: ");
scanf("%s", name);
}
if(!strcmp(name, (*head)->name))
{
temp=(*head);
(*head)=(*head)->next;
free(temp->name);
free(temp);
current=*head;
}
while(current!=NULL)
{
if(current->next!=NULL)
{
if(!strcmp(name, current->next->name))
{//if next node is node to be removed
temp=current->next;
current->next=current->next->next;
//moves to next node
free(temp->name);
free(temp);
}
}
current=current->next;
}
}
Basically the second one anticipates one node and links one node further but why should this one work and not the other (which prints segmentation fault right where the removed node was... Nodes seem so easy but are so complicated to manage. Especially when you are bad at imagining how it works.
Upvotes: 0
Views: 90
Reputation: 12742
In your first method you are not proactive.
That is you check for the string
after visiting the particular node
and once you found the node
which is to be deleted you just free
it and move further without fixing the list
.
Adding one more pointer
to point the previous node
should fix this issue.
if(!strcmp(name, (*head)->name))
{
/* Code to delete in the head node */
temp=(*head);
(*head)=(*head)->next;
free(temp->name);
free(temp);
current=*head;
}
else
{
/* Code to delete in the rest of the list*/
character *prev=*head;
while(current!=NULL)
{
if(!strcmp(name, current->name))
{
prev->next = current->next;//move to next node
free(current->name);
free(current);//free removed node
break;
}
prev = current;
current=current->next;
}
}
In your second method you are proactive.
That is you check for the string
before visiting the particular node
and once you found out that next node
which is to be deleted then you free
it and move further after fixing the list
.
if(!strcmp(name, current->next->name)) // Found out next node to be deleted
{
temp=current->next; // Get the next node
current->next=current->next->next; // Adjust the list by skipping the next node
free(temp->name); // Free the node.
free(temp);
}
Upvotes: 1