Bird
Raised Fist0
DSA Typescriptprogramming

Delete by Value in Doubly Linked List in DSA Typescript

Choose your learning style10 modes available
Mental Model
We find the node with the value and remove it by linking its neighbors directly to each other.
Analogy: Imagine a train with cars connected front and back. Removing a car means connecting the previous car directly to the next car, skipping the removed one.
null ← 1 ↔ 2 ↔ 3 ↔ 4 -> null
           ↑
Dry Run Walkthrough
Input: list: 1 ↔ 2 ↔ 3 ↔ 4, delete value 3
Goal: Remove the node with value 3 and keep the list connected
Step 1: start at head node with value 1
null ← [1] ↔ 2 ↔ 3 ↔ 4 -> null
Why: We begin searching from the start to find the node to delete
Step 2: move to next node with value 2
null ← 1 ↔ [2] ↔ 3 ↔ 4 -> null
Why: Keep moving forward to find the target value
Step 3: move to next node with value 3 (target found)
null ← 1 ↔ 2 ↔ [3] ↔ 4 -> null
Why: Found the node to delete
Step 4: link node 2's next to node 4 and node 4's prev to node 2, removing node 3
null ← 1 ↔ 2 ↔ 4 -> null
Why: By skipping node 3, we remove it and keep the list connected
Result:
null ← 1 ↔ 2 ↔ 4 -> null
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;
  tail: Node | null;

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

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

  deleteByValue(value: number): boolean {
    let curr = this.head;
    while (curr) {
      if (curr.value === value) {
        if (curr.prev) {
          curr.prev.next = curr.next; // link previous node to next
        } else {
          this.head = curr.next; // deleting head
        }
        if (curr.next) {
          curr.next.prev = curr.prev; // link next node to previous
        } else {
          this.tail = curr.prev; // deleting tail
        }
        return true; // deleted successfully
      }
      curr = curr.next; // move forward
    }
    return false; // value not found
  }

  toString(): string {
    let curr = this.head;
    let result = '';
    while (curr) {
      result += curr.value;
      if (curr.next) result += ' ↔ ';
      curr = curr.next;
    }
    return 'null ← ' + result + ' -> null';
  }
}

// Driver code
const list = new DoublyLinkedList();
list.append(1);
list.append(2);
list.append(3);
list.append(4);
console.log(list.toString());
const deleted = list.deleteByValue(3);
console.log(deleted ? 'Deleted 3' : '3 not found');
console.log(list.toString());
while (curr) {
iterate through nodes to find target value
if (curr.value === value) {
check if current node has the value to delete
if (curr.prev) { curr.prev.next = curr.next; } else { this.head = curr.next; }
link previous node to next or update head if deleting first node
if (curr.next) { curr.next.prev = curr.prev; } else { this.tail = curr.prev; }
link next node to previous or update tail if deleting last node
curr = curr.next;
move to next node if current is not target
OutputSuccess
null ← 1 ↔ 2 ↔ 3 ↔ 4 -> null Deleted 3 null ← 1 ↔ 2 ↔ 4 -> null
Complexity Analysis
Time: O(n) because we may need to check each node once to find the value
Space: O(1) because we only use a few pointers and no extra data structures
vs Alternative: Compared to arrays where deleting requires shifting elements O(n), doubly linked list deletion is O(1) once node is found, but finding node is O(n)
Edge Cases
empty list
deleteByValue returns false, list remains empty
DSA Typescript
while (curr) {
delete head node
head pointer updates to next node, prev of new head is null
DSA Typescript
if (curr.prev) { curr.prev.next = curr.next; } else { this.head = curr.next; }
delete tail node
tail pointer updates to previous node, next of new tail is null
DSA Typescript
if (curr.next) { curr.next.prev = curr.prev; } else { this.tail = curr.prev; }
value not found
function returns false, list unchanged
DSA Typescript
return false;
When to Use This Pattern
When you need to remove a specific value from a list that allows backward and forward traversal, use delete by value in doubly linked list to efficiently update neighbors.
Common Mistakes
Mistake: Not updating the head or tail pointers when deleting the first or last node
Fix: Add checks to update head if deleting first node and tail if deleting last node
Mistake: Forgetting to update the prev pointer of the next node
Fix: Always update next node's prev pointer to skip the deleted node
Summary
Deletes a node by value in a doubly linked list by reconnecting neighbors.
Use when you want to remove a specific value and keep the list connected both ways.
The key is to update both previous and next pointers to skip the deleted node.

Practice

(1/5)
1. What happens when you delete a node by value in a doubly linked list?
easy
A. All nodes are deleted regardless of value
B. The node with the matching value is removed and links are updated
C. Only the first node is deleted no matter the value
D. The list is reversed instead of deleting

Solution

  1. Step 1: Identify the node with the given value

    Traverse the list from head to tail to find the node whose value matches the target.
  2. Step 2: Remove the node and update links

    Adjust the previous node's next pointer and the next node's previous pointer to exclude the found node.
  3. Final Answer:

    The node with the matching value is removed and links are updated -> Option B
  4. Quick Check:

    Deleting by value removes matching node [OK]
Hint: Find node by value, then update previous and next links [OK]
Common Mistakes:
  • Not updating previous node's next pointer
  • Not updating next node's previous pointer
  • Deleting all nodes instead of one
2. Which of the following is the correct TypeScript syntax to delete a node by value in a doubly linked list?
easy
A. function deleteNode(value) { /* code */ }
B. removeNode(value: number) => { /* code */ }
C. deleteNode(value: number): void { /* code */ }
D. delete node(value: number) { /* code */ }

Solution

  1. Step 1: Check method declaration syntax in TypeScript class

    Methods inside classes use the syntax methodName(params): returnType { body }.
  2. Step 2: Identify correct syntax for deleteNode method

    deleteNode(value: number): void { /* code */ } uses correct TypeScript method syntax with type annotation and void return.
  3. Final Answer:

    deleteNode(value: number): void { /* code */ } -> Option C
  4. Quick Check:

    TypeScript method syntax = deleteNode(value: number): void { /* code */ } [OK]
Hint: Use methodName(params): returnType { } inside class [OK]
Common Mistakes:
  • Using arrow function syntax inside class method
  • Missing type annotations
  • Using invalid keywords like 'delete node'
3. Given the doubly linked list: 10 <-> 20 <-> 30 <-> 40, what is the list after deleting the node with value 30?
medium
A. 10 <-> 20 <-> 40
B. 10 <-> 30 <-> 40
C. 20 <-> 30 <-> 40
D. 10 <-> 20 <-> 30 <-> 40

Solution

  1. Step 1: Locate node with value 30

    Traverse the list: 10 -> 20 -> 30 found at third node.
  2. Step 2: Remove node 30 and link 20 to 40

    Update 20's next pointer to 40 and 40's previous pointer to 20.
  3. Final Answer:

    10 <-> 20 <-> 40 -> Option A
  4. Quick Check:

    Deleted 30, list links updated [OK]
Hint: Remove node, link previous and next nodes directly [OK]
Common Mistakes:
  • Not updating previous node's next pointer
  • Not updating next node's previous pointer
  • Deleting wrong node
4. What is wrong with this delete function snippet for doubly linked list?
deleteNode(value: number): void {
  let current = this.head;
  while (current !== null) {
    if (current.value === value) {
      current.prev.next = current.next;
      current.next.prev = current.prev;
      break;
    }
    current = current.next;
  }
}
medium
A. It does not handle deleting the head node correctly
B. It deletes all nodes with the value instead of one
C. It uses wrong variable names
D. It causes infinite loop

Solution

  1. Step 1: Check handling of head node deletion

    If current is head, current.prev is null, so current.prev.next causes error.
  2. Step 2: Identify missing head update

    Function does not update this.head when deleting the first node, causing broken list.
  3. Final Answer:

    It does not handle deleting the head node correctly -> Option A
  4. Quick Check:

    Head deletion needs special handling [OK]
Hint: Check if node is head before updating prev pointers [OK]
Common Mistakes:
  • Not checking if current.prev is null
  • Not updating head pointer when deleting first node
  • Assuming all nodes have prev and next
5. You have a doubly linked list: 5 <-> 10 <-> 15 <-> 20 <-> 25. You want to delete the node with value 5, then delete the node with value 25. What is the final list?
hard
A. 15 <-> 20
B. 5 <-> 10 <-> 15 <-> 20
C. 10 <-> 15 <-> 20 <-> 25
D. 10 <-> 15 <-> 20

Solution

  1. Step 1: Delete node with value 5 (head node)

    Update head to 10, set 10.prev to null.
  2. Step 2: Delete node with value 25 (tail node)

    Update 20.next to null, removing 25.
  3. Final Answer:

    10 <-> 15 <-> 20 -> Option D
  4. Quick Check:

    Deleted head and tail nodes correctly [OK]
Hint: Update head or tail pointers when deleting first or last nodes [OK]
Common Mistakes:
  • Not updating head when deleting first node
  • Not updating tail when deleting last node
  • Breaking links between middle nodes
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