The problem statement: We have to delete every alternate node of a Linked List. Eg: Original list: 1->2->3->4->5 to: 1->3->5
complete problem statement: https://practice.geeksforgeeks.org/problems/delete-alternate-nodes/1/?ref=self
As you can see, this is a function problem so I'm not actually writing the complete code(just have to complete the function). Here is the code that I'm writing:
void deleteAlt(struct Node *head){
// Code here
struct Node *traverse=head,*alternate=head->next;
if(alternate->next==NULL)
{
head->next=NULL;
return;
}
while(traverse->next!=NULL && alternate->next!=NULL)
{
traverse->next = alternate->next;
traverse = traverse->next;
alternate = traverse->next;
if((alternate->next)==NULL) //presence of this if statement causes segmentation fault
{
traverse->next=NULL;
}
}
}
I have gone through similar problems on stackoverflow but their code and objective were different, like, not initializing the pointer and comparing it. However, my problem is different.
In the case when number of nodes is even, alternate
is always going to be NULL and hence there should be no initialization problem.
you do
while(traverse->next!=NULL && alternate->next!=NULL)
traverse->next = alternate->next;
traverse = traverse->next;
alternate = traverse->next;
if((alternate->next)==NULL) //presence of this if statement causes segmentation fault
so in fact
while(traverse->next!=NULL && alternate->next!=NULL)
traverse = alternate->next;
alternate = traverse->next;
if((alternate->next)==NULL) //presence of this if statement causes segmentation fault
so in fact
while(traverse->next!=NULL && alternate->next!=NULL)
alternate = alternate->next->next;
if((alternate->next)==NULL) //presence of this if statement causes segmentation fault
so in fact
while(traverse->next!=NULL && alternate->next!=NULL)
if((alternate->next->next->next)==NULL) //presence of this if statement causes segmentation fault
when alternate->next->next
is NULL (not checked by the while ) alternate->next->next->next
causes your segmentation fault
A solution is :
void deleteAlt(struct Node * head)
{
if (head != NULL) {
while (head->next != NULL) {
Node * d = head->next;
head->next = head->next->next;
free(d);
head = head->next;
}
}
}
A complete program to prove :
#include <stdio.h>
#include <stdlib.h>
typedef struct Node {
int v;
struct Node * next;
} Node;
Node * make(int v, Node * n)
{
Node * r = malloc(sizeof(Node));
r->v = v;
r->next = n;
return r;
}
void pr(Node * l)
{
while (l != NULL) {
printf("%d ", l->v);
l = l->next;
}
putchar('\n');
}
void deleteAlt(struct Node * head)
{
if (head != NULL) {
while (head->next != NULL) {
Node * d = head->next;
head->next = head->next->next;
free(d);
head = head->next;
}
}
}
int main()
{
Node * l = make(1, make(2, make(3, make(4, make(5, NULL)))));
pr(l);
deleteAlt(l);
pr(l);
/* free rest of list */
while (l != NULL) {
Node * n = l->next;
free(l);
l = n;
}
}
Compilation and execution:
pi@raspberrypi:/tmp $ gcc -pedantc -Wextra l.c
pi@raspberrypi:/tmp $ ./a.out
1 2 3 4 5
1 3 5
pi@raspberrypi:/tmp $
Execution under valgrind to check memory accesses/leaks
pi@raspberrypi:/tmp $ valgrind ./a.out
==2479== Memcheck, a memory error detector
==2479== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==2479== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==2479== Command: ./a.out
==2479==
1 2 3 4 5
1 3 5
==2479==
==2479== HEAP SUMMARY:
==2479== in use at exit: 0 bytes in 0 blocks
==2479== total heap usage: 6 allocs, 6 frees, 1,064 bytes allocated
==2479==
==2479== All heap blocks were freed -- no leaks are possible
==2479==
==2479== For counts of detected and suppressed errors, rerun with: -v
==2479== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 3)
(edit) In case the length of the list can be even the definition must be changed to :
void deleteAlt(struct Node * head)
{
while ((head != NULL) && (head->next != NULL)) {
Node * d = head->next;
head->next = head->next->next;
free(d);
head = head->next;
}
}
modifying main to check :
int main()
{
{
Node * l = make(1, make(2, make(3, make(4, make(5, NULL)))));
pr(l);
deleteAlt(l);
pr(l);
/* free rest of list */
while (l != NULL) {
Node * n = l->next;
free(l);
l = n;
}
}
{
Node * l = make(1, make(2, make(3, make(4, NULL))));
pr(l);
deleteAlt(l);
pr(l);
/* free rest of list */
while (l != NULL) {
Node * n = l->next;
free(l);
l = n;
}
}
}
Compilation and execution :
pi@raspberrypi:/tmp $ gcc -pedantic -Wextra l.c
pi@raspberrypi:/tmp $ ./a.out
1 2 3 4 5
1 3 5
1 2 3 4
1 3
and under valgrind :
pi@raspberrypi:/tmp $ valgrind ./a.out
==3450== Memcheck, a memory error detector
==3450== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==3450== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==3450== Command: ./a.out
==3450==
1 2 3 4 5
1 3 5
1 2 3 4
1 3
==3450==
==3450== HEAP SUMMARY:
==3450== in use at exit: 0 bytes in 0 blocks
==3450== total heap usage: 10 allocs, 10 frees, 1,096 bytes allocated
==3450==
==3450== All heap blocks were freed -- no leaks are possible
==3450==
==3450== For counts of detected and suppressed errors, rerun with: -v
==3450== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 3)
try this:
void deleteAlt(struct Node *head){
struct Node * head_tmp=head;
struct Node * tmp=NULL;
while(head_tmp->next!=NULL){
tmp=head_tmp->next;
head_tmp->next=tmp->next;
head_tmp=tmp->next;
//do something for freeing tmp node
}
}
I can see a code smell in
if(alternate->next==NULL)
{
head->next=NULL;
return;
}
What if i have a single node? In that case alternate
points to null.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.