Bird
Raised Fist0
DSA Typescriptprogramming

Reverse a Doubly Linked List in DSA Typescript

Choose your learning style10 modes available
Mental Model
To reverse a doubly linked list, we swap the previous and next links of each node, then update the head to the last node.
Analogy: Imagine a train with cars connected front and back. Reversing means flipping the direction of all connectors so the last car becomes the first.
null ← 1 ↔ 2 ↔ 3 -> null
↑head
Dry Run Walkthrough
Input: list: 1 ↔ 2 ↔ 3, reverse the list
Goal: Change the list so it reads 3 ↔ 2 ↔ 1 with head at 3
Step 1: Start at head (node 1), swap its prev and next pointers
null -> 1 ← 2 ↔ 3 -> null
↑curr=1
Why: Swapping pointers reverses the direction for this node
Step 2: Move curr to old next (which is prev after swap), now curr=2
null ← 1 -> 2 ↔ 3 -> null
↑curr=2
Why: We continue reversing by moving to the next node in original order
Step 3: Swap prev and next of node 2
null ← 1 -> 2 ← 3 -> null
↑curr=2
Why: Reverse pointers for node 2 to flip its direction
Step 4: Move curr to old next (prev after swap), now curr=3
null ← 1 -> 2 -> 3 -> null
↑curr=3
Why: Continue to next node to reverse pointers
Step 5: Swap prev and next of node 3
null ← 1 -> 2 -> 3 ← null
↑curr=3
Why: Reverse pointers for last node
Step 6: Move curr to old next (prev after swap), now curr=null; update head to last node (3)
null ← 1 -> 2 -> 3 ← null
↑head=3
Why: End of list reached, head updated to new front
Result:
null ← 1 -> 2 -> 3 ← null
↑head=3
List reversed: 3 ↔ 2 ↔ 1
Annotated Code
DSA Typescript
class Node {
  value: number;
  prev: Node | null;
  next: Node | null;
  constructor(value: number) {
    this.value = value;
    this.prev = null;
    this.next = null;
  }
}

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

  append(value: number): void {
    const newNode = new Node(value);
    if (!this.head) {
      this.head = newNode;
      return;
    }
    let curr = this.head;
    while (curr.next) {
      curr = curr.next;
    }
    curr.next = newNode;
    newNode.prev = curr;
  }

  reverse(): void {
    let curr = this.head;
    let temp: Node | null = null;
    while (curr) {
      temp = curr.prev; // save prev
      curr.prev = curr.next; // swap prev and next
      curr.next = temp;
      curr = curr.prev; // move to next node in original order
    }
    if (temp) {
      this.head = temp.prev; // update head to last node
    }
  }

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

// Driver code
const dll = new DoublyLinkedList();
dll.append(1);
dll.append(2);
dll.append(3);
console.log('Original list:');
dll.printList();
dll.reverse();
console.log('Reversed list:');
dll.printList();
while (curr) {
iterate through each node to reverse pointers
temp = curr.prev; // save prev
store original prev pointer before swapping
curr.prev = curr.next; // swap prev and next
reverse the direction of pointers for current node
curr.next = temp;
complete the swap of prev and next pointers
curr = curr.prev; // move to next node in original order
advance to next node using swapped pointers
if (temp) { this.head = temp.prev; }
update head to new front after reversal
OutputSuccess
Original list: 1 ↔ 2 ↔ 3 ↔ null Reversed list: 3 ↔ 2 ↔ 1 ↔ null
Complexity Analysis
Time: O(n) because we visit each node once to swap pointers
Space: O(1) because we only use a few extra variables for swapping
vs Alternative: Compared to creating a new reversed list (O(n) time and space), this reverses in place saving memory
Edge Cases
empty list
reverse does nothing, head remains null
DSA Typescript
while (curr) {
single node list
reverse swaps pointers but list remains same, head unchanged
DSA Typescript
while (curr) {
When to Use This Pattern
When asked to reverse a doubly linked list, swap each node's prev and next pointers and update the head to the last node to reverse in place.
Common Mistakes
Mistake: Advancing curr using curr.next after swapping pointers causes skipping nodes or infinite loop
Fix: Advance curr using curr.prev because pointers are swapped
Mistake: Not updating head to new front after reversal
Fix: Set head to temp.prev after loop ends
Summary
Reverses a doubly linked list by swapping each node's prev and next pointers.
Use when you need to reverse the order of nodes in a doubly linked list efficiently.
The key is to swap pointers and move along the original next nodes using the swapped pointers.

Practice

(1/5)
1. What is the main purpose of reversing a doubly linked list?
easy
A. To sort the nodes in ascending order
B. To reverse the order of nodes so the last becomes first and vice versa
C. To delete all nodes from the list
D. To convert it into a singly linked list

Solution

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

    A doubly linked list has nodes with pointers to both previous and next nodes.
  2. Step 2: Purpose of reversing

    Reversing swaps the direction so the last node becomes the first and the first becomes the last.
  3. Final Answer:

    To reverse the order of nodes so the last becomes first and vice versa -> Option B
  4. Quick Check:

    Reversing = changing node order [OK]
Hint: Reversing flips the list order, not deleting or sorting [OK]
Common Mistakes:
  • Confusing reversing with deleting nodes
  • Thinking reversing sorts the list
  • Assuming it converts to singly linked list
2. Which of the following TypeScript code snippets correctly swaps the next and prev pointers of a node in a doubly linked list?
easy
A. let temp = node.next; node.next = node.prev; node.prev = temp;
B. node.next = node.next; node.prev = node.prev;
C. node.prev = node.next; node.next = node.prev;
D. let temp = node.prev; node.prev = node.next; node.next = temp.next;

Solution

  1. Step 1: Identify correct swapping logic

    Swapping pointers requires a temporary variable to hold one pointer before assignment.
  2. Step 2: Check each option

    let temp = node.next; node.next = node.prev; node.prev = temp; correctly uses a temp variable to swap next and prev. Others either assign incorrectly or lose references.
  3. Final Answer:

    let temp = node.next; node.next = node.prev; node.prev = temp; -> Option A
  4. Quick Check:

    Swap pointers using temp variable [OK]
Hint: Use a temp variable to swap pointers safely [OK]
Common Mistakes:
  • Assigning pointers without temp causes data loss
  • Mixing up next and prev assignments
  • Using incorrect pointer references
3. What will be the output of the following TypeScript code that reverses a doubly linked list?
class Node {
  data: number;
  next: Node | null = null;
  prev: Node | null = null;
  constructor(data: number) { this.data = data; }
}

function reverse(head: Node | null): Node | null {
  let current = head;
  let temp: Node | null = null;
  while (current !== null) {
    temp = current.prev;
    current.prev = current.next;
    current.next = temp;
    current = current.prev;
  }
  if (temp !== null) {
    head = temp.prev;
  }
  return head;
}

// Create list: 1 <-> 2 <-> 3
const n1 = new Node(1);
const n2 = new Node(2);
n1.next = n2; n2.prev = n1;
const n3 = new Node(3);
n2.next = n3; n3.prev = n2;

const newHead = reverse(n1);

// Print reversed list
let result = [];
let node = newHead;
while (node !== null) {
  result.push(node.data);
  node = node.next;
}
console.log(result);
medium
A. []
B. [1, 2, 3]
C. [3, 2, 1]
D. [3, 1, 2]

Solution

  1. Step 1: Trace pointer swaps in the loop

    Each node swaps its next and prev. The loop moves forward using the old next pointer now in prev.
  2. Step 2: Update head to new first node

    After loop, head is updated to last node processed, which is node with data 3.
  3. Final Answer:

    [3, 2, 1] -> Option C
  4. Quick Check:

    Reversed list order = [3, 2, 1] [OK]
Hint: Reversing swaps pointers and updates head to last node [OK]
Common Mistakes:
  • Not updating head after reversal
  • Confusing next and prev in loop
  • Printing original list order
4. Identify the bug in this TypeScript function that attempts to reverse a doubly linked list:
function reverse(head: Node | null): Node | null {
  let current = head;
  while (current !== null) {
    let temp = current.next;
    current.next = current.prev;
    current.prev = temp;
    current = current.next;
  }
  return head;
}
medium
A. The function should return current instead of head
B. The pointers next and prev are swapped incorrectly
C. The loop condition should be current.next !== null
D. The function does not update the head to the new first node after reversal

Solution

  1. Step 1: Check pointer swapping logic

    The swapping of next and prev is correct using a temp variable.
  2. Step 2: Verify head update after reversal

    The function returns original head without updating it to the new first node, so the reversed list head is incorrect.
  3. Final Answer:

    The function does not update the head to the new first node after reversal -> Option D
  4. Quick Check:

    Head must update to new first node [OK]
Hint: Always update head to last processed node after reversal [OK]
Common Mistakes:
  • Forgetting to update head after reversal
  • Returning old head instead of new head
  • Incorrect loop condition causing infinite loop
5. Given a doubly linked list with nodes containing integer data, how would you modify the reversal function to also count how many nodes were reversed and return both the new head and the count?
hard
A. Modify the function to use an object return type like { head: Node | null, count: number }, increment count inside the loop, and update head after reversal.
B. Add a global variable to count nodes and return only the new head.
C. Count nodes before reversal and return the count without changing the function.
D. Return an array with the reversed list nodes and count without modifying the reversal logic.

Solution

  1. Step 1: Add a counter variable inside the reversal function

    Initialize a count variable to zero and increment it each time a node is processed in the reversal loop.
  2. Step 2: Return both new head and count

    After reversal, return an object containing the updated head and the count of nodes reversed.
  3. Final Answer:

    Modify the function to use an object return type like { head: Node | null, count: number }, increment count inside the loop, and update head after reversal. -> Option A
  4. Quick Check:

    Return head and count together after reversal [OK]
Hint: Use an object return type to return multiple values [OK]
Common Mistakes:
  • Using global variables instead of local counters
  • Not updating head before returning
  • Returning count without reversing
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