1use std::fmt;
10
11#[derive(Clone)]
35pub struct PrioQueue<T> {
36 prio: fn(&T, &T)->bool,
37 tree: Vec<T>,
38}
39impl<T> PrioQueue<T> {
40
41 pub fn new(prio: fn(&T, &T)->bool) -> Self {
43 Self {
44 prio,
45 tree: Vec::new(),
46 }
47 }
48
49 pub fn with_capacity(capacity: usize, prio: fn(&T, &T)->bool) -> Self {
50 Self {
51 prio,
52 tree: Vec::with_capacity(capacity),
53 }
54 }
55
56 pub fn new_min() -> Self
58 where T: PartialOrd
59 {
60 Self::new(|l, r| l < r)
61 }
62
63 pub fn new_max() -> Self
65 where T: PartialOrd
66 {
67 Self::new(|l, r| l > r)
68 }
69
70 pub fn push(&mut self, value: T) {
72 let index = self.len();
73 self.tree.push(value);
74 self.bubble_up(index);
75 }
76
77 pub fn pop(&mut self) -> Option<T> {
79 if self.len() == 0 {
80 None
81 }
82 else {
83 let poped = self.tree.swap_remove(0);
84 if self.len() > 0 {
85 self.bubble_down(0);
86 }
87 Some(poped)
88 }
89 }
90
91 pub fn remove(&mut self, index: usize) -> T {
93 assert!(index < self.len());
94 let poped = self.tree.swap_remove(index);
95 if index < self.len() {
96 self.bubble_up(index);
97 self.bubble_down(index);
98 }
99 poped
100 }
101
102 pub fn drain(&mut self) -> Drain<T> {
104 Drain {
105 inner: self
106 }
107 }
108
109 pub fn retain(&mut self, mut pred: impl FnMut(&T)->bool) {
111 let mut index = 0;
112 while index < self.len() {
113 if pred(&self[index]) {
114 self.bubble_up(index);
115 index += 1;
116 }
117 else {
118 self.tree.swap_remove(index);
119 }
120 }
121 }
122
123 fn bubble_up(&mut self, mut index: usize) {
124 debug_assert!(index < self.len());
125 while let Some(parent) = self.parent(index) {
126 if self.is_prio(index, parent) {
127 self.tree.swap(index, parent);
128 index = parent;
129 }
130 else {
131 break
132 }
133 }
134 }
135
136 fn bubble_down(&mut self, mut index: usize) {
137 debug_assert!(index < self.len());
138 while let Some((left, right)) = self.childs(index) {
139 let result = if let Some(right) = right {
140 if self.is_prio(left, right) {
141 if self.is_prio(left, index) {
142 Some(left)
143 }
144 else if self.is_prio(right, index) {
145 Some(right)
146 }
147 else {
148 None
149 }
150 }
151 else {
152 if self.is_prio(right, index) {
153 Some(right)
154 }
155 else if self.is_prio(left, index) {
156 Some(left)
157 }
158 else {
159 None
160 }
161 }
162 }
163 else {
164 if self.is_prio(left, index) {
165 Some(left)
166 }
167 else {
168 None
169 }
170 };
171 if let Some(result) = result {
172 self.tree.swap(result, index);
173 index = result;
174 }
175 else {
176 break;
177 }
178 }
179 }
180
181 pub fn is_prio(&self, lhs: usize, rhs: usize) -> bool {
183 assert!(lhs < self.len());
184 assert!(rhs < self.len());
185 assert!(lhs != rhs);
186 (self.prio)(&self[lhs], &self[rhs])
187 }
188
189 pub fn parent(&self, index: usize) -> Option<usize> {
191 assert!(index < self.len());
192 match index {
193 0 => None,
194 n => Some((n + 1) / 2 - 1),
195 }
196 }
197
198 pub fn childs(&self, index: usize) -> Option<(usize, Option<usize>)> {
200 let right = (index + 1) * 2;
201 let left = right - 1;
202 match (left < self.len(), right < self.len()) {
203 ( true, true) => Some((left, Some(right))),
204 ( true, false) => Some((left, None)),
205 (false, _) => None,
206 }
207 }
208
209 pub fn unchecked_mut(&mut self) -> &mut Vec<T> {
211 &mut self.tree
212 }
213
214 pub fn checked_mut(&mut self) -> CheckedMut<T> {
216 CheckedMut{ inner: self }
217 }
218
219 pub fn check_consistency(&self) -> bool {
221 (1..self.len()).all(|i| self.is_prio(self.parent(i).unwrap(), i))
222 }
223
224 pub fn restore_consistency(&mut self) {
226 for i in 1..self.len() {
227 self.bubble_up(i);
228 }
229 }
230
231 pub fn from_vec(vec: Vec<T>, prio: fn(&T, &T)->bool) -> Self {
234 let mut queue = Self {
235 prio,
236 tree: vec,
237 };
238 queue.restore_consistency();
239 queue
240 }
241
242 pub fn from_vec_checked(vec: Vec<T>, prio: fn(&T, &T)->bool) -> Self {
244 let queue = Self {
245 prio,
246 tree: vec,
247 };
248 assert!(queue.check_consistency());
249 queue
250 }
251
252 pub fn from_vec_unchecked(vec: Vec<T>, prio: fn(&T, &T)->bool) -> Self {
254 Self {
255 prio,
256 tree: vec,
257 }
258 }
259
260 pub fn from_iter<I: IntoIterator<Item=T>>(iter: I, prio: fn(&T, &T)->bool) -> Self {
262 Self::from_vec(iter.into_iter().collect(), prio)
263 }
264}
265
266pub struct CheckedMut<'a, T> {
267 inner: &'a mut PrioQueue<T>,
268}
269impl<'a, T> std::ops::Deref for CheckedMut<'a, T> {
270 type Target = Vec<T>;
271 fn deref(&self) -> &Self::Target {
272 &self.inner.tree
273 }
274}
275impl<'a, T> std::ops::DerefMut for CheckedMut<'a, T> {
276 fn deref_mut(&mut self) -> &mut Self::Target {
277 &mut self.inner.tree
278 }
279}
280impl<'a, T> Drop for CheckedMut<'a, T> {
281 fn drop(&mut self) {
282 assert!(self.inner.check_consistency());
283 }
284}
285
286impl<T: fmt::Debug> fmt::Debug for PrioQueue<T> {
287 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
288 self.tree.fmt(f)
289 }
290}
291impl<T: fmt::Display> fmt::Display for PrioQueue<T> {
292 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
293 let width = f.width().unwrap_or(3);
294 let len = (self.len() + 1).next_power_of_two();
295 let pow = len.trailing_zeros() as usize;
296 let wl = (width - 1) / 2;
297 let wr = (width - 1) - wl;
298 for i in 0..pow {
299 let span = (1 << (pow - 1 - i)) - 1;
300 for j in 0..(1 << i) {
301 let elem = (1 << i) - 1 + j;
302 let childs = self.childs(elem);
303 match childs {
304 None => {
305 write!(f, "{: >1$}", "", width * span)?;
306 if elem < self.len() {
307 write!(f, "{: ^1$}", self[elem], width)?;
308 }
309 else {
310 write!(f, "{: >1$}", "", width)?;
311 }
312 write!(f, "{: >1$}", "", width * span)?;
313 }
314 Some((_, right)) => {
315 write!(f, "{: >1$}", "", width * (span / 2) + wl)?;
316 write!(f, "╭")?;
317 write!(f, "{:─>1$}", "", width * (span / 2) + wr)?;
318 write!(f, "{:─^1$}", self[elem], width)?;
319 if let Some(_) = right {
320 write!(f, "{:─>1$}", "", width * (span / 2) + wl)?;
321 write!(f, "╮")?;
322 write!(f, "{: >1$}", "", width * (span / 2) + wr)?;
323 }
324 else {
325 write!(f, "{: >1$}", "", width * span)?;
326 }
327 }
328 }
329 write!(f, "{: >1$}", "", width)?;
330 }
331 writeln!(f, )?;
332 }
333 Ok(())
334 }
335}
336
337impl<T> std::ops::Deref for PrioQueue<T> {
338 type Target = [T];
339 fn deref(&self) -> &Self::Target {
340 &self.tree
341 }
342}
343
344pub struct Drain<'a, T> {
345 inner: &'a mut PrioQueue<T>,
346}
347impl<'a, T> Iterator for Drain<'a, T> {
348 type Item = T;
349 fn next(&mut self) -> Option<Self::Item> {
350 self.inner.pop()
351 }
352}
353
354pub struct IntoIter<T> {
355 inner: PrioQueue<T>,
356}
357impl<T> Iterator for IntoIter<T> {
358 type Item = T;
359 fn next(&mut self) -> Option<Self::Item> {
360 self.inner.pop()
361 }
362}
363
364impl<T> IntoIterator for PrioQueue<T> {
365 type Item = T;
366 type IntoIter = IntoIter<T>;
367 fn into_iter(self) -> Self::IntoIter {
368 IntoIter{
369 inner: self
370 }
371 }
372}
373
374impl<T> Extend<T> for PrioQueue<T> {
375 fn extend<I>(&mut self, iter: I)
376 where I: IntoIterator<Item = T>
377 {
378 for elem in iter {
379 self.push(elem);
380 }
381 }
382}
383
384impl<T: PartialOrd> std::iter::FromIterator<T> for PrioQueue<T> {
385 fn from_iter<I>(iter: I) -> Self
386 where I: IntoIterator<Item = T>
387 {
388 let mut queue = Self::new(|l, r| l < r);
389 queue.extend(iter);
390 queue
391 }
392}
393
394#[cfg(test)]
395mod tests {
396 use super::*;
397 #[test]
398 fn sorts() {
399 use rand::{Rng, SeedableRng, rngs::SmallRng};
400 let mut rng = SmallRng::seed_from_u64(9320154);
401 for _i in 0..100 {
402 let len = rng.gen_range(0..128);
403 let mut values = Vec::with_capacity(len);
405 for _ in 0..len {
406 values.push(rng.gen_range(0..100));
407 }
408 let queue: PrioQueue<_> = values.iter().copied().collect();
409 let result: Vec<_> = queue.into_iter().collect();
411 values.sort();
412 assert_eq!(values, result);
413 }
414 }
415 #[test]
416 fn remove() {
417 use rand::{Rng, SeedableRng, rngs::SmallRng};
418 let mut rng = SmallRng::seed_from_u64(885301);
419 for _i in 0..100 {
420 let len = rng.gen_range(0..128);
421 let remove = rng.gen_range(0..=len);
422 let mut values = Vec::with_capacity(len);
424 for _ in 0..len {
425 values.push(rng.gen_range(0..100));
426 }
427 let mut queue: PrioQueue<_> = values.iter().copied().collect();
428 for _ in 0..remove {
430 let index = rng.gen_range(0..values.len());
431 let value = values.swap_remove(index);
432 let index = queue.iter().position(|&e| e == value).unwrap();
433 let removed = queue.remove(index);
434 assert_eq!(value, removed);
435 }
436 let result: Vec<_> = queue.into_iter().collect();
438 values.sort();
439 assert_eq!(values, result);
440 }
441 }
442
443 #[test]
444 fn retain() {
445 use rand::{Rng, SeedableRng, rngs::SmallRng};
446 let mut rng = SmallRng::seed_from_u64(340712856);
447 for _i in 0..100 {
448 let len = rng.gen_range(0..128);
449 let factor = rng.gen_range(1..6);
450 let mut values = Vec::with_capacity(len);
452 for _ in 0..len {
453 values.push(rng.gen_range(0..100));
454 }
455 let mut queue: PrioQueue<_> = values.iter().copied().collect();
456 queue.retain(|&e| e % factor != 0);
458 values.retain(|&e| e % factor != 0);
459 let result: Vec<_> = queue.into_iter().collect();
461 values.sort();
462 assert_eq!(values, result);
463 }
464 }
465
466 #[test]
467 #[should_panic]
468 fn checked_bad_mut() {
469 let mut queue = PrioQueue::new(|l, r| l < r);
470 queue.push(1);
471 queue.checked_mut().push(0);
472 }
473
474 #[test]
475 fn unchecked_bad_mut() {
476 use rand::{Rng, SeedableRng, rngs::SmallRng};
477 use std::ops::RangeInclusive;
478
479 fn test(len: usize, values: RangeInclusive<i32>, remove: usize, mut rng: impl Rng) {
480 assert!(remove <= len);
481 let mut vec = Vec::with_capacity(len);
482 for _ in 0..len {
483 vec.push(rng.gen_range(values.clone()));
484 }
485 let mut queue: PrioQueue<_> = vec.iter().copied().collect();
486 let mut removed = {
487 let tmp = queue.unchecked_mut();
488 let mut removed = Vec::with_capacity(remove);
489 for _ in 0..remove {
490 removed.push(tmp.remove(rng.gen_range(0..tmp.len())));
491 }
492 removed
493 };
494 assert_eq!(removed.len(), remove);
495 assert_eq!(queue.len(), len - remove);
496 removed.extend(queue);
497 removed.sort();
498 vec.sort();
499 assert_eq!(removed, vec);
500 }
501 let mut rng = SmallRng::seed_from_u64(150738);
502 for _i in 0..100 {
503 let len = rng.gen_range(0..100);
504 test(len, 0..=rng.gen_range(0..100), rng.gen_range(0..=len), &mut rng);
505 }
506 }
507}