# 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.

## Recommended: Please try your approach on {IDE} first, before moving on to the solution.

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 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 s;      public DblEndedPQ()     {         s = new HashSet();     }            // 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

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.

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.

My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.

Improved By : andrew1234, Rajput-Ji