DSA

Stack & Queue

brian | Published: March 13, 2024, 1:49 p.m. | Updated: May 25, 2025, 7:47 p.m.

Profile Picture


What is Stack?
A stack is a linear data structure in which the insertion of a new element and removal of an existing element takes place at the same end represented as the top of the stack.


To implement the stack, it is required to maintain the pointer to the top of the stack, which is the last element to be inserted because we can access the elements only on the top of the stack.

LIFO( Last In First Out ):

This strategy states that the element that is inserted last will come out first. You can take a pile of plates kept on top of each other as a real-life example. The plate which we put last is on the top, and when we remove the plate that is at the top, we can say that the plate that was put last comes out first. (LIFO)

Basic Operations on Stack
In order to make manipulations in a stack, there are certain operations provided to us.

push() to insert an element into the stack
pop() to remove an element from the stack
peek() Returns the top element of the stack.
isEmpty() returns true if stack is empty else false.
size() returns the size of stack.

 

*** You can implement stacks in python using collections.deque which is better than the built in list from python
**The deque data structure from the collections module is designed specifically to implement queues efficiently. 

 

The two main operations associated with a stack are:

1. Push: This operation is used to add an element to the top of the stack.
2. Pop: This operation is used to remove and retrieve the element from the top of the stack.

Additional operations that are often supported by stacks include:

3. Peek (or Top): This operation is used to retrieve the element at the top of the stack without removing it.
4. Is Empty: This operation checks whether the stack is empty or not.
5. Size: This operation returns the number of elements in the stack.

 


Push/Pop element O(1)
Search  element by value O(n)


Use cases for stacks:
    *browsers navitgation back and forward
    *Undo (ctrl+z) functionality in any editor uses stack to track down last set of operations

 


deque some methods

append(x)¶
Add x to the right side of the deque.

appendleft(x)
Add x to the left side of the deque.

clear()
Remove all elements from the deque leaving it with length 0.

copy()
Create a shallow copy of the deque.


pop()
Remove and return an element from the right side of the deque. If no elements are present, raises an IndexError.

popleft()
Remove and return an element from the left side of the deque. If no elements are present, raises an IndexError.

remove(value)
Remove the first occurrence of value. If not found, raises a ValueError.

reverse()
Reverse the elements of the deque in-place and then return None.

 

My implementation using Python



from collections import deque



class Stack:

    def __init__(self):
        self.container = deque()
    
    def push(self, val):
        self.container.append(val)

    def pop(self):
        return self.container.pop()
    
    def peek(self):
        return self.container[-1]
    
    def is_empty(self):
        return len(self.container) == 0
    
    def size(self):
        return len(self.container)
    


stack = Stack()
print(stack.container)
print(stack.is_empty())
print(stack.size())
for x in range(5):
    stack.push(x)
print(stack.container)

stack.pop()
print(stack.container)

print(stack.peek())
print(stack.size())



---output---
deque([])
True
0
deque([0, 1, 2, 3, 4])
deque([0, 1, 2, 3])
3
4

 

 

 

Queue: Operations are performed FIFO (first in, first out), which means that the first element added will be the first one removed. A queue can be implemented using an array, However in Python it's generally recommended to use the deque from the collections module. 
The deque provides efficient methods for both enqueue(insert) and dequeue(del/pop) operations, making it well-suited for implementing 
queues and offering better performance than using lists, especially for large queues.

*think of queue as waiting in a Line, first come first served
Python: ways to implement
    *list
    *collections.deque
    *queue.LifoQueue

from collections import deque


q = deque()

q.appendleft(1)
q.appendleft(2)
q.appendleft(3)

#1 print all values
print(q)

print('-' * 15)

#2 print the popped value which is the first value we added, 
#should return 1, also removes it
print('Popped: ' , q.pop())

print('-' * 15)

#3 prints all values again
print(q)



-----output------
deque([3, 2, 1])
---------------
Popped:  1     
---------------
deque([3, 2])