 Open in App
Not now

# Design Front Middle Back Queue using STL

• Difficulty Level : Medium
• Last Updated : 04 Aug, 2021

Design a data structure that supports the following operations in queue efficiently:

• push__front(x): Insert an element at the front of the queue.
• push__middle(x): Inserts element at the middle of the queue.
• push__back(x): Inserts element at the back of the queue.
• pop__front() Removes the front element of the queue and returns it. If the queue is empty, returns -1.
• pop__middle(): Removes the middle element of the queue and returns it. If the queue is empty, returns -1.
• pop__back():Removes the back element of the queue and returns it. If the queue is empty, returns -1.

Examples:

Deque-based Approach: The problem can be solved using two deque. The idea is to use two deques. Operation at the back of the queue is to be done at the end of the second deque, and operation at the middle is to be done at the end of the first deque. Follow the steps below to solve the problem:

• If the size of the first deque is greater than the size of the second deque, then remove the end element of the first deque and add it to the front of the second deque.
• If the size of the second deque exceeds the size of the first deque by 1, then remove the front element of the second deque and push it at the end of the first deque.
• If the size of the first deque is greater than the second deque, then remove the back element from the first deque and insert it into the second deque.
• push__front(x): Insert an element x at the front of the first deque using push_front().
• push__back(x): Insert an element x at the end of the second deque using push_back()
• push__middle(x): Insert the element x at the end of the first deque using push_back().
• pop__front(): Remove the front element of the first deque if the size of deque is greater than 0 using pop_front().
• pop__back(): Remove the end element of the second deque if the size of deque greater than 0 using pop_back().
• pop__middle(): Remove the end element of the first deque if the size of deque greater than using pop_back().

Below is the implementation of the above approach:

## C++

 `// C++ program to implement` `// the above approach`   `#include ` `using` `namespace` `std;`   `// Create class Queue.` `class` `Queue {`   `    ``// Initialize two deques` `    ``deque<``int``> first, second;`   `    ``// Function to balance the size of` `    ``// first ans second deque` `    ``void` `equalizeSizedeque1deque2()` `    ``{`   `        ``// If size of less than second` `        ``if` `(first.size() <= second.size())` `            ``return``;`   `        ``// Insert the last element of` `        ``// first deque into second deque` `        ``second.push_front(first.back());`   `        ``// Pop the front element` `        ``// of the deque` `        ``first.pop_back();` `    ``}`   `    ``// Function to balance the size of` `    ``// second and first deque` `    ``void` `equalizeSizedeque2deque1()` `    ``{`   `        ``// if size of second deque deceed` `        ``// the first deque by 1` `        ``if` `(second.size() <= first.size() + 1)` `            ``return``;`   `        ``// Insert front element of second` `        ``// deque into the first` `        ``first.push_back(second.front());`   `        ``// Remove front element of` `        ``// second deque` `        ``second.pop_front();` `    ``}`   `public``:` `    ``// Function to insert element` `    ``// at front of queue` `    ``void` `push__front(``int` `val)` `    ``{`   `        ``// Insert val into first deque` `        ``first.push_front(val);`   `        ``// Balancing the size of second` `        ``equalizeSizedeque1deque2();` `    ``}`   `    ``// Function to insert val` `    ``// into the middle of queue` `    ``void` `push__middle(``int` `val)` `    ``{`   `        ``// Insert val into first deque` `        ``first.push_back(val);`   `        ``// Balancing the size of` `        ``// second deque` `        ``equalizeSizedeque1deque2();` `    ``}`   `    ``// Function to insert val` `    ``// into back of queue` `    ``void` `push__back(``int` `val)` `    ``{`   `        ``// Insert val into second deque` `        ``second.push_back(val);`   `        ``// Balancing the size of` `        ``// second deque` `        ``equalizeSizedeque2deque1();` `    ``}`   `    ``// Function to pop front` `    ``// element from queue` `    ``int` `pop__front()` `    ``{`   `        ``// If first deque and second` `        ``// deque is empty` `        ``if` `(first.empty() && second.empty())` `            ``return` `-1;`   `        ``int` `ans;`   `        ``// If the first deque` `        ``// is empty` `        ``if` `(first.empty()) {`   `            ``// Stores front element` `            ``// of second deque` `            ``ans = second.front();`   `            ``// Pop front element of` `            ``// second deque` `            ``second.pop_front();` `        ``}` `        ``else` `{`   `            ``// Stores front element` `            ``// of first deque` `            ``ans = first.front();`   `            ``// Pop front element of` `            ``// first deque` `            ``first.pop_front();`   `            ``// Balancing the size of first` `            ``equalizeSizedeque2deque1();` `        ``}` `        ``return` `ans;` `    ``}`   `    ``// Function to pop middle` `    ``// element of queue` `    ``int` `pop__middle()` `    ``{`   `        ``// If both deques are empty` `        ``if` `(first.empty() && second.empty())` `            ``return` `-1;`   `        ``// Stores mid element` `        ``// of queue` `        ``int` `ans;`   `        ``// If size of both deque is equal` `        ``if` `(first.size() == second.size()) {`   `            ``// Stores back element` `            ``// of first deque` `            ``ans = first.back();`   `            ``// Pop back element of` `            ``// first deque` `            ``first.pop_back();` `        ``}` `        ``else` `{`   `            ``// Stores front element` `            ``// of second deque` `            ``ans = second.front();`   `            ``// Pop front element` `            ``// from second deque` `            ``second.pop_front();` `        ``}` `        ``return` `ans;` `    ``}`   `    ``// Function to remove mid` `    ``// element from queue` `    ``int` `pop__back()` `    ``{`   `        ``// If both the deque are empty` `        ``if` `(first.empty() && second.empty())` `            ``return` `-1;`   `        ``// Stores back element from` `        ``// second deque` `        ``int` `ans = second.back();`   `        ``// Pop back element from` `        ``// second deque` `        ``second.pop_back();`   `        ``// Balancing the size of second` `        ``equalizeSizedeque1deque2();` `        ``return` `ans;` `    ``}` `};`   `// Driver code` `int` `main()` `{` `    ``Queue q;` `    ``q.push__front(1);` `    ``q.push__back(2);` `    ``q.push__middle(3);` `    ``cout << q.pop__middle() << ``" "``;` `    ``cout << q.pop__back() << ``" "``;` `    ``cout << q.pop__front() << ``" "``;` `    ``return` `0;` `}`

Output:

`3 2 1`

Time Complexity Analysis:

List-based Approach: Follow the steps below to solve the problem:

• push__front(x): Insert an element x at the front of the list using push_front().
• push__back(x): Insert an element x at the end of the second list using push_back()
• push__middle(x): Traverse the list using advance() and then insert the element at mid position of the list using insert()
• pop__front(): Remove the front element of the list if the size of list greater than 0 using pop_front(), otherwise return -1.
• pop__back(): Remove the last element of the list if the size of list greater than 0 using pop_back(), otherwise return -1.
• pop__middle(): If the size of the list greater than 0, then iterate to the middle element of the list using advance() and then erase the element at that position using erase(). Otherwise, return -1.

Below is the implementation of the above approach:

## C++

 `// C++ program to implement` `// the above approach`   `#include ` `using` `namespace` `std;`   `// Create structure of queue` `class` `Queue {`   `    ``list<``int``> l;`   `public``:` `    ``// Function to push element` `    ``// at front of the queue` `    ``void` `push__front(``int` `val)` `    ``{` `        ``l.push_front(val);` `    ``}`   `    ``// Function to push element` `    ``// at middle of the queue` `    ``void` `push__middle(``int` `val)` `    ``{`   `        ``auto` `itr = l.begin();`   `        ``// Traverse the list` `        ``advance(itr, l.size() / 2);`   `        ``// Insert element into` `        ``// middle of the list` `        ``l.insert(itr, val);` `    ``}`   `    ``// Function to insert element` `    ``// at the back of the queue` `    ``void` `push__back(``int` `val)` `    ``{` `        ``l.push_back(val);` `    ``}`   `    ``// Function to pop element from` `    ``// front of the queue` `    ``int` `pop__front()` `    ``{`   `        ``// Stores front element` `        ``// of queue` `        ``int` `val = -1;` `        ``if` `(l.size()) {` `            ``val = l.front();` `            ``l.pop_front();` `        ``}` `        ``return` `val;` `    ``}`   `    ``// Function to pop middle element` `    ``// of the queue` `    ``int` `pop__middle()` `    ``{` `        ``int` `val = -1;` `        ``if` `(l.size()) {` `            ``auto` `itr = l.begin();`   `            ``// Traverse the list` `            ``advance(itr, (l.size() - 1) / 2);` `            ``val = *itr;`   `            ``// Remove mid element` `            ``// from queue` `            ``l.erase(itr);` `        ``}` `        ``return` `val;` `    ``}`   `    ``// Function to pop end` `    ``// element of the queue` `    ``int` `pop__back()` `    ``{`   `        ``// Stores back element` `        ``// of the queue` `        ``int` `val = -1;`   `        ``if` `(l.size()) {` `            ``val = l.back();` `            ``l.pop_back();` `        ``}` `        ``return` `val;` `    ``}` `};`   `// Drivers code` `int` `main()` `{` `    ``Queue q;` `    ``q.push__front(1);` `    ``q.push__back(2);` `    ``q.push__middle(3);` `    ``cout << q.pop__middle() << ``" "``;` `    ``cout << q.pop__back() << ``" "``;` `    ``cout << q.pop__front() << ``" "``;` `    ``return` `0;` `}`

Output:

`3 2 1 `

Time Complexity Analysis:

Doubly linked list-based Approach: The problem can also be solved using a doubly-linked list without using STL by storing the address of the head and last node. Follow the steps below to solve the problem:

• push__front(x):
• Allocate space for storing the data value x and store the address in the current node pointer
• Increment the capacity by one
• push__back(x):
• Allocate space for storing the data value x and store the address in the current node pointer
• Insert the element x by linking the current node between the last node and last->previous node
• Increment the capacity by one
• push__middle(x):
• Allocate space for storing the data value x and store the address in the current node pointer
• Initialize a temp pointer of type node
• Reach the middle element of the doubly linked list by doing temp=temp->next half of current capacity times
• Now Insert the element x between temp and temp->next by relinking nodes
• Increment the capacity by one
• pop__front()
• If the capacity of size is less than 1 then return -1
• Decrement the capacity by one
• Return value of the deleted element
• pop__back():
• If the capacity is less than 1 then return -1
• Otherwise, delete the end node between the last and last->previous nodes by relinking nodes
• Decrement the capacity by one
• Return value of the deleted element
• pop__middle():
• Initialize a temp pointer of type node
• Reach the middle element of the doubly linked list by doing temp=temp->next half of current capacity times
• Now delete temp node between temp->previous and temp->next nodes by relinking nodes
• Decrement the capacity by one
• Return value of the deleted element

My Personal Notes arrow_drop_up
Related Articles