Priority Queues using std::priority_queue

Priority Queue with Stable Ordering

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

Illustration representing computer hardware

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.

A computer programmer
Part of the course:

Professional C++

Comprehensive course covering advanced concepts, and how to use them on large-scale projects.

Free, unlimited access

This course includes:

  • 124 Lessons
  • 550+ Code Samples
  • 96% Positive Reviews
  • Regularly Updated
  • Help and FAQ
Free, Unlimited Access

Professional C++

Comprehensive course covering advanced concepts, and how to use them on large-scale projects.

Screenshot from Warhammer: Total War
Screenshot from Tomb Raider
Screenshot from Jedi: Fallen Order
Contact|Privacy Policy|Terms of Use
Copyright © 2024 - All Rights Reserved