Open In App

Custom Comparator in Priority_queue in C++ STL

Improve
Improve
Like Article
Like
Save
Share
Report

Prerequisites:

Priority_queue<template datatype> is a very famous STL Container generally used when we need to use Heap Data structure.

 The Characteristics of the heap data structure are:

  • O(1) or constant time retrieval of min/max in the list.
  • O(log N) time for insertion and deletion.

Syntax:

priority_queue<data_type, container, comparator> ds;

Parameters:

  • data_type (mandatory) : datatype that we are going to store in priority_queue. (int, float, or even any custom datatype)
  • container (optional) : Container is passed as an underlying container to store the elements. It needs to satisfy some properties, therefore it can be either vector<datatype> or deque<datatype>.
  • comparator (optional) : Comparator decides the ordering of elements.

Why do we need a Custom Comparator?

  • Say in the above code we have either got the Maximum most element at the top of the priority queue (Max Heap) or the Minimum most element at the top of the priority queue (Min heap).
  • In Complex objects or pairs of data, we may need a different set of orders that are not entirely Ascending or Descending.
  • Comparator in the case of priority_queue decides the ordering of elements, which is basically in the competition among the elements, it decides who needs to be at the top of the priority queue.
  • In the case of Min-Heap, the greater<int> was used.

Custom Comparator in priority_queue

  • Likewise, how we passed greater<datatype> an inbuilt comparator, we can also pass a user-defined comparator to priority_queue.
  • You should declare a class Compare and overload operator() function.
class Compare {
    public:
       bool operator()(T a, T b){
           if(cond){
               return true;
           }
           return false;
      }
};
  • When true is returned, it means the order is correct and NO swapping of elements takes place.
  • When false is returned, it means the order is NOT correct and swapping of elements takes place.

Example:

  • We have pair of integers inside the priority_queue
  • first part sorted based on Ascending order. (Smaller first)
  • the second part is sorted based on Descending order. (Larger first)

Input:

{100,11} {100,41} {100,21} {300,1} {300,2} {1,1} {1,2} {1,20}

Output:

Top to Bottom:

1 20
1 2
1 1
100 41
100 21
100 11
300 2
300 1

Code of the above example:

C++




// C++ Program to implement
// Custom Comparator in Priority Queue
#include <iostream>
#include <queue>
#define PII pair<int, int>
 
// Pair of Ints = PII
using namespace std;
 
// based on first part in ascending and second part in
// descending first basis
class Compare {
public:
    bool operator()(PII below, PII above)
    {
        if (below.first > above.first) {
            return true;
        }
        else if (below.first == above.first
                 && below.second < above.second) {
            return true;
        }
 
        return false;
    }
};
 
int main()
{
    priority_queue<PII, vector<PII>, Compare> ds;
    ds.push({ 100, 11 });
    ds.push({ 100, 41 });
    ds.push({ 100, 21 });
    ds.push({ 300, 1 });
    ds.push({ 300, 2 });
    ds.push({ 1, 1 });
    ds.push({ 1, 2 });
    ds.push({ 1, 20 });
 
    cout << "The priority queue is : \n";
    while (!ds.empty()) {
        cout << ds.top().first << " " << ds.top().second
             << "\n";
        ds.pop(); // heapify happens
    }
 
    return 0;
}


Output

The priority queue is : 
1 20
1 2
1 1
100 41
100 21
100 11
300 2
300 1

Time and Space Complexity:

Time Complexity: O(Log K), where K is the size of the heap. If Total insertions are N, then it is O(N*LogK). In the above case, the K = N, therefore it boils down to O(N*LogN)

Space Complexity: O(K), where K is the size of the heap.



Last Updated : 23 Dec, 2022
Like Article
Save Article
Share your thoughts in the comments
Similar Reads