-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathBoundedPQueue.h
More file actions
193 lines (171 loc) · 6.69 KB
/
Copy pathBoundedPQueue.h
File metadata and controls
193 lines (171 loc) · 6.69 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
/**
* Author: Keith Schwarz (htiek@cs.stanford.edu)
*
* An implementation of the bounded priority queue abstraction.
* A bounded priority queue is in many ways like a regular priority
* queue. It stores a collection of elements tagged with a real-
* valued priority, and allows for access to the element whose
* priority is the smallest. However, unlike a regular priority
* queue, the number of elements in a bounded priority queue has
* a hard limit that is specified in the constructor. Whenever an
* element is added to the bounded priority queue such that the
* size exceeds the maximum, the element with the highest priority
* value will be ejected from the bounded priority queue. In this
* sense, a bounded priority queue is like a high score table for
* a video game that stores a fixed number of elements and deletes
* the least-important entry whenever a new value is inserted.
*
* When creating a bounded priority queue, you must specify the
* maximum number of elements to store in the queue as an argument
* to the constructor. For example:
*
* BoundedPQueue<int> bpq(15); // Holds up to fifteen values.
*
* The maximum size of the bounded priority queue can be obtained
* using the maxSize() function, as in
*
* size_t k = bpq.maxSize();
*
* Beyond these restrictions, the bounded priority queue behaves
* similarly to other containers. You can query its size using
* size() and check whether it is empty using empty(). You
* can enqueue an element into the bounded priority queue by
* writing
*
* bpq.enqueue(elem, priority);
*
* Note that after enqueuing the element, there is no guarantee
* that the value will actually be in the queue. If the queue
* is full and the new element's priority exceeds the largest
* priority in the container, it will not be added.
*
* You can dequeue elements from a bounded priority queue using
* the dequeueMin() function, as in
*
* int val = bpq.dequeueMin();
*
* The bounded priority queue also allows you to query the min
* and max priorities of the values in the queue. These values
* can be queried using the best() and worst() functions, which
* return the smallest and largest priorities in the queue,
* respectively.
*/
#ifndef BOUNDED_PQUEUE_INCLUDED
#define BOUNDED_PQUEUE_INCLUDED
#include <map>
#include <algorithm>
#include <limits>
template <typename T>
class BoundedPQueue {
public:
// Constructor: BoundedPQueue(size_t maxSize);
// Usage: BoundedPQueue<int> bpq(15);
// --------------------------------------------------
// Constructs a new, empty BoundedPQueue with
// maximum size equal to the constructor argument.
///
explicit BoundedPQueue(std::size_t maxSize);
// void enqueue(const T& value, double priority);
// Usage: bpq.enqueue("Hi!", 2.71828);
// --------------------------------------------------
// Enqueues a new element into the BoundedPQueue with
// the specified priority. If this overflows the maximum
// size of the queue, the element with the highest
// priority will be deleted from the queue. Note that
// this might be the element that was just added.
void enqueue(const T& value, double priority);
// T dequeueMin();
// Usage: int val = bpq.dequeueMin();
// --------------------------------------------------
// Returns the element from the BoundedPQueue with the
// smallest priority value, then removes that element
// from the queue.
T dequeueMin();
// size_t size() const;
// bool empty() const;
// Usage: while (!bpq.empty()) { ... }
// --------------------------------------------------
// Returns the number of elements in the queue and whether
// the queue is empty, respectively.
std::size_t size() const;
bool empty() const;
// size_t maxSize() const;
// Usage: size_t queueSize = bpq.maxSize();
// --------------------------------------------------
// Returns the maximum number of elements that can be
// stored in the queue.
std::size_t maxSize() const;
// double best() const;
// double worst() const;
// Usage: double highestPriority = bpq.worst();
// --------------------------------------------------
// best() returns the smallest priority of an element
// stored in the container (i.e. the priority of the
// element that will be dequeued first using dequeueMin).
// worst() returns the largest priority of an element
// stored in the container. If an element is enqueued
// with a priority above this value, it will automatically
// be deleted from the queue. Both functions return
// numeric_limits<double>::infinity() if the queue is
// empty.
double best() const;
double worst() const;
private:
// This class is layered on top of a multimap mapping from priorities
// to elements with those priorities.
std::multimap<double, T> elems;
std::size_t maximumSize;
};
/** BoundedPQueue class implementation details */
template <typename T>
BoundedPQueue<T>::BoundedPQueue(std::size_t maxSize) {
maximumSize = maxSize;
}
// enqueue adds the element to the map, then deletes the last element of the
// map if there size exceeds the maximum size.
template <typename T>
void BoundedPQueue<T>::enqueue(const T& value, double priority) {
// Add the element to the collection.
elems.insert(std::make_pair(priority, value));
// If there are too many elements in the queue, drop off the last one.
if (size() > maxSize()) {
typename std::multimap<double, T>::iterator last = elems.end();
--last; // Now points to highest-priority element
elems.erase(last);
}
}
// dequeueMin copies the lowest element of the map (the one pointed at by
// begin()) and then removes it.
template <typename T>
T BoundedPQueue<T>::dequeueMin() {
// Copy the best value.
T result = elems.begin()->second;
// Remove it from the map.
elems.erase(elems.begin());
return result;
}
// size() and empty() call directly down to the underlying map.
template <typename T>
std::size_t BoundedPQueue<T>::size() const {
return elems.size();
}
template <typename T>
bool BoundedPQueue<T>::empty() const {
return elems.empty();
}
// maxSize just returns the appropriate data member.
template <typename T>
std::size_t BoundedPQueue<T>::maxSize() const {
return maximumSize;
}
// The best() and worst() functions check if the queue is empty,
// and if so return infinity.
template <typename T>
double BoundedPQueue<T>::best() const {
return empty()? std::numeric_limits<double>::infinity() : elems.begin()->first;
}
template <typename T>
double BoundedPQueue<T>::worst() const {
return empty()? std::numeric_limits<double>::infinity() : elems.rbegin()->first;
}
#endif // BOUNDED_PQUEUE_INCLUDED