0

The aim was to make a program that deleted the last occurrence of an element in a linked list Ex:-If the linked list is 23->45->23->24->23 then i look for the output 23->45->23->24 but I am getting several errors on debugging mainly on the parts temp->next!=NULL and t1->next=t->next,kindly point out the errors hindering the execution of program?

#include<stdio.h>
#include<stdlib.h>
struct node
{
    int data;
    struct node *next;
};
void insertLL(struct node *head,int data)
{
    struct node *temp;
    struct node *new=(struct node *)malloc(sizeof(struct node));
    new->data=data;
    if(head==NULL)
    {
        head=new;
    }
    else
    {
        temp=head;   
        while(temp->next!=NULL)
        {
            temp=temp->next;
        }
        temp->next=new;
    }
}
void delete(struct node *head,int data)
{
    struct node *temp=head;
    struct node *t;
    struct node *t1;
    while(temp->next!=NULL)
    {
        if(temp->next->data==data)
        {
            t1=temp;
        }
        if(temp->data==data)
        {
            t=temp;
        }
        temp=temp->next;
    }
    t1->next=t->next;
    free(t);
}
void display(struct node *head)
{
    struct node *temp1=head;
    if (head==NULL)
    {
        printf("List is empty");
    }
    else
    {
        while(temp1->next!=NULL)
        {
            printf("%d",temp1->data);
            printf("->");
            temp1=temp1->next;
        }
    }
    
}
int main()
{
    int u,k,l,n;
    struct node *start;
    while(1)
    {
        printf("Press 1 to insert element into the Linked List, press 2 to delete the last occurence of an element from a linked list, press 3 to display the linked list, press 0 to exit the program\n");
        scanf("%d",&u);
        switch(u)
        {
            case 1:
            {
                printf("Enter the data you want to insert\n");
                scanf("%d",&l);
                insertLL(start,l);
                break;
            }
            case 2:
            {
                printf("Enter the element that you want to be deleted\n");
                scanf("%d",&k);
                delete(start,k);
                break;
            }
            case 3:
            {
                display(start);
                break;
            }
            default:
            {
                printf("Invalid input\n");
            }
            
        }
        printf("Enter 1 to continue or 0 to break\n");
        scanf("%d",&n);
        if(n==1)
        {
            continue;
        }
        if(n==0)
        {
            break;
        }
    }
}
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • Please tell us what errors or problems you are getting. That is, give the exact input, expected result and actual result. – kaylum Nov 13 '20 at 05:42
  • Yes,i ran the the code through the debugger,if the linked list is 23->45->23->24->23 then i look for the output 23->45->23->24 but I am getting segmentation fault in the delete function in the line temp->next!=NULL and t1->next=t->next – Archit Chandrakar Nov 13 '20 at 05:45
  • Please [edit](https://stackoverflow.com/posts/64816045/edit) the question with that info. – kaylum Nov 13 '20 at 05:46
  • 3
    One major problem: `head=new;` That won't work. `head` is a local variable because function parameters are passed be value in C. Changing that value does not change the caller's variable. – kaylum Nov 13 '20 at 05:47
  • so should i initialize struct node *start globally and then initialize new to the node start directly? – Archit Chandrakar Nov 13 '20 at 05:52
  • [Changing address contained by pointer using function](https://stackoverflow.com/questions/13431108/changing-address-contained-by-pointer-using-function) – kaylum Nov 13 '20 at 05:53
  • With only one node left (the `head` node), `temp->next == NULL`. What does your `delete()` function do then? See [Singly Linked List (node only, no wrapper)](https://pastebin.com/5MPLU4wB) the `del_list()` function. – David C. Rankin Nov 13 '20 at 05:59
  • In the insert function you also need `new->next=NULL` – Support Ukraine Nov 13 '20 at 06:06

1 Answers1

2

For starters the function insertLL is incorrect because it deals with a copy of the value of the pointer to the head node. That is changing the copy does not influence on the original object.

You need to pass the pointer to the head node by reference through pointer to it.

The function can be declared and defined the following way.

int insertLL( struct node **head, int data )
{
    struct node *new_node = malloc( sizeof( struct node ) );
    int success = new_node != NULL;

    if ( success )
    {
        new_node->data = data;
        new_node->next = NULL;

        while ( *head ) head = &( *head )->next;
  
        *head = new_node;
    }

    return success;
}

And the function can be called like

insertLL( &start, data );

or

if ( !insertLL( &start, data ) )
{
    puts( "Error: not enough memory." );
}

The function delete is also incorrect. For example it can invoke undefined behavior when it is called for an empty list due to this statement

while(temp->next!=NULL)

The function can be declared and defined the following way

void delete( struct node **head, int data )
{
    // Find the last node with the target data
    struct node **target = NULL;

    while ( *head )
    {
        if ( ( *head )->data == data )
        {
            target = head;
        }
    }

    // If the target node is found remove it from the list
    if ( target != NULL )
    {
        struct node *tmp = *target;
        *target = ( *target )->next;
        free( tmp );
    }
}

And the function display is in turn incorrect. It outputs nothing when the list contains only one node due to this statement

while(temp1->next!=NULL)

The function can be declared and defined the following way

void display( const struct node *head )
{
    for ( ; head != NULL; head = head->next )
    {
        printf( "%d -> ", head->data );
    }

    puts( "null" );
}

In main these statements

        default:
        {
            printf("Invalid input\n");
        }

and

    printf("Enter 1 to continue or 0 to break\n");
    scanf("%d",&n);
    if(n==1)
    {
        continue;
    }
    if(n==0)
    {
        break;
    }

is redundant. You already wrote to the user how to exit the loop

printf("Press 1 to insert element into the Linked List, press 2 to delete the last occurence of an element from a linked list, press 3 to display the linked list, press 0 to exit the program\n");

So the loop can look for example like

while(1)
{
    printf("Press 1 to insert element into the Linked List, press 2 to delete the last occurence of an element from a linked list, press 3 to display the linked list, press 0 to exit the program\n");

    u = -1;
    scanf("%d",&u);

    switch(u)
    {
        case 1:
        {
            //...
            break;
        }
        case 2:
        {
            //...
            break;
        }
        case 3:
        {
            //...
            break;
        }
        default:
        {
            if ( u != 0 )
            {
                printf("Invalid input\n");
            }
            break;
        }
    }

    if ( u == 0 ) break;
}
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335