12 #ifndef LOW_PRIORITY_QUEUE
13 #define LOW_PRIORITY_QUEUE
20 template<
class Element,
class Priority =
size_t,
class comparator = less<Priority> >
21 class low_priority_queue{
24 typedef typename std::pair<Element, Priority> value_type;
25 typedef typename list<value_type>::const_iterator const_iterator;
29 typedef typename list<value_type>::iterator iterator;
30 vector<list<value_type> > prio_to_list;
31 Priority min_priority;
32 const comparator* compare;
33 const bool delete_comparator;
38 low_priority_queue(
const comparator& _compare):
39 min_priority(SIZE_MAX),
41 delete_comparator(false),
42 increment((*compare)(Priority(0),Priority(1)) ? 1 : -1)
47 min_priority(SIZE_MAX),
48 compare(new comparator()),
49 delete_comparator(true),
50 increment((*compare)(Priority(0),Priority(1)) ? 1 : -1)
54 low_priority_queue(
const low_priority_queue<Element, Priority, comparator>& lpq):
55 compare(new comparator(lpq.compare)),
56 delete_comparator(true),
57 increment(lpq.increment)
60 for(Priority p(0); p < lpq.prio_to_list.size(); ++p){
61 const list<value_type>& vlist = lpq.prio_to_list[p];
63 prio_to_list.emplace_back(vlist);
64 if(first || compare(min_priority, p)){
72 ~low_priority_queue(){
73 if(delete_comparator)
delete compare;
77 const bool empty()
const{
78 return prio_to_list.empty();
82 const_iterator insert(
const value_type& value){
83 const Priority& prio = value.second;
85 if((*compare)(prio, min_priority) || empty()) min_priority = prio;
86 if(prio >= prio_to_list.size()) prio_to_list.resize(prio + 1);
87 list<value_type>& prio_list = prio_to_list[prio];
88 prio_list.emplace_front(value);
89 DEBUG5(cout <<
"inserted item of priority "<<prio_list.front().second<<
" min_priority is now "<<min_priority<<endl);
90 return prio_list.begin();
95 bool min_priority_can_be_incremented()
const{
96 if(increment == 1)
return min_priority < prio_to_list.size() - 1;
else return min_priority > 0;
101 void erase(
const const_iterator& it){
102 const Priority& prio = it->second;
103 assert(prio < prio_to_list.size());
105 list<value_type>& vlist = prio_to_list[prio];
109 while( min_priority_can_be_incremented() && prio_to_list[min_priority].empty()) min_priority += increment;
111 if(prio_to_list[min_priority].empty()){
112 prio_to_list.clear();
113 DEBUG5(cout <<
"prio queue now empty"<<endl);
115 DEBUG5(cout <<
"done erasing an item, new min_priority is "<<min_priority<<
" and there are "<<prio_to_list[min_priority].size()<<
" such items"<<endl);
120 void change_priority(
const const_iterator& it,
const Priority& new_prio){
121 const Priority& old_prio = it->second;
122 assert(old_prio < prio_to_list.size());
124 if(old_prio != new_prio){
126 if(new_prio >= prio_to_list.size())
127 prio_to_list.resize(new_prio + 1);
129 list<value_type>& source_list = prio_to_list[old_prio];
130 list<value_type>& target_list = prio_to_list[new_prio];
132 target_list.splice(target_list.begin(), source_list, it);
133 target_list.front().second = new_prio;
136 if((*compare)(new_prio, min_priority)) min_priority = new_prio;
137 while(prio_to_list[min_priority].empty()) min_priority += increment;
139 DEBUG5(cout <<
"changed a priority to "<<new_prio<<
", min priority now "<<min_priority<<
" & "<<prio_to_list[new_prio].size()<<
" items with the new prio"<<endl);
142 void decrement_priority(
const const_iterator& it){
143 change_priority(it, it->second - 1);
145 void increment_priority(
const const_iterator& it){
146 change_priority(it, it->second + 1);
151 assert(!prio_to_list.empty());
152 return prio_to_list[min_priority].front();
155 const value_type& top()
const{
156 return prio_to_list[min_priority].front();
162 erase(prio_to_list[min_priority].cbegin());
Definition: low_priority_queue.hpp:18