1#![warn(rust_2018_idioms)]
20use core::cmp::Ordering;
21
22pub fn make_heap<T: PartialOrd>(slice: &mut [T]) {
37 make_heap_with(slice, T::partial_cmp)
38}
39
40pub fn make_heap_with<T>(slice: &mut [T], pred: fn(&T, &T) -> Option<Ordering>) {
55 let n = slice.len();
56 for i in (0..=((n - 1) / 2)).rev() {
57 bubble_down(slice, i, pred);
58 }
59}
60
61pub fn make_heap_iter<T: PartialOrd>(slice: &mut [T]) -> HeapIterator<'_, T> {
72 make_heap(slice);
73 HeapIterator { heap: slice }
74}
75
76pub fn make_heap_iter_with<T>(
87 slice: &mut [T],
88 pred: fn(&T, &T) -> Option<Ordering>,
89) -> PredHeapIterator<'_, T> {
90 make_heap_with(slice, pred);
91 PredHeapIterator { heap: slice, pred }
92}
93
94pub fn push_heap<T: PartialOrd>(slice: &mut [T]) {
117 bubble_up(slice, T::partial_cmp);
118}
119
120pub fn push_heap_with<T>(slice: &mut [T], pred: fn(&T, &T) -> Option<Ordering>) {
143 bubble_up(slice, pred);
144}
145
146pub fn pop_heap<T: PartialOrd>(slice: &mut [T]) {
169 let n = slice.len();
170 if n > 1 {
171 slice.swap(0, n - 1);
172 bubble_down(&mut slice[0..n - 1], 0, T::partial_cmp);
173 }
174}
175pub fn pop_heap_with<T>(slice: &mut [T], pred: fn(&T, &T) -> Option<Ordering>) {
198 let n = slice.len();
199 if n > 1 {
200 slice.swap(0, n - 1);
201 bubble_down(&mut slice[0..n - 1], 0, pred);
202 }
203}
204
205pub fn peek_heap<T>(slice: &mut [T]) -> Option<&T> {
218 let n = slice.len();
219 if n > 0 {
220 Some(&slice[0])
221 } else {
222 None
223 }
224}
225
226fn pred_greater<T>(pred: fn(&T, &T) -> Option<Ordering>, lhs: &T, rhs: &T) -> bool {
227 pred(lhs, rhs) == Some(Ordering::Greater)
228}
229
230fn bubble_up<T>(slice: &mut [T], pred: fn(&T, &T) -> Option<Ordering>) {
231 let n = slice.len();
232 let mut i = n;
233 let mut p = i / 2;
234 while p > 0 && (pred_greater(pred, &slice[i - 1], &slice[p - 1])) {
235 slice.swap(p - 1, i - 1);
236 i = p;
237 p = i / 2;
238 }
239}
240
241fn bubble_down<T>(slice: &mut [T], index: usize, pred: fn(&T, &T) -> Option<Ordering>) {
242 let n = slice.len();
243 let mut i = index;
244 let mut l = i * 2 + 1;
245 let mut r = i * 2 + 2;
246
247 if r < n && pred_greater(pred, &slice[r], &slice[l]) {
248 l = r;
249 }
250 while l < n && pred_greater(pred, &slice[l], &slice[i]) {
253 slice.swap(i, l);
254 i = l;
255 l = i * 2 + 1;
256 r = i * 2 + 2;
257 if r < n && pred_greater(pred, &slice[r], &slice[l]) {
258 l = r;
259 }
260 }
261}
262
263#[derive(Debug)]
283pub struct HeapIterator<'a, T: PartialOrd> {
284 heap: &'a mut [T],
285}
286
287impl<'a, T: PartialOrd> core::iter::Iterator for HeapIterator<'a, T> {
288 type Item = &'a mut T;
289
290 fn next(&mut self) -> Option<Self::Item> {
291 let n = self.heap.len();
292 if n > 0 {
293 pop_heap(self.heap);
294
295 unsafe {
296 let old = core::ptr::read(&self.heap);
297 let (left, right) = old.split_at_mut(n - 1);
298 core::ptr::write(&mut self.heap, left);
299 assert_eq!(right.len(), 1);
300
301 Some(&mut right[0])
302 }
303 } else {
304 None
305 }
306 }
307
308 fn size_hint(&self) -> (usize, Option<usize>) {
309 (self.heap.len(), Some(self.heap.len()))
310 }
311}
312
313pub struct PredHeapIterator<'a, T> {
335 heap: &'a mut [T],
336 pred: fn(&T, &T) -> Option<Ordering>,
337}
338
339impl<'a, T> core::iter::Iterator for PredHeapIterator<'a, T> {
340 type Item = &'a mut T;
341
342 fn next(&mut self) -> Option<Self::Item> {
343 let n = self.heap.len();
344 if n > 0 {
345 pop_heap_with(self.heap, self.pred);
346
347 unsafe {
348 let old = core::ptr::read(&self.heap);
349 let (left, right) = old.split_at_mut(n - 1);
350 core::ptr::write(&mut self.heap, left);
351 assert_eq!(right.len(), 1);
352
353 Some(&mut right[0])
354 }
355 } else {
356 None
357 }
358 }
359
360 fn size_hint(&self) -> (usize, Option<usize>) {
361 (self.heap.len(), Some(self.heap.len()))
362 }
363}
364
365#[cfg(test)]
366mod tests {
367
368 use super::*;
369
370 #[test]
371 fn test_peek_heap() {
372 let mut arr = [2];
373 assert_eq!(peek_heap(&mut arr), Some(&2));
374 let mut empty = [0; 0];
375 assert_eq!(peek_heap(&mut empty), None);
376 }
377
378 #[test]
379 fn test_make_heap() {
380 let mut arr = [5, 7, 9];
381 make_heap(&mut arr);
382 assert_eq!(arr[0], 9);
383 assert_eq!(peek_heap(&mut arr), Some(&9));
384 }
385
386 #[test]
387 fn test_make_heap_with() {
388 let mut arr = [5, 7, 9];
389 make_heap_with(&mut arr, |lhs, rhs| rhs.partial_cmp(lhs));
390 assert_eq!(arr[0], 5);
391 assert_eq!(peek_heap(&mut arr), Some(&5));
392 }
393
394 #[test]
395 fn test_push_heap() {
396 let mut vec = vec![5, 7, 9];
397 make_heap(&mut vec);
398 assert_eq!(peek_heap(&mut vec), Some(&9));
399
400 vec.push(8);
401 push_heap(&mut vec);
402 assert_eq!(peek_heap(&mut vec), Some(&9));
403
404 vec.push(10);
405 push_heap(&mut vec);
406 assert_eq!(peek_heap(&mut vec), Some(&10));
407 }
408
409 #[test]
410 fn test_push_heap_with() {
411 let mut vec = vec![5, 7, 9];
412 let pred: fn(&i32, &i32) -> Option<Ordering> = |lhs, rhs| rhs.partial_cmp(lhs);
413 make_heap_with(&mut vec, pred);
414 assert_eq!(peek_heap(&mut vec), Some(&5));
415
416 vec.push(8);
417 push_heap_with(&mut vec, pred);
418 assert_eq!(peek_heap(&mut vec), Some(&5));
419
420 vec.push(3);
421 push_heap_with(&mut vec, pred);
422 assert_eq!(peek_heap(&mut vec), Some(&3));
423 }
424
425 #[test]
426 fn test_pop_heap() {
427 let mut vec = vec![5, 7, 9];
428 make_heap(&mut vec);
429 assert_eq!(peek_heap(&mut vec), Some(&9));
430
431 pop_heap(&mut vec);
432 assert_eq!(vec.pop(), Some(9));
433
434 pop_heap(&mut vec);
435 assert_eq!(vec.pop(), Some(7));
436
437 pop_heap(&mut vec);
438 assert_eq!(vec.pop(), Some(5));
439 }
440
441 #[test]
442 fn test_pop_heap_with() {
443 let mut vec = vec![5, 7, 9];
444 let pred: fn(&i32, &i32) -> Option<Ordering> = |lhs, rhs| rhs.partial_cmp(lhs);
445 make_heap_with(&mut vec, pred);
446 assert_eq!(peek_heap(&mut vec), Some(&5));
447
448 pop_heap_with(&mut vec, pred);
449 assert_eq!(vec.pop(), Some(5));
450
451 pop_heap_with(&mut vec, pred);
452 assert_eq!(vec.pop(), Some(7));
453
454 pop_heap_with(&mut vec, pred);
455 assert_eq!(vec.pop(), Some(9));
456 }
457
458 #[test]
459 fn test_heap_iterator_next_value() {
460 let mut vec = vec![5, 7, 9];
461 let mut iter = make_heap_iter(&mut vec);
462
463 assert_eq!(iter.next().cloned(), Some(9));
464 assert_eq!(iter.next().cloned(), Some(7));
465 assert_eq!(iter.next().cloned(), Some(5));
466 }
467
468 #[test]
469 fn test_heap_iterator_sorted() {
470 let mut vec = vec![1, 9, 2, 8, 3, 7];
471 let iter = make_heap_iter(&mut vec);
472 for _ in iter {}
473 assert_eq!(vec, vec![1, 2, 3, 7, 8, 9]);
474 }
475
476 #[test]
477 fn test_heap_iterator_mut() {
478 let mut vec = vec![1, 2, 3, 4, 5, 6];
479 let iter = make_heap_iter(&mut vec);
480 iter.for_each(|i| {
481 if *i % 2 == 0 {
482 *i = 0
483 }
484 });
485
486 assert_eq!(vec, vec![1, 0, 3, 0, 5, 0]);
487 }
488
489 #[test]
490 fn test_pred_heap_iterator_sorted() {
491 let pred: fn(&i32, &i32) -> Option<Ordering> = |lhs, rhs| rhs.partial_cmp(lhs);
492 let mut vec = vec![1, 9, 2, 8, 3, 7];
493 let iter = make_heap_iter_with(&mut vec, pred);
494 for _ in iter {}
495 assert_eq!(vec, vec![9, 8, 7, 3, 2, 1]);
496 }
497
498 #[test]
499 fn test_pred_heap_iterator_mut() {
500 let pred: fn(&i32, &i32) -> Option<Ordering> = |lhs, rhs| rhs.partial_cmp(lhs);
501 let mut vec = vec![1, 2, 3, 4, 5, 6];
502 let iter = make_heap_iter_with(&mut vec, pred);
503 iter.for_each(|i| {
504 if *i % 2 == 1 {
505 *i = 0
506 }
507 });
508
509 assert_eq!(vec, vec![6, 0, 4, 0, 2, 0]);
510 }
511}