FIFO
LIFO
Data Structures
Stack
Queue

Implementing FIFO using LIFO

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

Implementing FIFO (First-In-First-Out) order using a LIFO (Last-In-First-Out) data structure can be an intriguing challenge in computer science. The FIFO approach is quintessential in scenarios like queue management, where the first person in line should be the first one served. On the other hand, LIFO is the principle behind stacks, where the most recently added item is the first to be removed.

Key Concepts

Before we delve into the implementation, it's essential to comprehend the differences between FIFO and LIFO data structures:

  • FIFO (Queue):
    • Insertion: Always happens at the rear.
    • Deletion: Always occurs from the front.
  • LIFO (Stack):
    • Insertion: Always occurs at the top (end).
    • Deletion: Always happens from the top (end).

Overview of the Implementation Strategy

To simulate FIFO behavior using only LIFO data structures (stacks), we need to intricately manage multiple stacks to mimic the queue operations.

The primary mechanism for this implementation involves using two stacks:

  • Stack A: For enqueue operations.
  • Stack B: For dequeue operations.

Operations

  1. Enqueue (Insert) Operation:
    • Push the incoming element onto Stack A.
    • The newly pushed element is always at the 'top', retaining the order of insertion in Stack A.
  2. Dequeue (Remove) Operation:
    • If Stack B is empty, pop all elements from Stack A and push onto Stack B. This reverses the order, such that the bottom-most element of Stack A (the oldest inserted) becomes the top of Stack B.
    • Pop from Stack B to achieve the appearance of dequeuing from a queue.

Example in Python

  • Enqueue Operation:
    • Time Complexity: O(1)O(1) since we are merely pushing onto Stack A.
  • Dequeue Operation:
    • Worst-case Time Complexity: O(n)O(n) when Stack B is empty and all elements need to be transferred from Stack A.
    • Amortized Complexity: O(1)O(1) on average since not all enqueue operations will require the transfer between stacks.
  • Space Complexity: Additional space is required for auxiliary stack, making it O(n)O(n).
  • Performance: While the average performance is efficient, the worst-case scenario during a heavy dequeue phase can be a bottleneck.
  • Applicability: This implementation is optimal in settings where the frequency of operations balances out over time.

Related reading
Course
Intermediate
27 lessons
15 hours
DSA Fundamentals

Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

All Rights Reserved.