0
0
DSA Pythonprogramming~10 mins

Delete from End of Doubly Linked List in DSA Python - Execution Trace

Choose your learning style9 modes available
Concept Flow - Delete from End of Doubly Linked List
Start at tail node
↓
Check if list is empty?
| No↓
If only one node
| Yes↓
Set head and tail to None
No↓
Move tail pointer to previous node
↓
Set new tail's next to None
↓
Delete old tail node
↓
Done
Start from the tail node, check if list is empty or has one node, then update tail pointer and remove last node.
Execution Sample
DSA Python
class Node:
    def __init__(self, data):
        self.data = data
        self.prev = None
        self.next = None

class DoublyLinkedList:
    def __init__(self):
        self.head = None
        self.tail = None

    def delete_end(self):
        if not self.tail:
            return
        if self.head == self.tail:
            self.head = None
            self.tail = None
            return
        self.tail = self.tail.prev
        self.tail.next = None
Deletes the last node from a doubly linked list, updating pointers accordingly.
Execution Table
StepOperationNodes in ListPointer ChangesVisual State
1Start with list: 10 <-> 20 <-> 30 <-> 4010 <-> 20 <-> 30 <-> 40head → 10, tail → 40ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā” ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā” ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā” ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā” │ data:10│ │ data:20│ │ data:30│ │ data:40│ │ prev:āˆ… │←── │ prev:10│←── │ prev:20│←── │ prev:30│ │ next:20│──→ │ next:30│──→ │ next:40│──→ │ next:āˆ… │ ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜ ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜ ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜ ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜ head tail
2Check if list is empty10 <-> 20 <-> 30 <-> 40No changeSame as step 1
3Check if only one node10 <-> 20 <-> 30 <-> 40No changeSame as step 1
4Move tail pointer to previous node (30)10 <-> 20 <-> 30 <-> 40tail: 40 → 30ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā” ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā” ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā” ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā” │ data:10│ │ data:20│ │ data:30│ │ data:40│ │ prev:āˆ… │←── │ prev:10│←── │ prev:20│←── │ prev:30│ │ next:20│──→ │ next:30│──→ │ next:40│──→ │ next:āˆ… │ ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜ ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜ ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜ ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜ head tail (moved here)
5Set new tail's next to None10 <-> 20 <-> 3030.next: 40 → Noneā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā” ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā” ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā” │ data:10│ │ data:20│ │ data:30│ │ prev:āˆ… │←── │ prev:10│←── │ prev:20│ │ next:20│──→ │ next:30│──→ │ next:āˆ… │ ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜ ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜ ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜ head tail
6Old tail (40) is now disconnected and deleted10 <-> 20 <-> 3040 node removedā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā” ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā” ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā” │ data:10│ │ data:20│ │ data:30│ │ prev:āˆ… │←── │ prev:10│←── │ prev:20│ │ next:20│──→ │ next:30│──→ │ next:āˆ… │ ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜ ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜ ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜ head tail
7End of delete operation10 <-> 20 <-> 30Pointers stableSame as step 6
šŸ’” Tail moved to previous node and old tail disconnected, list updated
Variable Tracker
VariableStartAfter Step 4After Step 5Final
headNode(10)Node(10)Node(10)Node(10)
tailNode(40)Node(30)Node(30)Node(30)
tail.nextNoneNode(40)NoneNone
list size4 nodes4 nodes3 nodes3 nodes
Key Moments - 3 Insights
Why do we check if the list has only one node before deleting?
Because if there is only one node, deleting it means the list becomes empty. We must set both head and tail to None to avoid dangling pointers. See step 3 in execution_table.
Why do we set the new tail's next pointer to None?
Because the new tail is the last node now, so its next pointer must not point to any node. This disconnects the old tail. See step 5 in execution_table.
What happens to the old tail node after deletion?
It becomes disconnected from the list and is removed from memory (garbage collected). It no longer has any references. See step 6 in execution_table.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table at step 4, which node does the tail pointer move to?
ANode with data 20
BNode with data 30
CNode with data 40
DNode with data 10
šŸ’” Hint
Check the 'Pointer Changes' column in step 4 of execution_table
At which step does the list size reduce from 4 to 3 nodes?
AStep 3
BStep 6
CStep 5
DStep 7
šŸ’” Hint
Look at the 'Nodes in List' and 'Variable Tracker' after step 5
If the list had only one node, what would happen to head and tail after deletion?
ABoth head and tail become None
BHead points to None, tail remains the node
CBoth remain pointing to the single node
DTail points to None, head remains the node
šŸ’” Hint
Refer to step 3 and the key moment about single node deletion
Concept Snapshot
Delete from End of Doubly Linked List:
- Start at tail node
- If list empty: do nothing
- If one node: set head and tail to None
- Else move tail to tail.prev
- Set new tail.next to None
- Old tail node removed
Pointers updated to keep list consistent
Full Transcript
To delete the last node from a doubly linked list, we start at the tail. If the list is empty, we do nothing. If there is only one node, we set both head and tail to None, making the list empty. Otherwise, we move the tail pointer to the previous node and set the new tail's next pointer to None to disconnect the old tail. The old tail node is then removed from the list. This process updates pointers carefully to maintain the list's structure.