Stacks and queues are abstract data types that restrict how elements are added and removed. They model real-world waiting lines and last-in-first-out behavior.
A stack is like a stack of plates: you add to the top and remove from the top. The last item placed is the first one retrieved.
push(item) — adds an item to the toppop() — removes and returns the top itempeek() — returns the top item without removing itis_empty() — checks if the stack is emptyclass Stack:
def __init__(self):
self.items = []
def push(self, item):
self.items.append(item)
def pop(self):
if self.is_empty():
return None
return self.items.pop()
def peek(self):
if self.is_empty():
return None
return self.items[-1]
def is_empty(self):
return len(self.items) == 0
class StackNode:
def __init__(self, data):
self.data = data
self.next = None
class LinkedListStack:
def __init__(self):
self.top = None
def push(self, data):
node = StackNode(data)
node.next = self.top
self.top = node
def pop(self):
if self.top is None:
return None
data = self.top.data
self.top = self.top.next
return data
def peek(self):
return self.top.data if self.top else None
def is_empty(self):
return self.top is None
A queue is like a line at a ticket counter: the first person in line is the first one served.
enqueue(item) — adds an item to the reardequeue() — removes and returns the front itemfront() — returns the front item without removing itis_empty() — checks if the queue is emptyclass Queue:
def __init__(self):
self.items = []
def enqueue(self, item):
self.items.append(item)
def dequeue(self):
if self.is_empty():
return None
return self.items.pop(0)
def front(self):
return self.items[0] if not self.is_empty() else None
def is_empty(self):
return len(self.items) == 0
A circular queue reuses array slots by wrapping around. It uses a fixed-size array with front and rear pointers.
class CircularQueue:
def __init__(self, capacity):
self.capacity = capacity
self.items = [None] * capacity
self.front = 0
self.rear = 0
self.size = 0
def enqueue(self, item):
if self.size == self.capacity:
return False
self.items[self.rear] = item
self.rear = (self.rear + 1) % self.capacity
self.size += 1
return True
def dequeue(self):
if self.size == 0:
return None
item = self.items[self.front]
self.front = (self.front + 1) % self.capacity
self.size -= 1
return item
Allows insertion and deletion from both ends. Python's collections.deque is a highly optimized implementation.
Elements are dequeued in order of priority, not insertion order. Typically implemented with a binary heap. Operations: O(log n) for insertion and deletion.
"({[]})" is balanced but "({[})" is not.