Bird
Raised Fist0
DSA C#programming

Delete from End of Doubly Linked List in DSA C#

Choose your learning style10 modes available
Mental Model
A doubly linked list lets you move forward and backward through nodes. To delete from the end, you remove the last node and update the second last node to be the new end.
Analogy: Imagine a train with cars connected front and back. Removing the last car means disconnecting it and making the second last car the new tail.
head -> 1 ↔ 2 ↔ 3 ↔ 4 ← tail
null ← 1 ↔ 2 ↔ 3 ↔ 4 -> null
Dry Run Walkthrough
Input: list: 1 ↔ 2 ↔ 3 ↔ 4, delete from end
Goal: Remove the last node (4) and update the list tail to node 3
Step 1: start at tail node 4
head -> 1 ↔ 2 ↔ 3 ↔ [tail->4]
null ← 1 ↔ 2 ↔ 3 ↔ 4 -> null
Why: We need to remove the last node, so we start at the tail
Step 2: move tail pointer to previous node 3
head -> 1 ↔ 2 ↔ [tail->3] ↔ 4
null ← 1 ↔ 2 ↔ 3 ↔ 4 -> null
Why: The new tail will be the node before the current tail
Step 3: set tail's next pointer to null, disconnect node 4
head -> 1 ↔ 2 ↔ 3 -> null
null ← 1 ↔ 2 ↔ 3 -> null
Why: Disconnecting the old tail removes it from the list
Result:
head -> 1 ↔ 2 ↔ 3 -> null
null ← 1 ↔ 2 ↔ 3 -> null
Annotated Code
DSA C#
using System;

public class DoublyLinkedListNode
{
    public int Data;
    public DoublyLinkedListNode Prev;
    public DoublyLinkedListNode Next;

    public DoublyLinkedListNode(int data)
    {
        Data = data;
        Prev = null;
        Next = null;
    }
}

public class DoublyLinkedList
{
    public DoublyLinkedListNode Head;
    public DoublyLinkedListNode Tail;

    public DoublyLinkedList()
    {
        Head = null;
        Tail = null;
    }

    public void Append(int data)
    {
        var newNode = new DoublyLinkedListNode(data);
        if (Head == null)
        {
            Head = newNode;
            Tail = newNode;
            return;
        }
        Tail.Next = newNode; // link current tail to new node
        newNode.Prev = Tail; // link new node back to current tail
        Tail = newNode;      // update tail to new node
    }

    public void DeleteFromEnd()
    {
        if (Tail == null) return; // empty list, nothing to delete

        if (Tail.Prev == null)
        {
            // only one node in list
            Head = null;
            Tail = null;
            return;
        }

        Tail = Tail.Prev;       // move tail pointer back one node
        Tail.Next = null;       // disconnect old tail
    }

    public void PrintList()
    {
        var curr = Head;
        while (curr != null)
        {
            Console.Write(curr.Data);
            if (curr.Next != null) Console.Write(" ↔ ");
            curr = curr.Next;
        }
        Console.WriteLine();
    }
}

public class Program
{
    public static void Main()
    {
        var list = new DoublyLinkedList();
        list.Append(1);
        list.Append(2);
        list.Append(3);
        list.Append(4);

        list.DeleteFromEnd();
        list.PrintList();
    }
}
if (Tail == null) return; // empty list, nothing to delete
check if list is empty to avoid errors
if (Tail.Prev == null) { Head = null; Tail = null; return; }
handle single node list by clearing head and tail
Tail = Tail.Prev; // move tail pointer back one node
move tail pointer to previous node to remove last node
Tail.Next = null; // disconnect old tail
disconnect old tail node to remove it from list
OutputSuccess
1 ↔ 2 ↔ 3
Complexity Analysis
Time: O(1) because we directly access the tail and update pointers without traversal
Space: O(1) because no extra space is used besides a few pointers
vs Alternative: Compared to singly linked list deletion from end which requires O(n) traversal, doubly linked list deletion from end is faster at O(1)
Edge Cases
empty list
delete does nothing, list remains empty
DSA C#
if (Tail == null) return; // empty list, nothing to delete
single node list
deleting last node empties the list by setting head and tail to null
DSA C#
if (Tail.Prev == null)
{
    Head = null;
    Tail = null;
    return;
}
When to Use This Pattern
When you need to remove the last element quickly from a list and have backward links, use the doubly linked list delete from end pattern for O(1) deletion.
Common Mistakes
Mistake: Not updating the tail pointer to the previous node before disconnecting the last node
Fix: Always move the tail pointer back one node before setting Tail.Next to null
Mistake: Not handling the single node list case, causing null reference errors
Fix: Check if Tail.Prev is null and clear head and tail pointers accordingly
Summary
Deletes the last node from a doubly linked list by updating the tail pointer and disconnecting the old tail.
Use when you want to remove the last element efficiently from a doubly linked list.
The key is to move the tail pointer back one node and then disconnect the old tail to remove it.

Practice

(1/5)
1. What happens when you delete the last node from a doubly linked list that has multiple nodes?
easy
A. The first node is deleted instead.
B. The head pointer is set to null.
C. The list becomes empty immediately.
D. The second last node becomes the new tail and its next pointer is set to null.

Solution

  1. Step 1: Identify the last node and its previous node

    In a doubly linked list, the last node's previous node is the second last node.
  2. Step 2: Update the second last node's next pointer

    Set the second last node's next pointer to null to remove the last node from the list.
  3. Final Answer:

    The second last node becomes the new tail and its next pointer is set to null. -> Option D
  4. Quick Check:

    Deleting last node updates tail's next to null [OK]
Hint: Last node's previous next pointer must be null after deletion [OK]
Common Mistakes:
  • Setting head to null instead of updating tail
  • Not updating the previous node's next pointer
  • Deleting the first node by mistake
2. Which of the following is the correct C# syntax to delete the last node from a doubly linked list named dll?
easy
A. dll.Head = dll.Head.Next; dll.Head.Previous = null;
B. dll.Tail = dll.Tail.Previous; dll.Tail.Next = null;
C. dll.Tail = null; dll.Head = null;
D. dll.Head.Previous = dll.Tail; dll.Tail.Next = dll.Head;

Solution

  1. Step 1: Move tail pointer to previous node

    Set dll.Tail to dll.Tail.Previous to remove the last node.
  2. Step 2: Set new tail's next pointer to null

    Update dll.Tail.Next to null to mark the end of the list.
  3. Final Answer:

    dll.Tail = dll.Tail.Previous; dll.Tail.Next = null; -> Option B
  4. Quick Check:

    Correct tail update syntax = dll.Tail = dll.Tail.Previous; dll.Tail.Next = null; [OK]
Hint: Tail moves back, next pointer cleared [OK]
Common Mistakes:
  • Updating head instead of tail
  • Not setting tail's next to null
  • Setting both head and tail to null unnecessarily
3. Consider the following C# code that deletes the last node from a doubly linked list. What will be the printed list after deletion?
dll.AddLast(1); dll.AddLast(2); dll.AddLast(3); dll.DeleteFromEnd(); dll.PrintList();
medium
A. 2 -> 3 -> null
B. 1 -> 2 -> 3 -> null
C. 1 -> 2 -> null
D. null

Solution

  1. Step 1: Add nodes 1, 2, 3 to the list

    The list becomes 1 -> 2 -> 3 -> null.
  2. Step 2: Delete the last node (3)

    After deletion, the list becomes 1 -> 2 -> null.
  3. Final Answer:

    1 -> 2 -> null -> Option C
  4. Quick Check:

    Last node removed, list ends at 2 [OK]
Hint: Deleting last removes tail node only [OK]
Common Mistakes:
  • Assuming list remains unchanged
  • Deleting head instead of tail
  • Printing list before deletion
4. The following code attempts to delete the last node from a doubly linked list but causes a runtime error. What is the error?
if (dll.Tail != null) { dll.Tail = dll.Tail.Previous; dll.Tail.Next = null; }
medium
A. NullReferenceException when list has only one node
B. Syntax error due to missing braces
C. The head pointer is not updated
D. The list becomes circular

Solution

  1. Step 1: Check deletion when only one node exists

    If only one node exists, dll.Tail.Previous is null, so dll.Tail becomes null.
  2. Step 2: Accessing dll.Tail.Next causes error

    After setting dll.Tail to null, accessing dll.Tail.Next throws NullReferenceException.
  3. Final Answer:

    NullReferenceException when list has only one node -> Option A
  4. Quick Check:

    Accessing property on null tail causes error [OK]
Hint: Check for null tail before accessing Next [OK]
Common Mistakes:
  • Not handling single-node list case
  • Ignoring null checks before pointer access
  • Assuming head updates automatically
5. You have a doubly linked list with nodes: 10 <-> 20 <-> 30 <-> 40. After deleting the last node twice, what will be the list and the tail node's value?
hard
A. 10 <-> 20 -> null, Tail = 20
B. 10 <-> 20 <-> 30 -> null, Tail = 30
C. 10 -> null, Tail = 10
D. Empty list, Tail = null

Solution

  1. Step 1: Initial list and first deletion

    List is 10 <-> 20 <-> 30 <-> 40. Deleting last node removes 40, list becomes 10 <-> 20 <-> 30.
  2. Step 2: Second deletion removes 30

    After second deletion, list becomes 10 <-> 20, and tail points to node with value 20.
  3. Final Answer:

    10 <-> 20 -> null, Tail = 20 -> Option A
  4. Quick Check:

    Two deletions remove last two nodes [OK]
Hint: Each deletion removes tail, tail moves back [OK]
Common Mistakes:
  • Deleting only one node instead of two
  • Not updating tail after deletions
  • Confusing head and tail pointers
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