Overview
Understanding how to build basic data structures from scratch is crucial for understanding how memory works and how algorithms operate. This chapter implements two fundamental data structures in Go:- Stack (Last-In-First-Out)
- Queue (First-In-First-Out)
Stack (LIFO)
A Stack is a Last-In-First-Out (LIFO) data structure. Think of it like a stack of plates:- You add plates to the top (Push)
- You remove plates from the top (Pop)
- You can only access the top plate
Visual Representation
Stack Implementation
stack/main.go
The
top field tracks the index of the top element. When top == -1, the stack is empty.Push Operation
Adds an element to the top of the stack.stack/main.go
Pop Operation
Removes and returns the top element.stack/main.go
Why return
bool? Go doesn’t have exceptions. Returning a boolean allows the caller to check if the operation succeeded.Stack Usage Example
stack/main.go
Stack Operations Complexity
| Operation | Time Complexity | Space Complexity |
|---|---|---|
| Push | O(1) | O(1) |
| Pop | O(1) | O(1) |
| Peek/Top | O(1) | O(1) |
| IsEmpty | O(1) | O(1) |
Queue (FIFO)
A Queue is a First-In-First-Out (FIFO) data structure. Think of it like a line at a ticket counter:- People join at the rear (Enqueue)
- People leave from the front (Dequeue)
- First person in line is served first
Visual Representation
Queue Implementation
queue/main.go
Both
front and rear start at -1 to indicate an empty queue.Enqueue Operation
Adds an element to the rear of the queue.queue/main.go
Dequeue Operation
Removes and returns the front element.queue/main.go
Queue Usage Example
queue/main.go
Queue Operations Complexity
| Operation | Time Complexity | Space Complexity |
|---|---|---|
| Enqueue | O(1) | O(1) |
| Dequeue | O(1) | O(1) |
| Peek/Front | O(1) | O(1) |
| IsEmpty | O(1) | O(1) |
Linear Queue vs Circular Queue
The Problem with Linear Queues
Even though positions 0 and 1 are empty, we cannot insert becauserear has reached the end!
Solution: Circular Queue
A Circular Queue wraps around using modulo arithmetic:Using
% q.size makes the queue “wrap around” to position 0 when it reaches the end.Stack vs Queue Comparison
| Feature | Stack | Queue |
|---|---|---|
| Order | LIFO (Last-In-First-Out) | FIFO (First-In-First-Out) |
| Insertion | Push (top) | Enqueue (rear) |
| Removal | Pop (top) | Dequeue (front) |
| Access | Top only | Front only |
| Use Cases | Function calls, undo/redo, expression evaluation | Task scheduling, BFS, print queue |
Real-World Use Cases
Stack Applications
Queue Applications
Memory Representation
Stack Memory Layout
Queue Memory Layout
Running the Examples
Best Practices
Improvements and Extensions
Generic Stack Example
Next Steps
- Implement a Circular Queue to solve the linear queue limitation
- Build a Priority Queue using a heap
- Explore Go’s built-in container/list and container/heap packages
- Study more complex structures like Trees and Graphs