📖 Scenario: Imagine you are managing a playlist of songs on your music app. You want to move forward and backward through songs easily.
🎯 Goal: You will build a simple doubly linked list to understand why it is better than a singly linked list for moving both forward and backward.
📋 What You'll Learn
Create a doubly linked list with three nodes containing the songs 'Song1', 'Song2', and 'Song3'.
Add a variable to keep track of the current song node.
Write code to move forward to the next song and backward to the previous song.
Print the current song after moving forward and backward.
💡 Why This Matters
🌍 Real World
Music players, web browsers (back and forward buttons), and undo-redo features use doubly linked lists to move easily in both directions.
💼 Career
Understanding doubly linked lists helps in jobs involving data structure design, software development, and optimizing navigation features.
Progress0 / 4 steps
1
Create a doubly linked list with three songs
Create a class called Node with attributes data, prev, and next. Then create three nodes with data 'Song1', 'Song2', and 'Song3'. Link them so that node1.next = node2, node2.prev = node1, node2.next = node3, and node3.prev = node2.
DSA Python
Hint
Remember, each node needs to know its previous and next node to move both ways.
2
Add a variable to track the current song
Create a variable called current and set it to node1 to start at the first song.
DSA Python
Hint
This variable will help us know which song is playing now.
3
Move forward and backward through the playlist
Write code to move current to the next song using current = current.next and then move back to the previous song using current = current.prev.
DSA Python
Hint
Use the next and prev links to move forward and backward.
4
Print the current song after moving forward and backward
Write two print statements: one to print current.data after moving forward, and one to print current.data after moving backward.
DSA Python
Hint
Print the data of the current node after each move.
Practice
(1/5)
1. Why might a doubly linked list be preferred over a singly linked list when you need to traverse the list backwards?
easy
A. Because doubly linked lists have pointers to both next and previous nodes, allowing backward traversal.
B. Because singly linked lists use less memory, making backward traversal faster.
C. Because singly linked lists have built-in backward pointers.
D. Because doubly linked lists store data twice for faster access.
Solution
Step 1: Understand pointer structure in doubly linked lists
Doubly linked lists have two pointers per node: one to the next node and one to the previous node.
Step 2: Compare with singly linked lists
Singly linked lists only have a pointer to the next node, so they cannot move backwards easily.
Final Answer:
Because doubly linked lists have pointers to both next and previous nodes, allowing backward traversal. -> Option A
Quick Check:
Backward traversal needs previous pointers = A [OK]
Hint: Backward traversal needs previous pointers, only in doubly linked lists [OK]
Common Mistakes:
Thinking singly linked lists can traverse backwards easily
Confusing memory usage with traversal ability
Assuming doubly linked lists duplicate data
2. Which of the following is the correct way to define a node in a doubly linked list in Python?
easy
A. class Node:
def __init__(self, data):
self.data = data
self.next = None
self.prev = None
B. class Node:
def __init__(self, data):
self.data = data
self.next = None
C. class Node:
def __init__(self, data):
self.data = data
self.prev = None
D. class Node:
def __init__(self, data):
self.next = None
self.prev = None
Solution
Step 1: Identify required pointers for doubly linked list node
A doubly linked list node must have pointers to both next and previous nodes.
Step 2: Check each option for correct attributes
class Node:
def __init__(self, data):
self.data = data
self.next = None
self.prev = None correctly defines data, next, and prev attributes in __init__.
Final Answer:
class Node:\n def __init__(self, data):\n self.data = data\n self.next = None\n self.prev = None -> Option A
Quick Check:
Doubly linked list node needs next and prev = A [OK]
Hint: Doubly linked list nodes have both next and prev pointers [OK]
Common Mistakes:
Omitting the prev pointer
Defining only prev without next
Not initializing data attribute
3. What will be the output of the following code snippet that uses a doubly linked list?
class Node:
def __init__(self, data):
self.data = data
self.next = None
self.prev = None
class DoublyLinkedList:
def __init__(self):
self.head = None
def append(self, data):
new_node = Node(data)
if not self.head:
self.head = new_node
return
last = self.head
while last.next:
last = last.next
last.next = new_node
new_node.prev = last
def print_reverse(self):
current = self.head
while current.next:
current = current.next
result = []
while current:
result.append(current.data)
current = current.prev
print(result)
dll = DoublyLinkedList()
dll.append(1)
dll.append(2)
dll.append(3)
dll.print_reverse()
medium
A. [1, 2, 3]
B. []
C. [1, 3, 2]
D. [3, 2, 1]
Solution
Step 1: Append nodes 1, 2, 3 to doubly linked list
Nodes are added at the end, so list is 1 <-> 2 <-> 3.
Step 2: Traverse to last node and print in reverse
print_reverse moves to last node (3), then collects data moving backward: 3, 2, 1.
Final Answer:
[3, 2, 1] -> Option D
Quick Check:
Reverse traversal collects nodes backward = B [OK]
Hint: Reverse print collects data from tail to head using prev pointers [OK]
Common Mistakes:
Confusing forward and backward traversal
Printing in insertion order instead of reverse
Not updating prev pointers correctly
4. The following code tries to delete the last node from a doubly linked list but causes an error. What is the mistake?
def delete_last(self):
if not self.head:
return
current = self.head
while current.next:
current = current.next
current.prev.next = None
current.prev = None
medium
A. It sets current.prev to None before removing the node.
B. It tries to delete the head node instead of the last node.
C. It does not handle the case when the list has only one node.
D. It does not update the head pointer after deletion.
Solution
Step 1: Analyze deletion logic for last node
The code moves to the last node, then sets previous node's next to None to remove last node.
Step 2: Check edge case for single-node list
If list has only one node, current.prev is None, so current.prev.next causes error.
Final Answer:
It does not handle the case when the list has only one node. -> Option C
Quick Check:
Single-node list needs special handling = C [OK]
Hint: Check for single-node list before accessing prev pointers [OK]
Common Mistakes:
Ignoring empty or single-node list edge cases
Assuming prev always exists
Not updating head when list becomes empty
5. You want to implement a feature that allows moving both forward and backward through a playlist of songs efficiently. Why is a doubly linked list better than a singly linked list for this, and what is a key trade-off?
hard
A. Singly linked lists are better because they have prev pointers; trade-off is more CPU usage.
B. Doubly linked lists allow easy forward and backward moves; trade-off is extra memory for prev pointers.
C. Doubly linked lists use less memory and are faster; trade-off is complex code.
D. Singly linked lists allow backward moves with less memory; trade-off is slower forward moves.
Solution
Step 1: Understand traversal needs for playlist
Moving forward and backward efficiently requires pointers in both directions.
Step 2: Compare singly vs doubly linked lists
Doubly linked lists have next and prev pointers, enabling easy two-way traversal; singly linked lists only have next pointers.
Step 3: Identify trade-off
Extra prev pointers in doubly linked lists use more memory compared to singly linked lists.
Final Answer:
Doubly linked lists allow easy forward and backward moves; trade-off is extra memory for prev pointers. -> Option B
Quick Check:
Two-way traversal needs prev pointers, costs extra memory = D [OK]
Hint: Two-way moves need prev pointers; extra memory is the cost [OK]
Common Mistakes:
Thinking singly linked lists support backward moves easily
Ignoring memory cost of extra pointers
Confusing speed with memory trade-offs
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.