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.
Linked Lists:
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++
#include <bits/stdc++.h>
using namespace std;
struct DblEndedPQ {
multiset< int > st;
int size() { return st.size(); }
bool isEmpty() { return (st.size() == 0); }
void insert( int x) { st.insert(x); }
int getMin() { return *(st.begin()); }
int getMax() { return *(st.rbegin()); }
void deleteMin()
{
if (st.size() == 0)
return ;
auto it = st.begin();
st.erase(it);
}
void deleteMax()
{
if (st.size() == 0)
return ;
auto it = st.end();
it--;
st.erase(it);
}
};
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<Integer> 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<Integer>) 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()
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 DblEndedPQ
{
SortedSet< int > st = new SortedSet< int >();
public int Size()
{
return st.Count;
}
public bool IsEmpty()
{
return st.Count == 0;
}
public void Insert( int x)
{
st.Add(x);
}
public int GetMin()
{
return st.Min;
}
public int GetMax()
{
return st.Max;
}
public void DeleteMin()
{
if (st.Count == 0)
return ;
st.Remove(st.Min);
}
public void DeleteMax()
{
if (st.Count == 0)
return ;
st.Remove(st.Max);
}
}
class Program
{
static void Main( string [] args)
{
DblEndedPQ d = new DblEndedPQ();
d.Insert(10);
d.Insert(20);
d.Insert(40);
d.Insert(30);
Console.WriteLine( "Minimum Element is: " + d.GetMin());
Console.WriteLine( "Maximum Element is: " + d.GetMax());
d.DeleteMin();
Console.WriteLine( "Minimum Element is: " + d.GetMin());
d.DeleteMax();
Console.WriteLine( "Maximum Element is: " + d.GetMax());
Console.WriteLine( "Size of DblEndedPQ is: " + d.Size());
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:
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...