Imagine you have a list of items that can grow or shrink often. Which problem does a linked list solve better than an array?
Think about what happens when you add or remove items in the middle of an array.
Arrays require shifting elements when inserting or deleting in the middle, which is slow. Linked lists just change pointers, making these operations faster.
What is the printed linked list after inserting nodes 1, 2, 3 at the head?
class Node: def __init__(self, val): self.val = val self.next = None class LinkedList: def __init__(self): self.head = None def insert_head(self, val): new_node = Node(val) new_node.next = self.head self.head = new_node def print_list(self): current = self.head while current: print(current.val, end=' -> ') current = current.next print('null') ll = LinkedList() ll.insert_head(1) ll.insert_head(2) ll.insert_head(3) ll.print_list()
New nodes are added at the head, so the last inserted node appears first.
Each new node points to the previous head, so the list order reverses the insertion order at the head.
What error does this code raise when printing the linked list?
class Node: def __init__(self, val): self.val = val self.next = None class LinkedList: def __init__(self): self.head = None def print_list(self): current = self.head while current.next: print(current.val, end=' -> ') current = current.next print('null') ll = LinkedList() ll.head = Node(1) ll.head.next = Node(2) ll.print_list()
Check the loop condition and what happens to the last node.
The loop stops before printing the last node because it checks current.next instead of current. So the last node's value is never printed.
Which reason best explains why linked lists are often used to implement stacks?
Think about what happens when a stack grows beyond initial size in an array.
Stacks need fast push/pop operations and dynamic size. Linked lists provide this by adding/removing nodes at the head without resizing.
What is the printed linked list after deleting the node with value 2?
class Node: def __init__(self, val): self.val = val self.next = None class LinkedList: def __init__(self): self.head = None def insert_tail(self, val): new_node = Node(val) if not self.head: self.head = new_node return current = self.head while current.next: current = current.next current.next = new_node def delete_value(self, val): current = self.head prev = None while current: if current.val == val: if prev: prev.next = current.next else: self.head = current.next return prev = current current = current.next def print_list(self): current = self.head while current: print(current.val, end=' -> ') current = current.next print('null') ll = LinkedList() ll.insert_tail(1) ll.insert_tail(2) ll.insert_tail(3) ll.delete_value(2) ll.print_list()
Check how the delete_value method updates pointers when deleting the node.
The node with value 2 is removed by linking the previous node (1) to the next node (3), so the list becomes 1 -> 3 -> null.