Home | Projects | Notes > Data Structures & Algorithms > Queues
A queue is a linear data structure that follows the First In, First Out (FIFO) principle. Elements are added at the back (enqueue) and removed from the front (dequeue). It is commonly used in scheduling, buffering, and breadth-first traversal scenarios.

Simple FIFO Logic: Maintains processing order, ideal for task scheduling and buffering.
Efficient Operations: O(1) time for enqueue and dequeue (with a linked list or circular buffer).
Flexible Implementations: Can be implemented using arrays, linked lists, or circular buffers.
Dynamic Size (Linked List): Grows as needed without reallocation.
Limited Access: Only the front and rear elements can be accessed — no random access or indexed lookup.
Fixed Capacity (Array-Based): Unless dynamically resized, array-based queues have limited space.
Inefficient Deletion/Search: Not suitable for arbitrary removal or searching through the queue.
Better: When processing order must be preserved (e.g., printers, CPU scheduling).
Worse: When backtracking or nested operations are needed (stack excels there).
queue.hpp)32123
4class node5{6public:7 node(int val) : data(val), p_next(nullptr) {}8
9 int data;10 node *p_next;11};12
13class queue14{15public:16 queue();17 ~queue();18 void push(const int val); // enqueue19 void pop(); // dequeue20 int front() const;21 int back() const;22 bool empty() const;23 int size() const;24 void clear();25
26private:27 node *p_front;28 node *p_back;29 int cnt;30};31
32queue.cpp)96123
4queue::queue()5 : p_front(nullptr), p_back(nullptr), cnt(0)6{7 // do nothing8}9
10queue::~queue()11{12 while (!empty())13 {14 pop();15 }16}17
18void queue::push(const int val)19{20 node *p_new = new node(val);21
22 if (empty())23 {24 p_front = p_back = p_new;25 }26 else27 {28 p_back->p_next = p_new;29 p_back = p_new;30 }31
32 ++cnt;33}34
35void queue::pop()36{37 if (empty())38 {39 throw std::runtime_error("Queue underflow");40 }41
42 node *p_del = p_front;43 p_front = p_front->p_next;44 delete p_del;45
46 if (nullptr == p_front)47 {48 p_back = nullptr;49 }50
51 --cnt;52}53
54int queue::front() const55{56 if (empty())57 {58 throw std::runtime_error("Queue is empty");59 }60
61 return p_front->data;62}63
64int queue::back() const65{66 if (empty())67 {68 throw std::runtime_error("Queue is empty");69 }70
71 return p_back->data;72}73
74bool queue::empty() const75{76 return 0 == cnt; // return nullptr == p_front;77}78
79int queue::size() const80{81 return cnt;82}83
84void queue::clear()85{86 while (p_front)87 {88 node *p_del = p_front;89 p_front = p_front->p_next;90 delete p_del;91
92 // or simply just call 'pop()' in this while loop93 }94
95 cnt = 0;96}25123
4int main(int argc, char *argv[])5{6 queue q;7
8 q.push(1);9 q.push(2);10 q.push(3);11 q.push(4);12 q.push(5); // 1 -> 2 -> 3 -> 4 -> 513
14 std::cout << q.front() << std::endl; // 115 std::cout << q.back() << std::endl; // 516 17 q.pop();18 std::cout << q.size() << std::endl; // 419 std::cout << q.empty() << std::endl; // 020
21 q.clear();22 std::cout << q.size() << std::endl; // 023
24 return 0;25}51125344050