Priority Queue with Stable Ordering

How can I ensure stable ordering in a priority queue when elements have the same priority?

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.

Priority Queues using std::priority_queue

Learn how to access objects based on their importance, and how to customise how that priority is determined

Questions & Answers

Answers are generated by AI models and may not have been reviewed. Be mindful when running any code on your device.

Custom Comparison Function for Priority Queue
How can I define a custom comparison function for a priority queue of custom objects?
Removing a Specific Element from Priority Queue
Is it possible to remove a specific element from a priority queue without popping the top element?
Priority Queue with Unique Elements
How can I ensure that a priority queue contains only unique elements?
Priority Queue with Dynamic Priorities
Can I update the priority of an element already in the priority queue?
Priority Queue with Custom Container
Can I use a custom container as the underlying container for a priority queue?
Or Ask your Own Question
Get an immediate answer to your specific question using our AI assistant