GFG App
Open App
Browser
Continue

# 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 following operations are expected from double ended priority queue.

1. getMax() : Returns maximum element.
2. getMin() : Returns minimum element.
3. deleteMax() : Deletes maximum element.
4. deleteMin() : Deletes minimum element.
5. size() : Returns count of elements.
6. isEmpty() : Returns true if the queue is empty.

We can try different data structure like Linked List. In case of linked list, if we maintain elements in sorted order, then time complexity of all operations become O(1) except the operation insert() which takes O(n) time.

We can try two heaps (min heap and max heap). We maintain a pointer of every max heap element in min heap. To get minimum element, we simply return root. To get maximum element, we return root of max heap. To insert an element, we insert in min heap and max heap both. The main idea is to maintain one to one correspondence, so that deleteMin() and deleteMax() can be done in O(Log n) time.

1. getMax() : O(1)
2. getMin() : O(1)
3. deleteMax() : O(Log n)
4. deleteMin() : O(Log n)
5. size() : O(1)
6. isEmpty() : O(1)

Another solution is to use self balancing binary search tree. A self balancing BST is implemented as set in C++ and TreeSet in Java.

1. getMax() : O(1)
2. getMin() : O(1)
3. deleteMax() : O(Log n)
4. deleteMin() : O(Log n)
5. size() : O(1)
6. isEmpty() : O(1)

Below is the implementation of above approach:

## C++

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

## Java

 `// Java program to implement double-ended ` `// priority queue using self balancing BST. ` `import` `java.util.*;` `class` `solution` `{`   `static` `class` `DblEndedPQ { ` `    ``Set s; ` `    ``DblEndedPQ()` `    ``{` `        ``s= ``new` `HashSet();` `    ``}` `    ``// Returns size of the queue. Works in ` `    ``// O(1) time ` `    ``int` `size() ` `    ``{ ` `    ``return` `s.size(); ` `    ``} `   `    ``// Returns true if queue is empty. Works ` `    ``// in O(1) time ` `    ``boolean` `isEmpty() ` `    ``{ ` `    ``return` `(s.size() == ``0``); ` `    ``} `   `    ``// Inserts an element. Works in O(Log n) ` `    ``// time ` `    ``void` `insert(``int` `x) ` `    ``{ ` `        ``s.add(x); ` `        `  `    ``} `   `    ``// Returns minimum element. Works in O(1) ` `    ``// time ` `    ``int` `getMin() ` `    ``{ ` `        ``return` `Collections.min(s,``null``); ` `    ``} `   `    ``// Returns maximum element. Works in O(1) ` `    ``// time ` `    ``int` `getMax() ` `    ``{ ` `        ``return` `Collections.max(s,``null``); ` `    ``} ` `    `  `    ``// Deletes minimum element. Works in O(Log n) ` `    ``// time ` `    ``void` `deleteMin() ` `    ``{ ` `        ``if` `(s.size() == ``0``) ` `            ``return` `; ` `        ``s.remove(Collections.min(s,``null``)); ` `        `  `    ``} `   `    ``// Deletes maximum element. Works in O(Log n) ` `    ``// time ` `    ``void` `deleteMax() ` `    ``{ ` `        ``if` `(s.size() == ``0``) ` `            ``return` `; ` `        ``s.remove(Collections.max(s,``null``));` `        `  `    ``} ` `}; `   `// Driver code ` `public` `static` `void` `main(String args[])` `{ ` `    ``DblEndedPQ d= ``new` `DblEndedPQ(); ` `    ``d.insert(``10``); ` `    ``d.insert(``50``); ` `    ``d.insert(``40``); ` `    ``d.insert(``20``); ` `    ``System.out.println( d.getMin() ); ` `    ``System.out.println(d.getMax() ); ` `    ``d.deleteMax(); ` `    ``System.out.println( d.getMax() ); ` `    ``d.deleteMin(); ` `    ``System.out.println( d.getMin() ); ` `} ` `}` `//contributed by Arnab Kundu`

## C#

 `// C# program to implement double-ended ` `// priority queue using self balancing BST. ` `using` `System;` `using` `System.Linq;` `using` `System.Collections.Generic; `   `class` `GFG` `{`   `public` `class` `DblEndedPQ ` `{ ` `    ``HashSet<``int``> s; ` `    ``public` `DblEndedPQ()` `    ``{` `        ``s = ``new` `HashSet<``int``>();` `    ``}` `    `  `    ``// Returns size of the queue. Works in ` `    ``// O(1) time ` `    ``public` `int` `size() ` `    ``{ ` `        ``return` `s.Count; ` `    ``} `   `    ``// Returns true if queue is empty. Works ` `    ``// in O(1) time ` `    ``public` `bool` `isEmpty() ` `    ``{ ` `        ``return` `(s.Count == 0); ` `    ``} `   `    ``// Inserts an element. Works in O(Log n) ` `    ``// time ` `    ``public` `void` `insert(``int` `x) ` `    ``{ ` `        ``s.Add(x); ` `        `  `    ``} `   `    ``// Returns minimum element. Works in O(1) ` `    ``// time ` `    ``public` `int` `getMin() ` `    ``{ ` `        ``return` `s.Min(); ` `    ``} `   `    ``// Returns maximum element. Works in O(1) ` `    ``// time ` `    ``public` `int` `getMax() ` `    ``{ ` `        ``return` `s.Max(); ` `    ``} ` `    `  `    ``// Deletes minimum element. Works in O(Log n) ` `    ``// time ` `    ``public` `void` `deleteMin() ` `    ``{ ` `        ``if` `(s.Count == 0) ` `            ``return` `; ` `        ``s.Remove(s.Min()); ` `        `  `    ``} `   `    ``// Deletes maximum element. Works in O(Log n) ` `    ``// time ` `    ``public` `void` `deleteMax() ` `    ``{ ` `        ``if` `(s.Count == 0) ` `            ``return` `; ` `        ``s.Remove(s.Max());` `        `  `    ``} ` `}; `   `// Driver code ` `public` `static` `void` `Main(String[] args)` `{ ` `    ``DblEndedPQ d= ``new` `DblEndedPQ(); ` `    ``d.insert(10); ` `    ``d.insert(50); ` `    ``d.insert(40); ` `    ``d.insert(20); ` `    ``Console.WriteLine( d.getMin() ); ` `    ``Console.WriteLine(d.getMax() ); ` `    ``d.deleteMax(); ` `    ``Console.WriteLine( d.getMax() ); ` `    ``d.deleteMin(); ` `    ``Console.WriteLine( d.getMin() ); ` `} ` `}`   `// This code contributed by Rajput-Ji`

## Javascript

 ``

## Python3

 `# Python code for the above approach`     `class` `DblEndedPQ:` `    ``def` `__init__(``self``):` `        ``self``.s ``=` `set``()`   `    ``# Returns size of the queue. Works in` `    ``# O(1) time`   `    ``def` `size(``self``):` `        ``return` `len``(``self``.s)`   `    ``# Returns true if queue is empty. Works` `    ``# in O(1) time` `    ``def` `isEmpty(``self``):` `        ``return` `len``(``self``.s) ``=``=` `0`   `    ``# Inserts an element. Works in O(Log n)` `    ``# time` `    ``def` `insert(``self``, x):` `        ``self``.s.add(x)`   `    ``# Returns minimum element. Works in O(1)` `    ``# time` `    ``def` `getMin(``self``):` `        ``return` `min``(``self``.s)`   `    ``# Returns maximum element. Works in O(1)` `    ``# time` `    ``def` `getMax(``self``):` `        ``return` `max``(``self``.s)`   `    ``# Deletes minimum element. Works in O(Log n)` `    ``# time` `    ``def` `deleteMin(``self``):` `        ``if` `len``(``self``.s) ``=``=` `0``:` `            ``return` `        ``self``.s.remove(``self``.getMin())`   `    ``# Deletes maximum element. Works in O(Log n)` `    ``# time` `    ``def` `deleteMax(``self``):` `        ``if` `len``(``self``.s) ``=``=` `0``:` `            ``return` `        ``self``.s.remove(``self``.getMax())`     `# Driver code` `d ``=` `DblEndedPQ()` `d.insert(``10``)` `d.insert(``50``)` `d.insert(``40``)` `d.insert(``20``)` `print``(d.getMin())` `print``(d.getMax())` `d.deleteMax()` `print``(d.getMax())` `d.deleteMin()` `print``(d.getMin())`   `# This code is contributed by codebraxnzt`

Output

```10
50
40
20```

Comparison of Heap and BST solutions
Heap based solution requires O(n) extra space for an extra heap. BST based solution does not require extra space. The advantage of heap based solution is cache friendly.

My Personal Notes arrow_drop_up