By default, the std::priority_queue
in C++ does not guarantee stable ordering when elements have the same priority. This means that if you insert elements with equal priorities, the order in which they are retrieved from the queue may not necessarily match the order in which they were inserted.
However, if you need stable ordering in a priority queue, you can achieve this by including additional information in the comparison function to break ties when elements have the same priority.
Here's an example of how you can ensure stable ordering in a priority queue:
#include <iostream>
#include <queue>
#include <vector>
struct Element {
int value;
int priority;
int insertionOrder;
};
struct CompareElement {
bool operator()(const Element& e1,
const Element& e2) {
if (e1.priority == e2.priority) {
return e1.insertionOrder >
e2.insertionOrder;
}
return e1.priority < e2.priority;
}
};
int main() {
std::priority_queue<Element,
std::vector<Element>, CompareElement> pq;
int insertionOrder = 0;
auto insertElement = [&](int value,
int priority) {
pq.push({value, priority, insertionOrder++});
};
insertElement(10, 2);
insertElement(20, 1);
insertElement(30, 2);
insertElement(40, 1);
while (!pq.empty()) {
std::cout << pq.top().value << " (Priority: "
<< pq.top().priority << ")\n";
pq.pop();
}
}
In this example, we define a struct Element
that represents an element with a value, a priority, and an additional field insertionOrder
to keep track of the order in which elements are inserted.
We also define a custom comparator CompareElement
that compares elements based on their priority. When the priorities are equal, the comparator uses the insertionOrder
to determine the order. Elements with a lower insertionOrder
value are considered to have a higher priority, ensuring stable ordering.
We create a priority queue of Element
objects and define a lambda function insertElement
that takes a value and a priority. Inside the lambda function, we create an Element
object with the given value, priority, and the current insertionOrder
, and push it into the priority queue. The insertionOrder
is incremented after each insertion.
Finally, we insert elements into the priority queue using the insertElement
lambda function and print the elements in the order they are retrieved from the queue.
The output of this code will be:
20 (Priority: 1)
40 (Priority: 1)
10 (Priority: 2)
30 (Priority: 2)
As you can see, the elements with the same priority (1 and 2) are retrieved in the order they were inserted, ensuring stable ordering.
By including additional information, such as the insertion order, in the comparison function, you can break ties and maintain stable ordering in a priority queue when elements have the same priority.
Answers to questions are automatically generated and may not have been reviewed.
std::priority_queue
Learn how to access objects based on their importance, and how to customise how that priority is determined