Open in App
Not now

# Extracting last element of a Priority Queue without traversing

• Last Updated : 09 Feb, 2023

The Task is to extract the last element of the priority queue without traversing it.

Approach:

This problem can be solved using a Double-ended priority queue, a double-ended priority queue supports operations of both max heap (a max priority queue) and min heap (a min priority queue).

The operations are:

• getMax(): Returns maximum element.
• getMin(): Returns minimum element.
• deleteMax(): Deletes maximum element.
• deleteMin(): Deletes minimum element.
• size(): Returns count of elements.
• isEmpty(): Returns true if the queue is empty.

## Approach to Extract the last element of a priority queue without traversing:

We can use the following two data structures to implement the functionality.

We can try using a linked list. In the case of a linked list, if we maintain elements in sorted order, then the time complexity of all operations becomes O(1) except the operation insert() which takes O(n) time.

### Heaps:

We can try to use two heaps (min heap and max heap). The main idea is to maintain one-to-one correspondence, so that deleteMin() and deleteMax() can be done in O(log n) time. The heap-based solution requires O(n) extra space for an extra heap. The advantage of a heap-based solution is cache friendly.

• We maintain a pointer of every max heap element in the min heap.
• To get the minimum element, we simply return the root.
• To get the maximum element, we return the root of the max heap.
• To insert an element, we insert it in the min heap and max heap.

### Self-Balancing Binary Search Tree:

We will here implement a double-ended priority queue using a self-balancing binary search tree.  A self-balancing BST is implemented as set in C++ and TreeSet in Java. Follow the below steps to implement a priority queue where we can get the last element without traversing.

• Create a struct class named DblEndedPQ that holds all operations of a double-ended priority queue.
• Initialize a multiset st. [ We are using multiset because elements inserted inside multiset sort automatically like a priority queue, according to need.]
• Then, create mandatory operations like:
• size()
• isEmpty(),
• insert(),
• getMin()
• getMax()
• getMin()
• deleteMin()
• deleteMax()

Below is the Implementation of the above approach:

## C++

 `// C++ program to implement double-ended` `// priority queue using self balancing BST.`   `#include ` `using` `namespace` `std;`   `// Structure of double-ended priority queue` `struct` `DblEndedPQ {` `    ``multiset<``int``> st;`   `    ``// Returns size of the queue. Works in` `    ``// O(1) time` `    ``int` `size() { ``return` `st.size(); }`   `    ``// Returns true if queue is empty.` `    ``// Works in O(1) time` `    ``bool` `isEmpty() { ``return` `(st.size() == 0); }`   `    ``// Inserts an element.` `    ``// Works in O(log n) time` `    ``void` `insert(``int` `x) { st.insert(x); }`   `    ``// Returns minimum element.` `    ``// Works in O(1) time` `    ``int` `getMin() { ``return` `*(st.begin()); }`   `    ``// Returns maximum element.` `    ``// Works in O(1) time` `    ``int` `getMax() { ``return` `*(st.rbegin()); }`   `    ``// Deletes the minimum element.` `    ``// Works in O(log n) time` `    ``void` `deleteMin()` `    ``{` `        ``if` `(st.size() == 0)` `            ``return``;`   `        ``auto` `it = st.begin();` `        ``st.erase(it);` `    ``}`   `    ``// Deletes the maximum element.` `    ``// Works in O(log n) time` `    ``void` `deleteMax()` `    ``{` `        ``if` `(st.size() == 0)` `            ``return``;`   `        ``auto` `it = st.end();` `        ``it--;` `        ``st.erase(it);` `    ``}` `};`   `// Driver code` `int` `main()` `{` `    ``DblEndedPQ d;`   `    ``d.insert(10);` `    ``d.insert(20);` `    ``d.insert(40);` `    ``d.insert(30);`   `    ``cout << ``"Minimum Element is: "` `<< d.getMin() << endl;` `    ``cout << ``"Maximum Element is: "` `<< d.getMax() << endl;`   `    ``d.deleteMin();` `    ``cout << ``"Minimum Element is: "` `<< d.getMin() << endl;`   `    ``d.deleteMax();` `    ``cout << ``"Maximum Element is: "` `<< d.getMax() << endl;`   `    ``cout << ``"Size of DblEndedPQ is: "` `<< d.size() << endl;`   `    ``cout << ``"Is DblEndedPQ empty: "` `         ``<< (d.isEmpty() ? ``"YES"` `: ``"NO"``) << endl;`   `    ``return` `0;` `}`

## Java

 `import` `java.util.Set;` `import` `java.util.TreeSet;`   `public` `class` `DblEndedPQ {` `    ``Set st;`   `    ``DblEndedPQ() {` `        ``st = ``new` `TreeSet<>();` `    ``}`   `    ``int` `size() {` `        ``return` `st.size();` `    ``}`   `    ``boolean` `isEmpty() {` `        ``return` `(st.size() == ``0``);` `    ``}`   `    ``void` `insert(``int` `x) {` `        ``st.add(x);` `    ``}`   `    ``int` `getMin() {` `        ``if` `(st.isEmpty()) {` `            ``return` `Integer.MIN_VALUE;` `        ``}` `        ``return` `st.iterator().next();` `    ``}`   `    ``int` `getMax() {` `        ``if` `(st.isEmpty()) {` `            ``return` `Integer.MIN_VALUE;` `        ``}` `        ``return` `((TreeSet) st).last();` `    ``}`   `    ``void` `deleteMin() {` `        ``if` `(st.size() == ``0``)` `            ``return``;`   `        ``st.remove(getMin());` `    ``}`   `    ``void` `deleteMax() {` `        ``if` `(st.size() == ``0``)` `            ``return``;`   `        ``st.remove(getMax());` `    ``}`   `    ``public` `static` `void` `main(String[] args) {` `        ``DblEndedPQ d = ``new` `DblEndedPQ();`   `        ``d.insert(``10``);` `        ``d.insert(``20``);` `        ``d.insert(``40``);` `        ``d.insert(``30``);`   `        ``System.out.println(``"Minimum Element is: "` `+ d.getMin());` `        ``System.out.println(``"Maximum Element is: "` `+ d.getMax());`   `        ``d.deleteMin();` `        ``System.out.println(``"Minimum Element is: "` `+ d.getMin());`   `        ``d.deleteMax();` `        ``System.out.println(``"Maximum Element is: "` `+ d.getMax());`   `        ``System.out.println(``"Size of DblEndedPQ is: "` `+ d.size());`   `        ``System.out.println(``"Is DblEndedPQ empty: "` `                ``+ (d.isEmpty() ? ``"YES"` `: ``"NO"``));` `    ``}` `}`

## Python3

 `import` `bisect`   `class` `DblEndedPQ:` `    ``def` `__init__(``self``):` `        ``self``.st ``=` `[]` `        `  `    ``def` `size(``self``):` `        ``return` `len``(``self``.st)` `    `  `    ``def` `isEmpty(``self``):` `        ``return` `self``.size() ``=``=` `0` `    `  `    ``def` `insert(``self``, x):` `        ``bisect.insort(``self``.st, x)` `    `  `    ``def` `getMin(``self``):` `        ``return` `self``.st[``0``]` `    `  `    ``def` `getMax(``self``):` `        ``return` `self``.st[``-``1``]` `    `  `    ``def` `deleteMin(``self``):` `        ``if` `self``.isEmpty():` `            ``return` `        ``self``.st.pop(``0``)` `    `  `    ``def` `deleteMax(``self``):` `        ``if` `self``.isEmpty():` `            ``return` `        ``self``.st.pop()` `        `    `# Driver code` `d ``=` `DblEndedPQ()`   `d.insert(``10``)` `d.insert(``20``)` `d.insert(``40``)` `d.insert(``30``)`   `print``(``"Minimum Element is: "``, d.getMin())` `print``(``"Maximum Element is: "``, d.getMax())`   `d.deleteMin()` `print``(``"Minimum Element is: "``, d.getMin())`   `d.deleteMax()` `print``(``"Maximum Element is: "``, d.getMax())`   `print``(``"Size of DblEndedPQ is: "``, d.size())`   `print``(``"Is DblEndedPQ empty: "``, ``"YES"` `if` `d.isEmpty() ``else` `"NO"``)`

## C#

 `using` `System;` `using` `System.Collections.Generic;`   `// Class to implement double-ended priority queue using SortedSet` `class` `DblEndedPQ` `{` `    ``// SortedSet to store elements in the queue` `    ``SortedSet<``int``> st = ``new` `SortedSet<``int``>();`   `    ``// Method to return the size of the queue` `    ``public` `int` `Size()` `    ``{` `        ``return` `st.Count;` `    ``}`   `    ``// Method to check if the queue is empty` `    ``public` `bool` `IsEmpty()` `    ``{` `        ``return` `st.Count == 0;` `    ``}`   `    ``// Method to insert an element into the queue` `    ``public` `void` `Insert(``int` `x)` `    ``{` `        ``st.Add(x);` `    ``}`   `    ``// Method to return the minimum element in the queue` `    ``public` `int` `GetMin()` `    ``{` `        ``return` `st.Min;` `    ``}`   `    ``// Method to return the maximum element in the queue` `    ``public` `int` `GetMax()` `    ``{` `        ``return` `st.Max;` `    ``}`   `    ``// Method to delete the minimum element in the queue` `    ``public` `void` `DeleteMin()` `    ``{` `        ``if` `(st.Count == 0)` `            ``return``;`   `        ``st.Remove(st.Min);` `    ``}`   `    ``// Method to delete the maximum element in the queue` `    ``public` `void` `DeleteMax()` `    ``{` `        ``if` `(st.Count == 0)` `            ``return``;`   `        ``st.Remove(st.Max);` `    ``}` `}`   `class` `Program` `{` `    ``static` `void` `Main(``string``[] args)` `    ``{` `        ``DblEndedPQ d = ``new` `DblEndedPQ();`   `        ``// Inserting elements into the queue` `        ``d.Insert(10);` `        ``d.Insert(20);` `        ``d.Insert(40);` `        ``d.Insert(30);`   `        ``// Printing minimum and maximum elements` `        ``Console.WriteLine(``"Minimum Element is: "` `+ d.GetMin());` `        ``Console.WriteLine(``"Maximum Element is: "` `+ d.GetMax());`   `        ``// Deleting the minimum element` `        ``d.DeleteMin();` `        ``Console.WriteLine(``"Minimum Element is: "` `+ d.GetMin());`   `        ``// Deleting the maximum element` `        ``d.DeleteMax();` `        ``Console.WriteLine(``"Maximum Element is: "` `+ d.GetMax());`   `        ``// Printing the size of the queue` `        ``Console.WriteLine(``"Size of DblEndedPQ is: "` `+ d.Size());`   `        ``// Printing if the queue is empty or not` `        ``Console.WriteLine(``"Is DblEndedPQ empty: "` `+ (d.IsEmpty() ? ``"YES"` `: ``"NO"``));` `    ``}` `}`

## Javascript

 `class DblEndedPQ {` `  ``constructor() {` `    ``this``.st = ``new` `Set();` `  ``}`   `  ``size() {` `    ``return` `this``.st.size;` `  ``}`   `  ``isEmpty() {` `    ``return` `this``.st.size === 0;` `  ``}`   `  ``insert(x) {` `    ``this``.st.add(x);` `  ``}`   `  ``getMin() {` `    ``return` `Math.min(...``this``.st);` `  ``}`   `  ``getMax() {` `    ``return` `Math.max(...``this``.st);` `  ``}`   `  ``deleteMin() {` `    ``if` `(``this``.st.size === 0) ``return``;` `    ``this``.st.``delete``(Math.min(...``this``.st));` `  ``}`   `  ``deleteMax() {` `    ``if` `(``this``.st.size === 0) ``return``;` `    ``this``.st.``delete``(Math.max(...``this``.st));` `  ``}` `}`   `const d = ``new` `DblEndedPQ();`   `d.insert(10);` `d.insert(20);` `d.insert(40);` `d.insert(30);`   `console.log(``"Minimum Element is: "` `+ d.getMin());` `console.log(``"Maximum Element is: "` `+ d.getMax());`   `d.deleteMin();` `console.log(``"Minimum Element is: "` `+ d.getMin());`   `d.deleteMax();` `console.log(``"Maximum Element is: "` `+ d.getMax());`   `console.log(``"Size of DblEndedPQ is: "` `+ d.size());`   `console.log(``"Is DblEndedPQ empty: "` `+ (d.isEmpty() ? ``"YES"` `: ``"NO"``));`

Output

```Minimum Element is: 10
Maximum Element is: 40
Minimum Element is: 20
Maximum Element is: 30
Size of DblEndedPQ is: 2
Is DblEndedPQ empty: NO```

Time Complexity:

• getMax() : O(1)
• getMin() : O(1)
• deleteMax() : O(Log n)
• deleteMin() : O(Log n)
• size() : O(1)
• isEmpty() : O(1)

Auxiliary Space: O(N)

Related Articles:

My Personal Notes arrow_drop_up
Related Articles