Stack Implementation Using Linked List in DSA C# - Time & Space Complexity
We want to understand how fast the main operations of a stack work when it is built using a linked list.
Specifically, we ask: how does the time to add or remove items grow as the stack gets bigger?
Analyze the time complexity of the following code snippet.
public class Node {
public int Data;
public Node Next;
public Node(int data) { Data = data; Next = null; }
}
public class Stack {
private Node top;
public void Push(int data) {
Node newNode = new Node(data);
newNode.Next = top;
top = newNode;
}
public int Pop() {
if (top == null) throw new InvalidOperationException("Stack is empty");
int value = top.Data;
top = top.Next;
return value;
}
}
This code adds (Push) and removes (Pop) items at the top of a linked list to behave like a stack.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Adding or removing one node at the top of the linked list.
- How many times: Each Push or Pop does this once, no loops or recursion inside these methods.
Each Push or Pop does a fixed number of steps regardless of how many items are in the stack.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | 5 steps (create node, link, update top) |
| 100 | 5 steps (same fixed steps) |
| 1000 | 5 steps (still the same fixed steps) |
Pattern observation: The number of steps stays the same no matter how big the stack is.
Time Complexity: O(1)
This means adding or removing an item takes the same short time no matter how many items are in the stack.
[X] Wrong: "Since the stack can grow, Push or Pop must take longer as it gets bigger."
[OK] Correct: Each operation only changes the top node, so it does not need to look through the whole stack.
Knowing that stack operations are fast and constant time helps you explain why stacks are useful in many programs and algorithms.
"What if we changed the stack to add items at the bottom instead of the top? How would the time complexity change?"
Practice
Solution
Step 1: Understand stack size limitation in arrays
Arrays have a fixed size, so stacks implemented with arrays have a maximum capacity.Step 2: Linked list dynamic size
Linked lists can grow or shrink dynamically by adding or removing nodes, so the stack size is limited only by memory.Final Answer:
The stack can grow dynamically without a fixed size limit -> Option BQuick Check:
Linked list stacks grow dynamically [OK]
- Thinking linked list uses less memory always
- Assuming linked list allows random access
- Confusing stack sorting with implementation
Solution
Step 1: Understand push operation in linked list stack
Push adds a new node at the beginning (top) of the linked list.Step 2: Correct pointer update
The new node's next points to the current top, then top is updated to new node.Final Answer:
Create a new node, set its next to current top, then update top to new node -> Option AQuick Check:
Push adds node at front [OK]
- Using previous pointer instead of next
- Adding node at end instead of front
- Overwriting top node value instead of adding new node
StackNode top = null; // Push 10 StackNode node1 = new StackNode(10); node1.next = top; top = node1; // Push 20 StackNode node2 = new StackNode(20); node2.next = top; top = node2; // Pop int popped = top.data; top = top.next; // Print top data Console.WriteLine(top.data);
Solution
Step 1: Trace push operations
Push 10: top points to node with data 10.
Push 20: top points to node with data 20, next points to node 10.Step 2: Trace pop operation
Pop removes top node (20), top updated to next node (10).Step 3: Print top data
Top now points to node with data 10, so output is 10.Final Answer:
10 -> Option CQuick Check:
After pop, top data = 10 [OK]
- Printing popped value instead of new top
- Confusing push order
- Not updating top after pop
public int Pop() {
if (top == null) {
Console.WriteLine("Stack Underflow");
}
int value = top.data;
top = top.next;
return value;
}Solution
Step 1: Check behavior when stack is empty
If top is null, method prints message but continues to access top.data causing error or returns no value.Step 2: Missing return for empty stack case
Method should return or throw exception when stack is empty to avoid runtime error.Final Answer:
It does not return a value when stack is empty -> Option AQuick Check:
Empty stack must return or throw [OK]
- Ignoring empty stack case
- Confusing overflow with underflow
- Not updating top pointer
ReverseStack that reverses the elements of a stack implemented using a linked list without using extra data structures. Which approach is correct?Solution
Step 1: Understand constraints
No extra data structures allowed, so using recursion (call stack) is allowed but no explicit new lists or queues.Step 2: Recursion approach
Recursively pop all elements, then insert them back at bottom to reverse order without extra storage.Step 3: Other options use extra structures
Swapping data or using new lists or queues violates constraints or is incorrect for stack reversal.Final Answer:
Use recursion to pop all elements, then push them back in reverse order -> Option DQuick Check:
Recursion reverses stack without extra structures [OK]
- Using extra linked lists or queues
- Trying to swap node data incorrectly
- Ignoring no extra structure constraint
Ready to prove it?
Pass the test and this pattern moves unknown
