Bird
Raised Fist0
DSA Javascriptprogramming~10 mins

Dequeue Using Linked List in DSA Javascript - Execution Trace

Choose your learning style10 modes available
Concept Flow - Dequeue Using Linked List
Create new node
↓
Is Dequeue empty?
↓
Set head & tail
↓
For addRear: tail.next = newNode; tail = newNode
↓
For removeFront: head = head.next
↓
For removeRear: traverse to node before tail; tail = prevNode; tail.next = null
↓
Update size
↓
Done
Shows how nodes are added or removed from front or rear in a linked list-based dequeue.
Execution Sample
DSA Javascript
class Node {
  constructor(value) {
    this.value = value;
    this.next = null;
  }
}

// Add to front
addFront(value) {
  const newNode = new Node(value);
  newNode.next = this.head;
  this.head = newNode;
  if (!this.tail) this.tail = newNode;
  this.size++;
}
Adds a new node at the front of the dequeue linked list.
Execution Table
StepOperationNodes in ListPointer ChangesVisual State
1Initialize empty dequeueNonehead = null, tail = null, size = 0null
2addFront(10)1 nodehead -> newNode(10), tail -> newNode(10), size = 110 -> null
3addRear(20)2 nodestail.next -> newNode(20), tail -> newNode(20), size = 210 -> 20 -> null
4addFront(5)3 nodesnewNode(5).next -> head(10), head -> newNode(5), size = 35 -> 10 -> 20 -> null
5removeFront()2 nodeshead -> head.next(10), size = 210 -> 20 -> null
6removeRear()1 nodeTraverse to node(10) before tail, tail -> 10, tail.next = null, size = 110 -> null
7removeFront()0 nodeshead -> null, tail -> null, size = 0null
8removeFront()0 nodesNo change, dequeue emptynull
💡 Stop when dequeue is empty and remove operation is called.
Variable Tracker
VariableStartAfter Step 2After Step 3After Step 4After Step 5After Step 6After Step 7After Step 8
headnullNode(10)Node(10)Node(5)Node(10)Node(10)nullnull
tailnullNode(10)Node(20)Node(20)Node(20)Node(10)nullnull
size01232100
Key Moments - 3 Insights
Why does removeRear need to traverse the list?
Because in a singly linked list, we only have a pointer to tail, but no pointer to the node before tail. So to update tail, we must find the node before it by traversing from head (see step 6 in execution_table).
What happens when we removeFront on an empty dequeue?
No changes occur because the dequeue is already empty (head and tail are null). This is shown in step 8 where pointers remain null and size stays 0.
Why do we update tail to null when the last node is removed?
When the last node is removed (step 7), both head and tail must be set to null to indicate the dequeue is empty. Otherwise, tail would point to a non-existent node.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution table at step 4. What is the visual state of the dequeue?
A10 -> 20 -> 5 -> null
B10 -> 5 -> 20 -> null
C5 -> 10 -> 20 -> null
D20 -> 10 -> 5 -> null
💡 Hint
Check the Visual State column at step 4 in the execution_table.
At which step does the dequeue become empty?
AStep 6
BStep 7
CStep 5
DStep 8
💡 Hint
Look at the size and pointer changes in the execution_table rows.
If we addRear(30) after step 7, what will be the new tail value?
ANode(30)
BNode(10)
Cnull
DNode(20)
💡 Hint
After step 7, dequeue is empty, so adding rear sets tail to new node (see addFront logic in variable_tracker).
Concept Snapshot
Dequeue using singly linked list:
- addFront: newNode.next = head; head = newNode; if empty tail = newNode
- addRear: tail.next = newNode; tail = newNode; if empty head = newNode
- removeFront: head = head.next; if empty tail = null
- removeRear: traverse to node before tail; tail = prevNode; tail.next = null
- size tracks number of nodes
- Traversal needed for removeRear due to singly linked list
Full Transcript
This visual trace shows how a dequeue is implemented using a singly linked list. We start with an empty dequeue where head and tail pointers are null and size is zero. Adding to the front creates a new node that points to the current head, then updates head to this new node. If the dequeue was empty, tail also points to this new node. Adding to the rear links the new node after tail and updates tail. Removing from front moves head to the next node, and if the list becomes empty, tail is set to null. Removing from rear requires traversing from head to find the node before tail, then updating tail to that node and setting tail.next to null. The size variable keeps track of the number of nodes. The execution table shows each step's operation, pointer changes, and the visual state of the list. Key moments clarify why traversal is needed for removeRear and what happens when removing from an empty dequeue. The quiz tests understanding of the visual states and pointer updates.

Practice

(1/5)
1. What is the main advantage of using a linked list to implement a dequeue compared to an array?
easy
A. It automatically sorts the elements as they are inserted.
B. It allows efficient insertion and deletion from both ends without shifting elements.
C. It uses less memory than an array for the same number of elements.
D. It prevents duplicate elements from being added.

Solution

  1. Step 1: Understand linked list operations

    A linked list allows adding or removing nodes at the front or back in constant time without moving other elements.
  2. Step 2: Compare with array behavior

    Arrays require shifting elements when inserting or deleting at the front, which is less efficient.
  3. Final Answer:

    It allows efficient insertion and deletion from both ends without shifting elements. -> Option B
  4. Quick Check:

    Linked list = efficient ends operations [OK]
Hint: Linked list avoids shifting elements for front/back operations [OK]
Common Mistakes:
  • Thinking arrays are always more memory efficient
  • Assuming linked list sorts elements automatically
  • Believing linked list prevents duplicates
2. Which of the following is the correct way to add a new node at the front of a dequeue implemented using a linked list in JavaScript?
easy
A. Create new node, set its prev to current tail, update tail to new node.
B. Create new node, set its prev to current head, update head to new node.
C. Create new node, set its next to null, update tail to new node.
D. Create new node, set its next to current head, update head to new node.

Solution

  1. Step 1: Understand adding at front in linked list

    To add at front, new node's next points to current head, then head updates to new node.
  2. Step 2: Check options for correctness

    Create new node, set its next to current head, update head to new node. matches this logic; others incorrectly use prev or tail.
  3. Final Answer:

    Create new node, set its next to current head, update head to new node. -> Option D
  4. Quick Check:

    Add front = newNode.next = head; head = newNode [OK]
Hint: New front node points next to old head [OK]
Common Mistakes:
  • Confusing prev and next pointers
  • Updating tail instead of head when adding front
  • Setting next to null incorrectly
3. Consider the following JavaScript code for a dequeue using a doubly linked list:
class Node {
  constructor(value) {
    this.value = value;
    this.next = null;
    this.prev = null;
  }
}

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

  addFront(value) {
    const newNode = new Node(value);
    if (!this.head) {
      this.head = this.tail = newNode;
    } else {
      newNode.next = this.head;
      this.head.prev = newNode;
      this.head = newNode;
    }
  }

  addRear(value) {
    const newNode = new Node(value);
    if (!this.tail) {
      this.head = this.tail = newNode;
    } else {
      this.tail.next = newNode;
      newNode.prev = this.tail;
      this.tail = newNode;
    }
  }

  removeFront() {
    if (!this.head) return null;
    const val = this.head.value;
    this.head = this.head.next;
    if (this.head) this.head.prev = null;
    else this.tail = null;
    return val;
  }
}

const dq = new Dequeue();
dq.addRear(10);
dq.addFront(20);
dq.addRear(30);
const removed = dq.removeFront();
console.log(removed);
console.log(dq.head.value + ' -> ' + dq.tail.value);
What will be the output?
medium
A. 10 20 -> 30
B. 20 30 -> 10
C. 20 10 -> 30
D. 10 30 -> 20

Solution

  1. Step 1: Trace insertions

    addRear(10): list is 10 addFront(20): list is 20 -> 10 addRear(30): list is 20 -> 10 -> 30
  2. Step 2: Trace removal

    removeFront() removes 20, returns 20. List becomes 10 -> 30.
  3. Final Answer:

    20 10 -> 30 -> Option C
  4. Quick Check:

    Remove front returns 20; list head=10, tail=30 [OK]
Hint: Track head/tail changes step-by-step [OK]
Common Mistakes:
  • Confusing addFront and addRear order
  • Forgetting to update prev pointers
  • Mixing removed value with current head
4. The following code snippet is intended to remove the rear node from a dequeue implemented using a doubly linked list. What is the error?
removeRear() {
  if (!this.tail) return null;
  const val = this.tail.value;
  this.tail = this.tail.prev;
  this.tail.next = null;
  return val;
}
medium
A. It does not handle the case when the list becomes empty after removal.
B. It incorrectly updates the head pointer instead of tail.
C. It should set this.tail.prev to null instead of this.tail.next.
D. It returns the wrong value after removal.

Solution

  1. Step 1: Analyze removal logic

    After setting tail to tail.prev, if tail becomes null (list empty), accessing tail.next causes error.
  2. Step 2: Identify missing check

    Code must check if tail is null before setting tail.next = null to avoid runtime error.
  3. Final Answer:

    It does not handle the case when the list becomes empty after removal. -> Option A
  4. Quick Check:

    Check empty list after removal to avoid null pointer [OK]
Hint: Check for empty list before pointer updates [OK]
Common Mistakes:
  • Not checking if tail is null after update
  • Confusing head and tail pointers
  • Setting wrong pointer to null
5. You want to implement a function reverseDequeue() that reverses the order of nodes in a dequeue implemented using a doubly linked list. Which approach correctly reverses the dequeue?
hard
A. Traverse each node, swap its next and prev pointers, then swap head and tail pointers.
B. Traverse each node, set next to null, and prev to head, then update head to tail.
C. Create a new dequeue and addRear nodes from the original dequeue's front to rear.
D. Swap values of head and tail nodes only.

Solution

  1. Step 1: Understand reversal in doubly linked list

    Reversing means each node's next and prev pointers must be swapped to reverse direction.
  2. Step 2: Update head and tail pointers

    After swapping pointers in all nodes, head and tail pointers must be swapped to reflect new ends.
  3. Final Answer:

    Traverse each node, swap its next and prev pointers, then swap head and tail pointers. -> Option A
  4. Quick Check:

    Swap next/prev in nodes + swap head/tail [OK]
Hint: Swap next and prev pointers in all nodes [OK]
Common Mistakes:
  • Only swapping head and tail values
  • Setting next to null incorrectly
  • Creating new dequeue instead of reversing in place
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