Enqueue Using Linked List in DSA Python - Time & Space Complexity
We want to understand how the time to add an item to a queue using a linked list changes as the queue grows.
How does the number of steps needed to add one item change when the queue gets bigger?
Analyze the time complexity of the following code snippet.
class Node:
def __init__(self, data):
self.data = data
self.next = None
class Queue:
def __init__(self):
self.front = None
self.rear = None
def enqueue(self, data):
new_node = Node(data)
if self.rear is None:
self.front = self.rear = new_node
return
self.rear.next = new_node
self.rear = new_node
This code adds a new item to the end of a queue implemented with a linked list.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Adding a new node by updating pointers.
- How many times: This happens once per enqueue call, no loops or traversals.
Adding one item always takes the same number of steps, no matter how big the queue is.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | 5-6 steps |
| 100 | 5-6 steps |
| 1000 | 5-6 steps |
Pattern observation: The time to add one item stays about the same regardless of queue size.
Time Complexity: O(1)
This means adding an item takes a constant amount of time no matter how many items are already in the queue.
[X] Wrong: "Adding an item takes longer as the queue grows because we have to find the end each time."
[OK] Correct: Because we keep a pointer to the end (rear), we add the new item directly without searching, so time stays constant.
Knowing that enqueue in a linked list queue is fast and constant time shows you understand efficient data structure design, a key skill in interviews.
"What if we did not keep a rear pointer and had to find the end each time? How would the time complexity change?"
Practice
enqueue operation do in a linked list implementation of a queue?Solution
Step 1: Understand enqueue operation in queue
Enqueue means adding an element to the queue, which is done at the end (tail) to maintain FIFO order.Step 2: Linked list enqueue behavior
In a linked list, adding at the tail means creating a new node and linking it as the last node.Final Answer:
Adds a new element at the end (tail) of the linked list -> Option AQuick Check:
Enqueue = Add at tail [OK]
- Confusing enqueue with dequeue operation
- Adding new element at head instead of tail
- Thinking enqueue removes elements
Solution
Step 1: Create new node with data
We create a new node object with the given data.Step 2: Link new node at tail and update tail pointer
Set current tail's next to new node, then update tail to new node.Final Answer:
new_node = Node(data); tail.next = new_node; tail = new_node -> Option BQuick Check:
New node linked at tail [OK]
- Linking new node to head instead of tail
- Not updating tail pointer after enqueue
- Setting new_node.next to tail (wrong direction)
class Node:
def __init__(self, data):
self.data = data
self.next = None
class Queue:
def __init__(self):
self.head = None
self.tail = None
def enqueue(self, data):
new_node = Node(data)
if not self.tail:
self.head = self.tail = new_node
else:
self.tail.next = new_node
self.tail = new_node
q = Queue()
q.enqueue(10)
q.enqueue(20)
q.enqueue(30)
current = q.head
result = []
while current:
result.append(current.data)
current = current.next
print(result)Solution
Step 1: Enqueue 10, 20, 30 in order
First enqueue sets head and tail to node with 10. Next enqueues add nodes at tail with 20 and 30.Step 2: Traverse from head to tail collecting data
Traversal collects 10, then 20, then 30 in order.Final Answer:
[10, 20, 30] -> Option DQuick Check:
Queue order = insertion order [OK]
- Assuming enqueue adds at head reversing order
- Not initializing head and tail properly
- Confusing output list order
def enqueue(self, data):
new_node = Node(data)
if self.head is None:
self.head = new_node
else:
self.tail.next = new_node
self.tail = new_nodeSolution
Step 1: Check initialization when queue is empty
When head is None, head is set to new_node but tail is not updated.Step 2: Tail must also point to new_node when queue is empty
Without updating tail, tail remains None causing errors on next enqueue.Final Answer:
Does not update tail when queue is empty -> Option CQuick Check:
Empty queue needs both head and tail set [OK]
- Updating only head or only tail on empty queue
- Forgetting to set tail.next on non-empty queue
- Assuming new_node.next needs manual None assignment
Solution
Step 1: Understand queue empty state
When queue is empty, both head and tail pointers are None.Step 2: Enqueue first element must update both pointers
To maintain O(1) enqueue and dequeue, head and tail must both point to the new node.Step 3: This ensures correct linking and prevents errors
Without setting both, dequeue or next enqueue operations may fail or cause errors.Final Answer:
Set both head and tail to the new node when queue is empty -> Option AQuick Check:
Empty queue enqueue sets head and tail [OK]
- Setting only tail or only head on empty enqueue
- Linking new node incorrectly to head or tail
- Not handling empty queue edge case
Ready to prove it?
Pass the test and this pattern moves unknown
