Which of the following is the main advantage of a doubly linked list over a singly linked list?
Think about how you can move through the list in both directions.
A doubly linked list has two pointers per node, allowing traversal forward and backward. A singly linked list only allows forward traversal.
What will be the output of the following code that traverses a doubly linked list backwards?
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 append(self, data): new_node = Node(data) if not self.head: self.head = new_node self.tail = new_node else: self.tail.next = new_node new_node.prev = self.tail self.tail = new_node def traverse_backward(self): current = self.tail result = [] while current: result.append(current.data) current = current.prev print(' -> '.join(map(str, result)) + ' -> null') # Create list and append elements dll = DoublyLinkedList() dll.append(1) dll.append(2) dll.append(3) dll.traverse_backward()
Look at how the traversal starts from the tail and moves using the prev pointer.
The traversal starts at the tail node (3) and moves backward using the prev pointer, printing 3, then 2, then 1.
What is the error in the following code that removes a node from a doubly linked list?
def remove_node(node): if node.prev: node.prev.next = node.next if node.next: node.next.prev = node.prev node = None
Think about what 'node = None' does inside the function.
Setting 'node = None' only changes the local variable inside the function, it does not remove references to the node outside the function.
What will be the printed output after inserting a node with value 4 between nodes 3 and 5?
class Node: def __init__(self, data): self.data = data self.prev = None self.next = 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 insert_after(self, prev_node, data): if not prev_node: return new_node = Node(data) new_node.next = prev_node.next new_node.prev = prev_node if prev_node.next: prev_node.next.prev = new_node prev_node.next = new_node def print_list(self): current = self.head result = [] while current: result.append(current.data) current = current.next print(' -> '.join(map(str, result)) + ' -> null') # Setup list dll = DoublyLinkedList() dll.append(1) dll.append(3) dll.append(5) # Insert 4 after 3 current = dll.head while current and current.data != 3: current = current.next dll.insert_after(current, 4) dll.print_list()
Check how the new node is linked between 3 and 5.
The new node with value 4 is inserted after node 3 and before node 5, so the list becomes 1 -> 3 -> 4 -> 5 -> null.
Why might a doubly linked list be less memory efficient than a singly linked list?
Think about how many pointers each node holds in both list types.
Doubly linked list nodes have two pointers (prev and next), so they use more memory per node than singly linked lists, which have only one pointer.