Bird
Raised Fist0
DSA Cprogramming~20 mins

Insert at End of Doubly Linked List in DSA C - Practice Problems & Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
Doubly Linked List Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ Predict Output
intermediate
2:00remaining
Output after inserting nodes at the end
What is the printed state of the doubly linked list after inserting 10, 20, and 30 at the end?
DSA C
typedef struct Node {
    int data;
    struct Node* prev;
    struct Node* next;
} Node;

#include <stdio.h>
#include <stdlib.h>

Node* insertAtEnd(Node* head, int data) {
    Node* newNode = (Node*)malloc(sizeof(Node));
    newNode->data = data;
    newNode->next = NULL;
    if (head == NULL) {
        newNode->prev = NULL;
        return newNode;
    }
    Node* temp = head;
    while (temp->next != NULL) {
        temp = temp->next;
    }
    temp->next = newNode;
    newNode->prev = temp;
    return head;
}

void printList(Node* head) {
    Node* temp = head;
    while (temp != NULL) {
        printf("%d -> ", temp->data);
        temp = temp->next;
    }
    printf("null\n");
}

int main() {
    Node* head = NULL;
    head = insertAtEnd(head, 10);
    head = insertAtEnd(head, 20);
    head = insertAtEnd(head, 30);
    printList(head);
    return 0;
}
A10 -> 20 -> null
B30 -> 20 -> 10 -> null
C10 -> 20 -> 30 -> null
Dnull
Attempts:
2 left
💡 Hint
Remember that inserting at the end adds the new node after the last node.
❓ Predict Output
intermediate
2:00remaining
Output after inserting into an empty list
What is the printed state of the doubly linked list after inserting a single node with value 5 into an empty list?
DSA C
typedef struct Node {
    int data;
    struct Node* prev;
    struct Node* next;
} Node;

#include <stdio.h>
#include <stdlib.h>

Node* insertAtEnd(Node* head, int data) {
    Node* newNode = (Node*)malloc(sizeof(Node));
    newNode->data = data;
    newNode->next = NULL;
    if (head == NULL) {
        newNode->prev = NULL;
        return newNode;
    }
    Node* temp = head;
    while (temp->next != NULL) {
        temp = temp->next;
    }
    temp->next = newNode;
    newNode->prev = temp;
    return head;
}

void printList(Node* head) {
    Node* temp = head;
    while (temp != NULL) {
        printf("%d -> ", temp->data);
        temp = temp->next;
    }
    printf("null\n");
}

int main() {
    Node* head = NULL;
    head = insertAtEnd(head, 5);
    printList(head);
    return 0;
}
A5 -> null
Bnull
C5 -> 5 -> null
D0 -> 5 -> null
Attempts:
2 left
💡 Hint
Inserting into an empty list creates a single node which is both head and tail.
🔧 Debug
advanced
2:00remaining
Identify the bug causing a segmentation fault
Why does the following insertAtEnd function cause a segmentation fault when inserting into a non-empty list?
DSA C
Node* insertAtEnd(Node* head, int data) {
    Node* newNode = (Node*)malloc(sizeof(Node));
    newNode->data = data;
    newNode->next = NULL;
    if (head == NULL) {
        newNode->prev = NULL;
        return newNode;
    }
    Node* temp = head;
    while (temp->next != NULL) {
        temp = temp->next;
    }
    temp->next = newNode;
    // Missing assignment here
    return head;
}
AnewNode->prev is not set, so accessing prev causes segmentation fault
BnewNode->next is not set to NULL, causing infinite loop
Chead is NULL but function does not handle it
Dmalloc is not called, so newNode is NULL
Attempts:
2 left
💡 Hint
Check if all pointers of the new node are properly assigned.
❓ Predict Output
advanced
2:30remaining
Output after multiple insertions and one deletion
Given the code below, what is the printed list after inserting 1, 2, 3 at the end and then deleting the node with value 2?
DSA C
typedef struct Node {
    int data;
    struct Node* prev;
    struct Node* next;
} Node;

#include <stdio.h>
#include <stdlib.h>

Node* insertAtEnd(Node* head, int data) {
    Node* newNode = (Node*)malloc(sizeof(Node));
    newNode->data = data;
    newNode->next = NULL;
    if (head == NULL) {
        newNode->prev = NULL;
        return newNode;
    }
    Node* temp = head;
    while (temp->next != NULL) {
        temp = temp->next;
    }
    temp->next = newNode;
    newNode->prev = temp;
    return head;
}

Node* deleteNode(Node* head, int key) {
    Node* temp = head;
    while (temp != NULL && temp->data != key) {
        temp = temp->next;
    }
    if (temp == NULL) return head;
    if (temp->prev != NULL) temp->prev->next = temp->next;
    else head = temp->next;
    if (temp->next != NULL) temp->next->prev = temp->prev;
    free(temp);
    return head;
}

void printList(Node* head) {
    Node* temp = head;
    while (temp != NULL) {
        printf("%d -> ", temp->data);
        temp = temp->next;
    }
    printf("null\n");
}

int main() {
    Node* head = NULL;
    head = insertAtEnd(head, 1);
    head = insertAtEnd(head, 2);
    head = insertAtEnd(head, 3);
    head = deleteNode(head, 2);
    printList(head);
    return 0;
}
A1 -> 2 -> 3 -> null
B1 -> 3 -> null
C2 -> 3 -> null
D1 -> null
Attempts:
2 left
💡 Hint
Deleting node with value 2 removes it from the list, linking 1 directly to 3.
🧠 Conceptual
expert
1:30remaining
Why is updating the prev pointer important in doubly linked list insertion?
In the insertAtEnd function for a doubly linked list, why must we update the new node's prev pointer to point to the last node?
ATo avoid memory leaks during insertion
BTo prevent the list from becoming circular
CTo ensure the new node becomes the head of the list
DTo maintain backward traversal capability of the list
Attempts:
2 left
💡 Hint
Think about how doubly linked lists allow moving backwards.

Practice

(1/5)
1. What is the main purpose of inserting a node at the end of a doubly linked list?
easy
A. To add a new element after the last node
B. To remove the first node
C. To reverse the list
D. To find the middle node

Solution

  1. Step 1: Understand the list structure

    A doubly linked list has nodes connected forward and backward, allowing traversal in both directions.
  2. Step 2: Purpose of insertion at end

    Inserting at the end means adding a new node after the last node, extending the list.
  3. Final Answer:

    To add a new element after the last node -> Option A
  4. Quick Check:

    Insert at end = add after last node [OK]
Hint: Insert at end means add after last node [OK]
Common Mistakes:
  • Confusing insertion at end with deletion
  • Thinking insertion happens at the start
  • Mixing up singly and doubly linked list operations
2. Which of the following is the correct way to update the 'next' pointer of the last node when inserting a new node at the end in C?
easy
A. last->next = newNode;
B. newNode->next = last;
C. last->prev = newNode;
D. newNode->prev = NULL;

Solution

  1. Step 1: Identify the last node's next pointer

    The last node's 'next' pointer should point to the new node to link it at the end.
  2. Step 2: Correct pointer assignment

    Assigning 'last->next = newNode;' correctly links the new node after the last node.
  3. Final Answer:

    last->next = newNode; -> Option A
  4. Quick Check:

    Last node's next points to new node [OK]
Hint: Last node's next points to new node [OK]
Common Mistakes:
  • Assigning newNode->next to last (wrong direction)
  • Changing last->prev instead of last->next
  • Setting newNode->prev to NULL instead of last
3. What will be the output of the following code snippet after inserting a node with value 5 at the end of the doubly linked list 1 <-> 3 <-> 4?
struct Node {
  int data;
  struct Node* next;
  struct Node* prev;
};

void insertEnd(struct Node** head, int val) {
  struct Node* newNode = malloc(sizeof(struct Node));
  newNode->data = val;
  newNode->next = NULL;
  if (*head == NULL) {
    newNode->prev = NULL;
    *head = newNode;
    return;
  }
  struct Node* temp = *head;
  while (temp->next != NULL) {
    temp = temp->next;
  }
  temp->next = newNode;
  newNode->prev = temp;
}

void printList(struct Node* head) {
  while (head != NULL) {
    printf("%d ", head->data);
    head = head->next;
  }
}

int main() {
  struct Node* head = malloc(sizeof(struct Node));
  head->data = 1; head->prev = NULL;
  struct Node* second = malloc(sizeof(struct Node));
  second->data = 3; second->prev = head; head->next = second;
  struct Node* third = malloc(sizeof(struct Node));
  third->data = 4; third->prev = second; second->next = third; third->next = NULL;
  insertEnd(&head, 5);
  printList(head);
  return 0;
}
medium
A. 1 3 4 0
B. 1 3 4 5
C. 1 3 4
D. 5 1 3 4

Solution

  1. Step 1: Understand initial list and insertion

    The list is 1 <-> 3 <-> 4. The function inserts 5 at the end by traversing to last node (4) and linking new node after it.
  2. Step 2: Trace printList output

    After insertion, list is 1 <-> 3 <-> 4 <-> 5. Printing nodes in order outputs "1 3 4 5 "
  3. Final Answer:

    1 3 4 5 -> Option B
  4. Quick Check:

    List after insertEnd = 1 3 4 5 [OK]
Hint: Traverse to last, link new node, print all nodes [OK]
Common Mistakes:
  • Not setting newNode->prev correctly
  • Forgetting to set last node's next to newNode
  • Printing before insertion
4. Identify the error in the following code snippet for inserting a node at the end of a doubly linked list:
void insertEnd(struct Node** head, int val) {
  struct Node* newNode = malloc(sizeof(struct Node));
  newNode->data = val;
  newNode->next = NULL;
  if (*head == NULL) {
    *head = newNode;
    return;
  }
  struct Node* temp = *head;
  while (temp->next != NULL) {
    temp = temp->next;
  }
  temp->next = newNode;
}
medium
A. Wrong condition in while loop
B. Incorrect malloc size
C. Missing setting newNode->prev pointer
D. Not updating head pointer

Solution

  1. Step 1: Check pointer assignments for doubly linked list

    In doubly linked list, newNode->prev must point to the last node (temp) after insertion.
  2. Step 2: Identify missing pointer update

    The code sets temp->next = newNode but does not set newNode->prev = temp, breaking backward link.
  3. Final Answer:

    Missing setting newNode->prev pointer -> Option C
  4. Quick Check:

    newNode->prev must be set [OK]
Hint: Always set newNode->prev to last node [OK]
Common Mistakes:
  • Forgetting newNode->prev assignment
  • Assuming singly linked list logic applies
  • Not handling empty list case
5. Given a doubly linked list with nodes 10 <-> 20 <-> 30, write the sequence of pointer changes when inserting a new node with value 40 at the end. Which of the following correctly describes the final connections?
hard
A. newNode->prev = NULL; newNode->next = NULL; last->next = NULL
B. newNode->next = last; last->prev = newNode; newNode->prev = NULL
C. last->prev = newNode; newNode->next = last; newNode->prev = NULL
D. last->next = newNode; newNode->prev = last; newNode->next = NULL

Solution

  1. Step 1: Identify last node and new node pointers

    Last node is 30. New node 40 should be linked after 30 with next NULL.
  2. Step 2: Correct pointer assignments

    Set last->next = newNode to link forward, newNode->prev = last for backward link, and newNode->next = NULL as it is new end.
  3. Final Answer:

    last->next = newNode; newNode->prev = last; newNode->next = NULL -> Option D
  4. Quick Check:

    New node linked after last with proper prev and next [OK]
Hint: New node's prev = last; last's next = new node; new node's next = NULL [OK]
Common Mistakes:
  • Reversing prev and next pointers
  • Setting newNode->prev to NULL incorrectly
  • Not setting last->next to newNode
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard