Enqueue Using Linked List in DSA Go - 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 grow when we add more items?
Analyze the time complexity of the following code snippet.
// Node structure
type Node struct {
value int
next *Node
}
// Queue with front and rear
type Queue struct {
front *Node
rear *Node
}
// Enqueue adds a new node at the rear
func (q *Queue) Enqueue(val int) {
newNode := &Node{value: val}
if q.rear == nil {
q.front = newNode
q.rear = newNode
return
}
q.rear.next = newNode
q.rear = newNode
}
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 at the rear.
- How many times: This happens once per enqueue call, no loops or recursion inside.
Each enqueue adds one node by changing a few pointers, no matter how big the queue is.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 1 pointer update |
| 100 | About 1 pointer update |
| 1000 | About 1 pointer update |
Pattern observation: The work stays the same no matter how many items are in the queue.
Time Complexity: O(1)
This means adding an item takes the same small amount of time no matter how big the queue is.
[X] Wrong: "Enqueue takes longer as the queue grows because we have to find the end each time."
[OK] Correct: We keep a pointer to the rear node, so we add directly without searching, keeping time constant.
Knowing that enqueue on a linked list queue is constant time shows you understand efficient data structure design, a key skill in coding interviews.
"What if we did not keep a rear pointer and only had a front pointer? How would the time complexity of enqueue change?"
Practice
enqueue operation do in a queue implemented using a linked list?Solution
Step 1: Understand enqueue operation
Enqueue means adding an element to the queue.Step 2: Enqueue in linked list context
In a linked list queue, enqueue adds the new node at the end (tail).Final Answer:
Adds a new element at the end of the linked list -> Option BQuick Check:
Enqueue = Add at end [OK]
- Confusing enqueue with dequeue operation
- Adding element at the head instead of tail
- Thinking enqueue removes elements
- Assuming enqueue checks emptiness
Solution
Step 1: Create new node correctly
Use pointer to Node with data and next set to nil.Step 2: Link new node at tail and update tail
Set current tail's next to new node, then update tail pointer.Final Answer:
node := &Node{data: value, next: nil} queue.tail.next = node queue.tail = node -> Option AQuick Check:
New node pointer + update tail = A [OK]
- Not using pointer for new node
- Assigning new node to head instead of tail
- Forgetting to update tail pointer
- Incorrect struct initialization syntax
type Node struct {
data int
next *Node
}
type Queue struct {
head *Node
tail *Node
}
func (q *Queue) enqueue(value int) {
node := &Node{data: value}
if q.tail == nil {
q.head = node
q.tail = node
} else {
q.tail.next = node
q.tail = node
}
}
func main() {
q := &Queue{}
q.enqueue(10)
q.enqueue(20)
q.enqueue(30)
// Print queue
current := q.head
for current != nil {
fmt.Print(current.data, " -> ")
current = current.next
}
fmt.Print("null")
}Solution
Step 1: Enqueue elements in order
Elements 10, 20, 30 are added at the tail one by one.Step 2: Traverse from head to tail
Traversal prints nodes in order: 10, then 20, then 30, then null.Final Answer:
10 -> 20 -> 30 -> null -> Option DQuick Check:
Enqueue order preserved in linked list [OK]
- Assuming new elements added at head
- Printing tail to head order
- Forgetting to print 'null' at end
- Confusing enqueue with dequeue output
func (q *Queue) enqueue(value int) {
node := &Node{data: value}
if q.head == nil {
q.head = node
} else {
q.tail.next = node
}
}Solution
Step 1: Analyze enqueue logic
Function sets head if empty, else links new node after tail.Step 2: Check tail pointer update
Function does not update q.tail to new node, so tail remains old node.Final Answer:
Missing update of q.tail to new node after adding -> Option AQuick Check:
Update tail pointer after enqueue [OK]
- Not updating tail pointer after enqueue
- Checking wrong pointer for empty queue
- Creating node without pointer
- Linking new node to head instead of tail
Solution
Step 1: Understand enqueue time complexity
Without tail pointer, enqueue requires traversal to last node, O(n).Step 2: Using tail pointer
Maintaining tail pointer allows direct access to last node, making enqueue O(1).Final Answer:
Maintain a tail pointer to the last node and update it on enqueue -> Option CQuick Check:
Tail pointer reduces enqueue to O(1) [OK]
- Thinking doubly linked list alone improves enqueue
- Adding at head breaks queue order
- Traversing list each time causes O(n) complexity
- Ignoring tail pointer update
Ready to prove it?
Pass the test and this pattern moves unknown
