How to use the priority queue STL for objects? - c++

class Person
{
public:
int age;
};
I want to store objects of the class Person in a priority queue.
priority_queue< Person, vector<Person>, ??? >
I think I need to define a class for the comparison thing, but I am not sure about it.
Also, when we write,
priority_queue< int, vector<int>, greater<int> >
How does the greater work?

You need to provide a valid strict weak ordering comparison for the type stored in the queue, Person in this case. The default is to use std::less<T>, which resolves to something equivalent to operator<. This relies on it's own stored type having one. So if you were to implement
bool operator<(const Person& lhs, const Person& rhs);
it should work without any further changes. The implementation could be
bool operator<(const Person& lhs, const Person& rhs)
{
return lhs.age < rhs.age;
}
If the the type does not have a natural "less than" comparison, it would make more sense to provide your own predicate, instead of the default std::less<Person>. For example,
struct LessThanByAge
{
bool operator()(const Person& lhs, const Person& rhs) const
{
return lhs.age < rhs.age;
}
};
then instantiate the queue like this:
std::priority_queue<Person, std::vector<Person>, LessThanByAge> pq;
Concerning the use of std::greater<Person> as comparator, this would use the equivalent of operator> and have the effect of creating a queue with the priority inverted WRT the default case. It would require the presence of an operator> that can operate on two Person instances.

You would write a comparator class, for example:
struct CompareAge {
bool operator()(Person const & p1, Person const & p2) {
// return "true" if "p1" is ordered before "p2", for example:
return p1.age < p2.age;
}
};
and use that as the comparator argument:
priority_queue<Person, vector<Person>, CompareAge>
Using greater gives the opposite ordering to the default less, meaning that the queue will give you the lowest value rather than the highest.

A priority queue is an abstract data type that captures the idea of a container whose elements have "priorities" attached to them. An element of highest priority always appears at the front of the queue. If that element is removed, the next highest priority element advances to the front.
The C++ standard library defines a class template priority_queue, with the following operations:
push: Insert an element into the prioity queue.
top: Return (without removing it) a highest priority element from the priority queue.
pop: Remove a highest priority element from the priority queue.
size: Return the number of elements in the priority queue.
empty: Return true or false according to whether the priority queue is empty or not.
The following code snippet shows how to construct two priority queues, one that can contain integers and another one that can contain character strings:
#include <queue>
priority_queue<int> q1;
priority_queue<string> q2;
The following is an example of priority queue usage:
#include <string>
#include <queue>
#include <iostream>
using namespace std; // This is to make available the names of things defined in the standard library.
int main()
{
piority_queue<string> pq; // Creates a priority queue pq to store strings, and initializes the queue to be empty.
pq.push("the quick");
pq.push("fox");
pq.push("jumped over");
pq.push("the lazy dog");
// The strings are ordered inside the priority queue in lexicographic (dictionary) order:
// "fox", "jumped over", "the lazy dog", "the quick"
// The lowest priority string is "fox", and the highest priority string is "the quick"
while (!pq.empty()) {
cout << pq.top() << endl; // Print highest priority string
pq.pop(); // Remmove highest priority string
}
return 0;
}
The output of this program is:
the quick
the lazy dog
jumped over
fox
Since a queue follows a priority discipline, the strings are printed from highest to lowest priority.
Sometimes one needs to create a priority queue to contain user defined objects. In this case, the priority queue needs to know the comparison criterion used to determine which objects have the highest priority. This is done by means of a function object belonging to a class that overloads the operator (). The overloaded () acts as < for the purpose of determining priorities. For example, suppose we want to create a priority queue to store Time objects. A Time object has three fields: hours, minutes, seconds:
struct Time {
int h;
int m;
int s;
};
class CompareTime {
public:
bool operator()(Time& t1, Time& t2) // Returns true if t1 is earlier than t2
{
if (t1.h < t2.h) return true;
if (t1.h == t2.h && t1.m < t2.m) return true;
if (t1.h == t2.h && t1.m == t2.m && t1.s < t2.s) return true;
return false;
}
}
A priority queue to store times according the the above comparison criterion would be defined as follows:
priority_queue<Time, vector<Time>, CompareTime> pq;
Here is a complete program:
#include <iostream>
#include <queue>
#include <iomanip>
using namespace std;
struct Time {
int h; // >= 0
int m; // 0-59
int s; // 0-59
};
class CompareTime {
public:
bool operator()(Time& t1, Time& t2)
{
if (t1.h < t2.h) return true;
if (t1.h == t2.h && t1.m < t2.m) return true;
if (t1.h == t2.h && t1.m == t2.m && t1.s < t2.s) return true;
return false;
}
};
int main()
{
priority_queue<Time, vector<Time>, CompareTime> pq;
// Array of 4 time objects:
Time t[4] = { {3, 2, 40}, {3, 2, 26}, {5, 16, 13}, {5, 14, 20}};
for (int i = 0; i < 4; ++i)
pq.push(t[i]);
while (! pq.empty()) {
Time t2 = pq.top();
cout << setw(3) << t2.h << " " << setw(3) << t2.m << " " <<
setw(3) << t2.s << endl;
pq.pop();
}
return 0;
}
The program prints the times from latest to earliest:
5 16 13
5 14 20
3 2 40
3 2 26
If we wanted earliest times to have the highest priority, we would redefine CompareTime like this:
class CompareTime {
public:
bool operator()(Time& t1, Time& t2) // t2 has highest prio than t1 if t2 is earlier than t1
{
if (t2.h < t1.h) return true;
if (t2.h == t1.h && t2.m < t1.m) return true;
if (t2.h == t1.h && t2.m == t1.m && t2.s < t1.s) return true;
return false;
}
};

This piece of code may help..
#include <bits/stdc++.h>
using namespace std;
class node{
public:
int age;
string name;
node(int a, string b){
age = a;
name = b;
}
};
bool operator<(const node& a, const node& b) {
node temp1=a,temp2=b;
if(a.age != b.age)
return a.age > b.age;
else{
return temp1.name.append(temp2.name) > temp2.name.append(temp1.name);
}
}
int main(){
priority_queue<node> pq;
node b(23,"prashantandsoon..");
node a(22,"prashant");
node c(22,"prashantonly");
pq.push(b);
pq.push(a);
pq.push(c);
int size = pq.size();
for (int i = 0; i < size; ++i)
{
cout<<pq.top().age<<" "<<pq.top().name<<"\n";
pq.pop();
}
}
Output:
22 prashantonly
22 prashant
23 prashantandsoon..

We can define user defined comparator: .The code below can be helpful for you.
Code Snippet :
#include<bits/stdc++.h>
using namespace std;
struct man
{
string name;
int priority;
};
class comparator
{
public:
bool operator()(const man& a, const man& b)
{
return a.priority<b.priority;
}
};
int main()
{
man arr[5];
priority_queue<man, vector<man>, comparator> pq;
for(int i=0; i<3; i++)
{
cin>>arr[i].name>>arr[i].priority;
pq.push(arr[i]);
}
while (!pq.empty())
{
cout<<pq.top().name<<" "<<pq.top().priority;
pq.pop();
cout<<endl;
}
return 0;
}
input :
batman 2
goku 9
mario 4
Output
goku 9
mario 4
batman 2

Related

In C++, when adding onto a minHeap, which calls the bubbleUp function, how can I lexicographically compare two things that have the same priority?

In C++, when adding onto a minHeap, which calls the bubbleUp function, how can I lexicographically compare two things that have the same priority?
I want the value that is smaller when compared lexicographically to come first in the heap. What should be the if condition be?
If the code is something like this:
void MinHeap::bubbleUp(int pos)
{
if (pos >= 0 && vec[pos].second < vec[(pos-1)/d].second)]
{
swap(vec[pos], vec[(pos-1)/d)];
bubbleUp(vec[(pos-1)/d)];
}
else if (pos >= 0 && vec[pos].second == vec[(pos-1)/d].second)
{
if(vec[pos].first < vec[(pos-1)/d].first)
{
swap(vec[pos], vec[(pos-1)/d];
bubbleup((pos-1)/d];
}
}
}
For some reference, the vector contains pair of string and priority.
If you want a specific sorting order for your data, you can either use a build in comparison function for "something is greater than something else", or, you can provide a custom sort Functor.
In order to use the Functor, you need to instantiate the std::priority_queue (the MinHeap) withall 3 template parameters. The last one will be the compare functor.
As underlying container you can take a std::vector.
An example program could look like the following:
#include <iostream>
#include <vector>
#include <queue>
struct MyData {
int a{};
int b{};
friend std::ostream& operator << (std::ostream& os, const MyData& m) {
return os << "a: " << m.a << " b: " << m.b << '\n';
}
};
struct Compare {
bool operator()(const MyData& md1, const MyData& md2) {
if (md1.a == md2.a)
return md1.b > md2.b;
else
return md1.a > md2.a;
}
};
using UnderlyingContainer = std::vector<MyData>;
using MinHeap = std::priority_queue<MyData, UnderlyingContainer, Compare>;
int main() {
MyData md1{ 5,5 }, md2{ 5,4 }, md3{ 5,3 }, md4{ 5,2 }, md5{ 5,1 };
MinHeap mh{};
mh.push(md1); mh.push(md4); mh.push(md3); mh.push(md2); mh.push(md5);
for (size_t i = 0; i < 5; ++i) {
std::cout << mh.top();
mh.pop();
}
return 0;
}

C++ List showing last 3 items from table

Hey i have a table of teams with the names and the points they have and i'm trying to figure out how to display the last 3 teams with the least amount of points in the table?
It displays all the teams and i want it to display only the last 3 in the table but don't know what way to go about it.
These are my Accessors
string GetName
int GetPoints
int lowest = 1000;
for (int i = 0; i < numTeams; i++)
{
if (league[i].GetPoints() < lowest)
{
lowest = league[i].GetPoints();
}
}
for (int i = 0; i < numTeams; i++)
{
if (league[i].GetPoints() == lowest)
{
cout << "\tThe lowest goals against is: " << league[i].GetName() << endl;
}
}
Actually, you don't need variable lowest, if you would sort the data before printing.
#include <algorithm>
// Sort using a Lambda expression.
std::sort(std::begin(league), std::end(league), [](const League &a, const League &b) {
return a.GetPoints() < b.GetPoints();
});
int last = 3;
for (int i = 0; i < last; i++)
{
cout << "\tThe lowest goals against is: " << league[i].GetName() << endl;
}
U could probably start by sorting your array
#include <algorithm>
std::array<int> foo;
std::sort(foo.begin(), foo.end());
and then Iterate From Your Last Element to your Last - 3. (U can use Reverse Iterators)
for (std::vector<int>::reverse_iterator it = v.rend() ; it != v.rend() + 3;
it++) {
//Do something
}
or by using auto
for (auto it = v.rend() ; it != v.rend() + 3; ++it) {
//Do something
}
In my example I've created test class(TestTeam) to implement several important methods for objects in your task.
I use std::sort method to sort container of objects, by default std::sort compares objects by less(<) operation, so I have overrided operator < for TestTeam object
bool operator < ( const TestTeam& r) const
{
return GetPoints() < r.GetPoints();
}
Also we could pass as third parameter another compare method or lambda method as shown in below answers:
std::sort(VecTeam.begin(), VecTeam.end(), [](const TestTeam& l, const TestTeam& r)
{
return l.GetPoints() < r.GetPoints();
});
And example when we use global method to compare:
bool CompareTestTeamLess(const TestTeam& l, const TestTeam& r)
{
return l.GetPoints() < r.GetPoints();
}
//...
// some code
//...
// In main() we use global method to sort
std::sort(VecTeam.begin(), VecTeam.end(), ::CompareTestTeamLess);
You can try my code with vector as container:
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
// Test class for example
class TestTeam
{
public:
TestTeam(int16_t p, const std::string& name = "Empty name"):mPoints(p), mName(name)
{
};
int16_t GetPoints() const {return mPoints;}
const std::string& GetName() const {return mName;}
void SetName( const std::string& name ) {mName=name;}
bool operator < ( const TestTeam& r) const
{
return GetPoints() < r.GetPoints();
}
private:
int16_t mPoints;
std::string mName;
};
int main(int argc, const char * argv[])
{
const uint32_t COUNT_LOWEST_ELEMENTS_TO_FIND = 3;
// Fill container by test data with a help of non-explicit constructor to solve your task
std::vector<TestTeam> VecTeam {3,5,8,9,11,2,14,7};
// Here you can do others manipulations with team data ...
//Sort vector by GetPoints overloaded in less operator. After sort first three elements will be with lowest points in container
std::sort(VecTeam.begin(), VecTeam.end());
//Print results as points - name
std::for_each( VecTeam.begin(), VecTeam.begin() + COUNT_LOWEST_ELEMENTS_TO_FIND, [] (TestTeam el)
{
std::cout << el.GetPoints() << " - " << el.GetName() << std::endl;
} );
}
I made test class TestTeam only to implement test logic for your object.
If you try launch the program you can get next results:
2 - Empty name
3 - Empty name
5 - Empty name
Program ended with exit code: 0

Comparing function of binary_search

I am trying to run binary_search on vector of custom objects.
struct T{
string name;
T(string n):name(n){};
bool operator < ( T * n ) const {
return name < n -> name;
}
bool operator == ( T * n ) const {
return name == n -> name;
}
};
vector<T *> t;
t.push_back(new T("one"));
t.push_back(new T("two"));
t.push_back(new T("three"));
bool has_3 = binary_search( t.begin(), t.end(), new T("two") ) ;
if( has_3 ){
cout <<"Its there" << endl;
}
The comparation function should be just fine yet when i run the code has_3 equals to 0 = the element isnt present in vector. Is this problem caused by my overloading of < ? I see no reason why this shouldnt find the value. Considering the order of insertion into vector it should be sorted
Thanks for help.
There are several reasons why this shouldn't find the value:
The range must be sorted; your range is out of alphabetical order
Your comparison functionality is defined between T and T*, while you search a vector of T* for a T*.
You can fix the first problem by swapping "two" and "three", and the second problem by making a vector of T:
struct T{
string name;
T(string n):name(n){};
bool operator < ( const T &n ) const {
return name < n.name;
}
// operator == is not necessary for binary_search
};
int main() {
vector<T> t;
t.push_back(T("one"));
t.push_back(T("three"));
t.push_back(T("two"));
bool has_3 = binary_search( t.begin(), t.end(), T("two") ) ;
if( has_3 ){
cout <<"Its there" << endl;
}
return 0;
}
Demo 1.
If you do have no way but to construct a vector of pointers, you have this ugly work-around available (I strongly recommend against it):
struct T{
string name;
T(string n):name(n){};
};
bool operator < (const T& l, const T *r) {
return l.name < r->name;
}
bool operator < (const T *l, const T &r) {
return l->name < r.name;
}
Now you can search like this:
bool has_3 = binary_search( t.begin(), t.end(), T("two") ) ;
if( has_3 ){
cout <<"Its there" << endl;
}
Demo 2.
It's a really dumb requirement to work with a vector of pointers to dynamically allocated objects. But here is an approach that will work.
#include <iostream>
#include <string>
#include <algorithm>
struct T
{
std::string name;
T(std::string n):name(n){};
};
// this is the comparater needed to work with pointers, but it should
// NOT be a member of T
bool pointer_comparer(const T *left, const T *right)
{
// this assumes both left and right point to valid objects
return left->name < right->name;
}
int main()
{
std::vector<T *> t;
t.push_back(new T("one"));
t.push_back(new T("two"));
t.push_back(new T("three"));
// t is unsorted. We need to sort it since binary_search will
// ASSUME it is sorted
std::sort(t.begin(), t.end(), pointer_comparer);
T *value_needed = new T("two");
bool has_3 = std::binary_search( t.begin(), t.end(), value_needed, pointer_comparer);
if(has_3)
{
std::cout <<"Its there" << std::endl;
}
// since we've been stupidly allocating objects, we need to release them
delete value_needed;
for (std::vector<T *>::iterator i = t.begin(), end = t.end();
i != end; ++i)
{
delete (*i);
}
// and since t now contains a set of dangling pointers, we need to discard them too
t.resize(0);
return 0;
}
Why do I say the requirement to work with a vector of pointers to dynamically allocated objects. Compare the above with an approach that works with a vector<T> rather than a vector<T *>.
#include <iostream>
#include <string>
#include <algorithm>
struct T
{
std::string name;
T(std::string n):name(n){};
bool operator < (const T &) const
{
return name < n.name;
};
};
int main()
{
std::vector<T> t;
t.push_back(T("one"));
t.push_back(T("two"));
t.push_back(T("three"));
// t is unsorted. We need to sort it since binary_search will
// ASSUME it is sorted
std::sort(t.begin(), t.end());
bool has_3 = std::binary_search(t.begin(), t.end(), T("two"));
if(has_3)
{
std::cout <<"Its there" << std::endl;
}
// we need do nothing here. All objects use above will be properly released
return 0;
}
Note: I've written the above so it works with ALL C++ standards. Assuming C++11 and later, simplifications are possible in both cases.

How to use different comparators for a priority queue depending on conditions

I'm working on an assignment, where I have a priority queue and I want it to work like this:
if(field == '0')
priority_queue<record_t*,vector<record_t*>, CompareRecordID > pq;
else if(field == '1')
priority_queue<record_t*,vector<record_t*>, CompareRecordNum > pq;
else if(field == '2')
priority_queue<record_t*,vector<record_t*>, CompareRecordStr > pq;
else if(field == '3')
priority_queue<record_t*,vector<record_t*>, CompareRecordNumStr > pq;
Where record_t is:
typedef struct {
unsigned int recid;
unsigned int num;
char str[STR_LENGTH];
bool valid; // if set, then this record is valid
int blockID; //The block the record belongs too -> Used only for minheap
} record_t;
Which means, depending on a function argument field, the queue will "sort" a different field of record_t. However, I cannot declare a queue inside an if statement, since it will obviously give me an error "pq was not declared in this scope". What can I do?
You can use the std::priority_queue constructor that takes a comparator object as a parameter. Then you can feed it a configurable comparator a bit like this:
#include <vector>
#include <queue>
#include <cstring>
#include <iostream>
const int STR_LENGTH = 20;
struct record_t
{
unsigned int recid;
unsigned int num;
char str[STR_LENGTH];
bool valid; // if set, then this record is valid
int blockID; //The block the record belongs too -> Used only for minheap
};
// switchable priority comparator
struct CompareRecord
{
int field;
CompareRecord(int field = 0): field(field) {}
bool operator() (const record_t* lhs, const record_t* rhs) const
{
switch(field)
{
case 0: return lhs->recid < rhs->recid;
case 1: return lhs->num < rhs->num;
case 2: return std::strcmp(lhs->str, rhs->str) < 0;
}
return true;
}
};
int main()
{
// physical records
std::vector<record_t> records;
record_t r;
r.recid = 1;
r.num = 1;
std::strcpy(r.str, "banana");
records.push_back(r);
r.recid = 2;
r.num = 4;
std::strcpy(r.str, "orange");
records.push_back(r);
r.recid = 3;
r.num = 2;
std::strcpy(r.str, "apple");
records.push_back(r);
// input priority type: 0, 1 or 2
int field;
std::cout << "Sort type [0, 1, 2]: " << std::flush;
std::cin >> field;
std::cout << '\n';
// build priority view
CompareRecord cmp(field);
std::priority_queue<record_t*, std::vector<record_t*>, CompareRecord> pq(cmp);
for(auto& r: records)
pq.push(&r);
while(!pq.empty())
{
std::cout << "rec: " << pq.top()->recid << '\n';
std::cout << "num: " << pq.top()->num << '\n';
std::cout << "str: " << pq.top()->str << '\n';
std::cout << '\n';
pq.pop();
}
}
Output:
Sort type [0, 1, 2]: 0
rec: 3
num: 2
str: apple
rec: 2
num: 4
str: orange
rec: 1
num: 1
str: banana
A priority_queue can take a comparator as a constructor argument.
std::priority_queue<record_t*,vector<record_t*>, CompareRecord > pq((CompareRecord(field)));
You just need to define the CompareRecord comparator appropriately. A simple way to do it would be:
struct CompareRecord{
char type;
CompareRecord(char type):type(type){}
bool operator()(const record_t* lhs, const record_t* rhs){
switch(type){
case '1': return lhs->recid < rhs->recid;
.. and so forth.
}
}

How can I create Min stl priority_queue?

The default stl priority queue is a Max one (Top function returns the largest element).
Say, for simplicity, that it is a priority queue of int values.
Use std::greater as the comparison function:
std::priority_queue<int, std::vector<int>, std::greater<int> > my_min_heap;
One way would be to define a suitable comparator with which to operate on the ordinary priority queue, such that its priority gets reversed:
#include <iostream>
#include <queue>
using namespace std;
struct compare
{
bool operator()(const int& l, const int& r)
{
return l > r;
}
};
int main()
{
priority_queue<int,vector<int>, compare > pq;
pq.push(3);
pq.push(5);
pq.push(1);
pq.push(8);
while ( !pq.empty() )
{
cout << pq.top() << endl;
pq.pop();
}
cin.get();
}
Which would output 1, 3, 5, 8 respectively.
Some examples of using priority queues via STL and Sedgewick's implementations are given here.
The third template parameter for priority_queue is the comparator. Set it to use greater.
e.g.
std::priority_queue<int, std::vector<int>, std::greater<int> > max_queue;
You'll need #include <functional> for std::greater.
You can do it in multiple ways:
1. Using greater as comparison function :
#include <bits/stdc++.h>
using namespace std;
int main()
{
priority_queue<int,vector<int>,greater<int> >pq;
pq.push(1);
pq.push(2);
pq.push(3);
while(!pq.empty())
{
int r = pq.top();
pq.pop();
cout<<r<< " ";
}
return 0;
}
2. Inserting values by changing their sign (using minus (-) for positive number and using plus (+) for negative number :
int main()
{
priority_queue<int>pq2;
pq2.push(-1); //for +1
pq2.push(-2); //for +2
pq2.push(-3); //for +3
pq2.push(4); //for -4
while(!pq2.empty())
{
int r = pq2.top();
pq2.pop();
cout<<-r<<" ";
}
return 0;
}
3. Using custom structure or class :
struct compare
{
bool operator()(const int & a, const int & b)
{
return a>b;
}
};
int main()
{
priority_queue<int,vector<int>,compare> pq;
pq.push(1);
pq.push(2);
pq.push(3);
while(!pq.empty())
{
int r = pq.top();
pq.pop();
cout<<r<<" ";
}
return 0;
}
4. Using custom structure or class you can use priority_queue in any order.
Suppose, we want to sort people in descending order according to their salary and if tie then according to their age.
struct people
{
int age,salary;
};
struct compare{
bool operator()(const people & a, const people & b)
{
if(a.salary==b.salary)
{
return a.age>b.age;
}
else
{
return a.salary>b.salary;
}
}
};
int main()
{
priority_queue<people,vector<people>,compare> pq;
people person1,person2,person3;
person1.salary=100;
person1.age = 50;
person2.salary=80;
person2.age = 40;
person3.salary = 100;
person3.age=40;
pq.push(person1);
pq.push(person2);
pq.push(person3);
while(!pq.empty())
{
people r = pq.top();
pq.pop();
cout<<r.salary<<" "<<r.age<<endl;
}
Same result can be obtained by operator overloading :
struct people
{
int age,salary;
bool operator< (const people & p)const
{
if(salary==p.salary)
{
return age>p.age;
}
else
{
return salary>p.salary;
}
}};
In main function :
priority_queue<people> pq;
people person1,person2,person3;
person1.salary=100;
person1.age = 50;
person2.salary=80;
person2.age = 40;
person3.salary = 100;
person3.age=40;
pq.push(person1);
pq.push(person2);
pq.push(person3);
while(!pq.empty())
{
people r = pq.top();
pq.pop();
cout<<r.salary<<" "<<r.age<<endl;
}
In C++11 you could also create an alias for convenience:
template<class T> using min_heap = priority_queue<T, std::vector<T>, std::greater<T>>;
And use it like this:
min_heap<int> my_heap;
One Way to solve this problem is, push the negative of each element in the priority_queue so the largest element will become the smallest element. At the time of making pop operation, take the negation of each element.
#include<bits/stdc++.h>
using namespace std;
int main(){
priority_queue<int> pq;
int i;
// push the negative of each element in priority_queue, so the largest number will become the smallest number
for (int i = 0; i < 5; i++)
{
cin>>j;
pq.push(j*-1);
}
for (int i = 0; i < 5; i++)
{
cout<<(-1)*pq.top()<<endl;
pq.pop();
}
}
Based on above all answers I created an example code for how to create priority queue. Note: It works C++11 and above compilers
#include <iostream>
#include <vector>
#include <iomanip>
#include <queue>
using namespace std;
// template for prirority Q
template<class T> using min_heap = priority_queue<T, std::vector<T>, std::greater<T>>;
template<class T> using max_heap = priority_queue<T, std::vector<T>>;
const int RANGE = 1000;
vector<int> get_sample_data(int size);
int main(){
int n;
cout << "Enter number of elements N = " ; cin >> n;
vector<int> dataset = get_sample_data(n);
max_heap<int> max_pq;
min_heap<int> min_pq;
// Push data to Priority Queue
for(int i: dataset){
max_pq.push(i);
min_pq.push(i);
}
while(!max_pq.empty() && !min_pq.empty()){
cout << setw(10) << min_pq.top()<< " | " << max_pq.top() << endl;
min_pq.pop();
max_pq.pop();
}
}
vector<int> get_sample_data(int size){
srand(time(NULL));
vector<int> dataset;
for(int i=0; i<size; i++){
dataset.push_back(rand()%RANGE);
}
return dataset;
}
Output of Above code
Enter number of elements N = 4
33 | 535
49 | 411
411 | 49
535 | 33
We can do this using several ways.
Using template comparator parameter
int main()
{
priority_queue<int, vector<int>, greater<int> > pq;
pq.push(40);
pq.push(320);
pq.push(42);
pq.push(65);
pq.push(12);
cout<<pq.top()<<endl;
return 0;
}
Using used defined compartor class
struct comp
{
bool operator () (int lhs, int rhs)
{
return lhs > rhs;
}
};
int main()
{
priority_queue<int, vector<int>, comp> pq;
pq.push(40);
pq.push(320);
pq.push(42);
pq.push(65);
pq.push(12);
cout<<pq.top()<<endl;
return 0;
}
Multiply values with -1 and use max heap to get the effect of min heap