I need some kind of priority queue to store pairs <key, value>. Values are unique, but keys aren’t. I will be performing the following operations (most common first):
- random insertion;
- retrieving (and removing) all elements with the least key.
- random removal (by value);
I can’t use std::priority_queue because it only supports removing the head.
For now, I’m using an unsorted std::list. Insertion is performed by just pushing new elements to the back (O(1)). Operation 2 sorts the list with list::sort (O(N*logN)), before performing the actual retrieval. Removal, however, is O(n), which is a bit expensive.
Any idea of a better data structure?
Ok, so I’ve tested many options and ended up with something based on the idea of Matthieu M.. I’m currently using a
std::map<key_type, std::list<value_type> >, where thevalue_typecontains astd::list<value_type>::iteratorto itself, which is useful for removal.Removal must check if the vector is empty, which implies a
mapquery and possibly a call toerase. Worst-case complexity is when keys are distinct,O(logN)for insertion,O(1)for retrieval andO(logN)for removal. I’ve got very good experimental results comparing to other alternatives on my test machine.Using a
std::vectoris less efficient both in terms of theoretical complexity (O(N) worst-case for removal when keys are identical) and experimentation I’ve been doing.