Open In App

Multiple comparisons in a C++ priority queue?

Improve
Improve
Like Article
Like
Save
Share
Report

What is a Priority Queue?

A Priority Queue is an abstract data type that is similar to a queue, and every element has some priority value associated with it. The priority of the elements in a priority queue determines the order in which elements are served (i.e., the order in which they are removed). If in any case, the elements have the same priority, they are served as per their ordering in the queue.

To learn more about priority queue, refer to the article on “Introduction to Priority Queue“.

What is priority_queue STL in C++?

A ‘priority_queue‘ is a container adaptor that provides us with a constant time lookup of the largest element at the expense of logarithmic insertion and extraction. We can use a user-provided compare function to change the order e.g. using std::greater<T> would cause the smallest element to appear at the top.

When we are using the priority queue we are basically using a heap in some random access container, which has the benefit of not being able to accidentally invalidate the given heap.

Priority Queue with a Custom Comparator 

Custom comparators are static functions that are used to define the parameter on which the given container is going to be sorted. It determines the way in which the given container is going to be sorted. 

If we use a ‘>’ symbol then we are trying to sort in the ascending order else we are trying to sort in the descending order as ‘>‘ will return true when a > b (a is greater than b) else it will return false. So a swap will take place if the comparator is going to return false else no swap is going to take place. 

Let’s see a program and further understand how this concept is going to be applied.

C++




#include <bits/stdc++.h>
using namespace std;
 
// This template is used to print
// the given heap again and again
// irrespective of the given data type 
template <class T>
void printQueue(T& q)
{
    while (q.empty() == false) {
        cout << q.top() << " ";
        q.pop();
    }
    cout << endl;
}
 
// Here we are using a basic priority queue
// and sorting the queue in ascending order 
void samplepriorityqueue()
{
    priority_queue<int, vector<int>, greater<int> > pq;
    for (int i = 0; i < 10; i++) {
        pq.push(i);
    }
    printQueue(pq);
}
 
// Here we are using the lambda comparator function
// to sort given priority queue in descending order
void samplepriorityqueue1()
{
    auto compare = [](int left, int right) {
        return left < right;
    };
    priority_queue<int, vector<int>, decltype(compare)> pq(
        compare);
    for (int i = 0; i < 10; i++) {
        pq.push(i);
    }
    printQueue(pq);
}
 
// Here we are using a comparator function
// to sort the given priority queue.
// This comparator function can be extended
// to included several other features 
struct mycmp {
    bool operator()(int a, int b)
    {
        return a > b;
    }
};
 
void samplepriorityqueue2()
{
    priority_queue<int, vector<int>, mycmp> pq;
    for (int i = 0; i < 10; i++) {
        pq.push(i);
    }
    printQueue(pq);
}
 
// Driver code
int main()
{
    samplepriorityqueue();
    samplepriorityqueue1();
    samplepriorityqueue2();
    return 0;
}


Output

0 1 2 3 4 5 6 7 8 9 
9 8 7 6 5 4 3 2 1 0 
0 1 2 3 4 5 6 7 8 9 

Here we see how the comparator is used to compare the defined datatypes and sort the data according to the comparator that we have given.

Multiple Comparisons in a C++ Priority Queue

Next, we are going to make multiple comparisons using the priority queue on a user-defined data type and then we are going to sort the data that has been given to us.

We can build a comparator function that compares more than one parameter and sort the data structure based on the conditions provided in the comparator. Below is an implementation of multiple comparisons in C++ priority queue.

C++




#include <bits/stdc++.h>
using namespace std;
 
// Structure of a user defined data structure
struct jobs {
public:
    int priority;
    int processing;
    int arrivaltime;
    int proccessing_time;
    string job;
    jobs(int priority1, int processing1, int arrivaltime1,
         int proccessing_time1, string s1)
    {
        this->priority = priority1;
        this->processing = processing1;
        this->arrivaltime = arrivaltime1;
        this->proccessing_time = proccessing_time1;
        this->job = s1;
    }
};
 
// Here we are sorting based on the processing time
// if the priority is same and we are sorting
// in descending order if the priority is same.
// Else we are sorting in ascending order
// on the priority of the tasks given to us
struct compare {
    bool operator()(jobs a, jobs b)
    {
        if (a.priority == b.priority) {
            return a.processing < b.processing;
        }
        return a.priority > b.priority;
    }
};
 
// Driver code
int main()
{
    priority_queue<jobs, vector<jobs>, compare> pq;
    for (int i = 0; i < 10; i++) {
        jobs a(rand() % 11, i + 1, rand() % 3 + i,
               rand() % 5 + 3, "somejob" + to_string(i));
        pq.push(a);
    }
 
    while (pq.empty() == false) {
        jobs b = pq.top();
        pq.pop();
        cout << b.priority << " " << b.processing << " "
             << b.arrivaltime << " " << b.proccessing_time
             << " " << b.job << endl;
    }
    return 0;
}


Output

0 9 10 5 somejob8
0 8 7 6 somejob7
3 3 2 4 somejob2
4 2 3 3 somejob1
6 1 1 6 somejob0
7 5 5 3 somejob4
7 4 5 4 somejob3
10 10 10 6 somejob9
10 7 7 5 somejob6
10 6 5 4 somejob5


Last Updated : 11 Jan, 2024
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads