4. Stacks & Queues
CS331 - 2021 Spring
Motivation
- All the implementations of list data structures we have discussed have some
operations that have $O(n)$ worst-case runtime.
- Can we define more restricted data structures that has still useful applications where
- all operations are in $O(1)$?
Stack & Operations
- A stack is a list data structure where we can only insert new elements at the head (push) and remove elements from the head (pop).
push(v)
: prepend v
as a new element to the stack
pop()
: remove and return the current head of the list (called the top)
peek()
: return the current head of the list without removing it
Runtime Complexity
- Using a singly linked list, all stack operations are in $O(1)$.
- The same worst-case complexity can be achieved with array-lists if the top of the stack is the last element
Operation |
Array-list |
Linked List |
push |
$O(1)$ (amortized) |
$O(1)$ |
peek |
$O(1)$ |
$O(1)$ |
pop |
$O(1)$ |
$O(1)$ |
LIFO
- Stacks are often called last-in-first-out (LIFO) data structures
- The last element to be pushed to the stack is the first one to be popped
Example
s = [3,2,1]
s.push(4) = [4,3,2,1]
s.pop() = 4
s.pop() = 3
Example Applications
- maintaining a todo list in algorithms
- e.g., to replace recursion with iteration
- keeping track of function calls (call stack)
- backtracking
Queue & Operations
- A queue is list which allows insertion at the head (enqueue) and removal from the tail (dequeue).
enqueue(v)
: insert a new element v
at the beginning of the queue
dequeue
: remove the last element from the queue and return it
- Queues are called first-in-first-out (FIFO) data structures
Runtime Complexity Summary
- When a queue is implemented using a doubly linked circular list, then enqueue and dequeue have $O(1)$ worst-case runtime complexity.
Operation |
Doubly Linked List |
enqueue |
$O(1)$ |
dequeue |
$O(1)$ |
Example
q =[1,2,3]
q.enqueue(4) = [1,2,3,4]
q.dequeue() = 1
q.dequeue() = 2
Example Applications
- job scheduling (round robin)
- breadth-first search
- todo lists