Bird
Raised Fist0
DSA Javascriptprogramming

Insert at End of Doubly Linked List in DSA Javascript

Choose your learning style10 modes available
Mental Model
A doubly linked list is a chain of nodes where each node knows the next and previous node. To add a new node at the end, we link it after the last node and update pointers.
Analogy: Imagine a train where each carriage is connected to the one before and after. Adding a new carriage at the end means hooking it to the last carriage and making sure both know about each other.
null ← 1 ↔ 2 ↔ 3 -> null
                 ↑tail
Dry Run Walkthrough
Input: list: 1 ↔ 2 ↔ 3, insert value 4 at end
Goal: Add a new node with value 4 at the end of the doubly linked list
Step 1: Create new node with value 4
null ← 1 ↔ 2 ↔ 3 -> null   4 (new node, not linked yet)
Why: We need a new node to insert at the end
Step 2: Set new node's previous pointer to current tail (3)
null ← 1 ↔ 2 ↔ 3 ←-> 4 -> null
Why: New node must know the node before it
Step 3: Set current tail's next pointer to new node
null ← 1 ↔ 2 ↔ 3 ↔ 4 -> null
Why: Current last node must point to new node
Step 4: Update tail pointer to new node (4)
null ← 1 ↔ 2 ↔ 3 ↔ 4 -> null
                     ↑tail
Why: Tail must point to the new last node
Result:
null ← 1 ↔ 2 ↔ 3 ↔ 4 -> null
                     ↑tail
Annotated Code
DSA Javascript
class Node {
  constructor(value) {
    this.value = value;
    this.next = null;
    this.prev = null;
  }
}

class DoublyLinkedList {
  constructor() {
    this.head = null;
    this.tail = null;
  }

  insertAtEnd(value) {
    const newNode = new Node(value);
    if (!this.head) {
      this.head = newNode;
      this.tail = newNode;
      return;
    }
    this.tail.next = newNode; // link current tail to new node
    newNode.prev = this.tail; // link new node back to current tail
    this.tail = newNode; // update tail to new node
  }

  printList() {
    let curr = this.head;
    let result = '';
    while (curr) {
      result += curr.value;
      if (curr.next) result += ' ↔ ';
      curr = curr.next;
    }
    console.log(result + ' -> null');
  }
}

// Driver code
const dll = new DoublyLinkedList();
dll.insertAtEnd(1);
dll.insertAtEnd(2);
dll.insertAtEnd(3);
dll.insertAtEnd(4);
dll.printList();
const newNode = new Node(value);
Create new node to insert
if (!this.head) { this.head = newNode; this.tail = newNode; return; }
Handle empty list by setting head and tail to new node
this.tail.next = newNode; // link current tail to new node
Link current tail's next to new node
newNode.prev = this.tail; // link new node back to current tail
Link new node's prev to current tail
this.tail = newNode; // update tail to new node
Update tail pointer to new node
OutputSuccess
1 ↔ 2 ↔ 3 ↔ 4 -> null
Complexity Analysis
Time: O(1) because we directly access the tail and update pointers without traversal
Space: O(1) because we only create one new node regardless of list size
vs Alternative: Compared to singly linked list without tail pointer, this is faster since no traversal is needed to find the end
Edge Cases
Empty list
New node becomes both head and tail
DSA Javascript
if (!this.head) { this.head = newNode; this.tail = newNode; return; }
Single element list
New node links after the single node and tail updates
DSA Javascript
this.tail.next = newNode; // link current tail to new node
When to Use This Pattern
When you need to add an element at the end of a list and want fast insertion, use the insert at end pattern with a tail pointer in a doubly linked list.
Common Mistakes
Mistake: Forgetting to update the new node's prev pointer to the old tail
Fix: Always set newNode.prev = this.tail before updating tail
Mistake: Not updating the tail pointer to the new node after insertion
Fix: Set this.tail = newNode after linking nodes
Summary
Adds a new node at the end of a doubly linked list by updating next and prev pointers and the tail.
Use when you want to append elements quickly to the end of a doubly linked list.
The key is to link the new node to the current tail and then update the tail pointer.

Practice

(1/5)
1. What is the main purpose of inserting a node at the end of a doubly linked list?
easy
A. To reverse the order of the nodes in the list
B. To remove the first node from the list
C. To add a new element after the last node, updating both next and previous links
D. To find the middle node of the list

Solution

  1. Step 1: Understand the structure of a doubly linked list

    A doubly linked list has nodes with pointers to both the next and previous nodes, allowing traversal in both directions.
  2. Step 2: Purpose of insertion at the end

    Inserting at the end means adding a new node after the current last node and updating the pointers accordingly.
  3. Final Answer:

    To add a new element after the last node, updating both next and previous links -> Option C
  4. Quick Check:

    Insert at end = Add after last node [OK]
Hint: Insert at end means add after last node with correct links [OK]
Common Mistakes:
  • Confusing insertion at end with deletion
  • Not updating previous pointer of new node
  • Trying to insert at beginning instead
2. Which of the following is the correct syntax to create a new node in JavaScript for a doubly linked list?
easy
A. const newNode = new Node(value);
B. const newNode = { value: data, nextNode: null };
C. const newNode = [value, null, null];
D. const newNode = { data: value, next: null, prev: null };

Solution

  1. Step 1: Identify the node structure for doubly linked list

    A node should have data, next pointer, and previous pointer properties.
  2. Step 2: Check each option for correct properties

    const newNode = { data: value, next: null, prev: null }; correctly uses data, next, and prev keys with null pointers initially.
  3. Final Answer:

    const newNode = { data: value, next: null, prev: null }; -> Option D
  4. Quick Check:

    Node = data + next + prev [OK]
Hint: Node needs data, next, and prev keys set [OK]
Common Mistakes:
  • Using wrong property names like value instead of data
  • Missing prev pointer in node
  • Using array instead of object for node
3. Consider the following code snippet that inserts nodes at the end of a doubly linked list. What will be the printed list after inserting 10, 20, and 30?
class Node {
  constructor(data) {
    this.data = data;
    this.next = null;
    this.prev = null;
  }
}

class DoublyLinkedList {
  constructor() {
    this.head = null;
  }

  insertAtEnd(data) {
    const newNode = new Node(data);
    if (!this.head) {
      this.head = newNode;
      return;
    }
    let temp = this.head;
    while (temp.next) {
      temp = temp.next;
    }
    temp.next = newNode;
    newNode.prev = temp;
  }

  printList() {
    let temp = this.head;
    let result = '';
    while (temp) {
      result += temp.data + ' -> ';
      temp = temp.next;
    }
    result += 'null';
    console.log(result);
  }
}

const dll = new DoublyLinkedList();
dll.insertAtEnd(10);
dll.insertAtEnd(20);
dll.insertAtEnd(30);
dll.printList();
medium
A. null
B. 10 -> 20 -> 30 -> null
C. 10 -> 20 -> null
D. 30 -> 20 -> 10 -> null

Solution

  1. Step 1: Insert nodes one by one at the end

    First insert 10 as head, then 20 after 10, then 30 after 20.
  2. Step 2: Print the list from head to end

    Traverse from head: 10 -> 20 -> 30 -> null is printed.
  3. Final Answer:

    10 -> 20 -> 30 -> null -> Option B
  4. Quick Check:

    Insert order = print order [OK]
Hint: Insert at end keeps order; print from head shows insertion order [OK]
Common Mistakes:
  • Confusing insertion order with reversed output
  • Not updating prev pointer causing broken links
  • Printing from tail instead of head
4. The following code tries to insert a node at the end of a doubly linked list but causes an error. What is the mistake?
insertAtEnd(data) {
  const newNode = new Node(data);
  if (!this.head) {
    this.head = newNode;
  }
  let temp = this.head;
  while (temp.next) {
    temp = temp.next;
  }
  temp.next = newNode;
  newNode.prev = temp;
}
medium
A. Missing return after setting head when list is empty
B. Incorrectly assigning newNode.prev instead of newNode.next
C. Not creating newNode with correct constructor
D. Using while loop instead of for loop

Solution

  1. Step 1: Analyze the empty list case

    If head is null, newNode is assigned as head but code continues to traverse and assign next pointers.
  2. Step 2: Identify missing return causing duplicate insertion

    Without return after setting head, code tries to add newNode again after head, causing a cycle or error.
  3. Final Answer:

    Missing return after setting head when list is empty -> Option A
  4. Quick Check:

    Return after empty insert prevents duplicate links [OK]
Hint: Return immediately after empty list insertion [OK]
Common Mistakes:
  • Forgetting to stop function after empty list insert
  • Mixing up prev and next pointers
  • Assuming loop type causes error
5. You want to insert a node with value 40 at the end of a doubly linked list that currently has nodes 10 -> 20 -> 30 -> null. After insertion, what should be the correct state of the list and the pointers of the new node?
hard
A. 10 -> 20 -> 30 -> 40 -> null, newNode.prev points to 30, newNode.next is null
B. 40 -> 10 -> 20 -> 30 -> null, newNode.prev is null, newNode.next points to 10
C. 10 -> 20 -> 30 -> null, newNode.prev and newNode.next both null
D. 10 -> 20 -> 30 -> 40 -> null, newNode.prev is null, newNode.next points to 30

Solution

  1. Step 1: Insert new node at the end

    New node with value 40 is added after node 30, so 30's next points to new node.
  2. Step 2: Set new node's pointers correctly

    New node's prev points to 30, and next is null because it's the last node.
  3. Final Answer:

    10 -> 20 -> 30 -> 40 -> null, newNode.prev points to 30, newNode.next is null -> Option A
  4. Quick Check:

    Last node's next = null, newNode.prev = previous last node [OK]
Hint: New last node prev = old last node, next = null [OK]
Common Mistakes:
  • Setting newNode.prev to null incorrectly
  • Placing new node at the beginning instead
  • Not updating previous last node's next pointer
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