Search code examples
clistdynamiclinked-listallocation

How to Delete the last element in a linked list in C?


I don't know how to delete the first and last element in a linked list in c. Below is my program, that uses a linked list. I have no idea how to actually delete the last element but I am able to find it. the element consists of an integer and the next pointer. if someone could please help me, it would be much appreciated.

struct ListNode{
    int value;
    struct ListNode *next;
};
typedef struct ListNode Link;

void deleteLast(Link *);
void printList(Link *);
void deleteFirst(Link *);

int main(){
    Link *myList;
 Link *curr, *newlink;
 int i;
    curr = myList;
    for(i = 0; i < 10; i++){

            newlink = (Link*) malloc(1*sizeof(Link));
            newlink->value = i*i;
            curr->next = newlink;
            curr = newlink;
    }

    curr->next = NULL;
    curr = myList->next;
    deleteFirst(curr);
    printList(curr);
    printf("\n");
}
void deleteLast(Link *head)
{
    Link *curr;
    curr = head->next;
    while (curr->next!=NULL)
    {
        curr = curr->next;
    }
     free(curr->next);

    curr->next = NULL;

}
void printList(Link *head){
    Link *curr;
    curr = head->next;

    printf("[");
    if(curr!=NULL){
        printf("%d",curr->value);
        curr = curr->next;
    }

    while(curr != NULL){
        printf(", %d", curr->value);
        curr = curr->next;
    }
    printf("]\n");

}
void deleteFirst(Link *head){
    Link *curr;
    curr = head->next;
    free(curr->value);
    free(curr->next);
    printf("%d\t",curr->value);
}

Nothing I try works, please can you help me.


Solution

  • You have many errors in your code.

    • When you create your list:
      • You don't have to cast the return value of malloc
      • You are doing curr->next = newlink; where curr = myList with initialized value. You can change your loop to
      Link *myList = NULL;
      Link *curr, *newlink;
      int i;
    
      curr = myList;
      for(i = 0; i < 10; i++){
    
        newlink = malloc(1*sizeof(Link));
        newlink->value = i*i;
        if (curr != NULL)
          curr->next = newlink;
        else
          myList = newlink;
        curr = newlink;
      }
    
    • When you remove the last element you are going to far, that's why it's not working
      Link  *curr;
    
      curr = head->next;   
      while (curr->next != NULL) {
        head = curr;
        curr = curr->next;
      }
    
      free(head->next);
      head->next = NULL;
    
    • When you want to remove the first element of your list
      • You don't have to free the field value since you have not allocated it with malloc
      • Even if you remove the first element of your list, you are not changing the value of the begining of your list in the main. It's why you must take as a param a Link**
    void deleteFirst(Link **head){
      Link *curr;
    
      curr = (*head)->next;
      free(*head);
      *head = curr;
    }
    

    And you can call this function from the main by giving the address of the beginning of your list:

      deleteFirst(&myList);
      deleteLast(myList);
      printList(myList);
    

    of course in all your functions you must check if you have at least some values in the list and not an empty pointer NULL