competitive_library/structure/
skew_heap.rs1use std::mem::swap;
4#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
5pub struct Heap<T: Ord + Clone> {
6 pub value: T,
7 pub left: Option<Box<Heap<T>>>,
8 pub right: Option<Box<Heap<T>>>,
9}
10
11impl<T: Ord + Clone> Heap<T> {
12 pub fn new(value: T) -> Option<Box<Heap<T>>> {
13 Some(Box::new(Heap {
14 value,
15 left: None,
16 right: None,
17 }))
18 }
19}
20#[derive(Default, Clone)]
21pub struct SkewHeap<T: Ord + Clone> {
22 node: Option<Box<Heap<T>>>,
23}
24impl<T: Ord + Clone> SkewHeap<T> {
25 pub fn new() -> Self {
26 Self { node: None }
27 }
28
29 #[inline]
30 pub fn push(&mut self, value: T) {
31 SkewHeap::merge(&mut self.node, Heap::new(value));
32 }
33 #[inline]
34 pub fn top(&self) -> Option<T> {
35 Some(self.node.as_ref()?.value.clone())
36 }
37 #[inline]
38 pub fn pop(&mut self) -> Option<T> {
39 let value = self.top()?;
40
41 let (mut left, right) = {
42 let mut tmp = self.node.take().unwrap();
43 (tmp.left.take(), tmp.right.take())
44 };
45 SkewHeap::merge(&mut left, right);
46 swap(&mut self.node, &mut left);
47
48 Some(value)
49 }
50
51 #[inline]
52 pub fn merge(a: &mut Option<Box<Heap<T>>>, mut b: Option<Box<Heap<T>>>) {
53 if a.is_none() {
54 swap(a, &mut b);
55 return;
56 }
57 if b.is_none() {
58 return;
59 }
60 if a > &mut b {
61 swap(a, &mut b);
62 }
63 SkewHeap::merge(&mut a.as_mut().unwrap().right, b);
64
65 let tmp = a.as_mut().unwrap();
66 swap(&mut tmp.left, &mut tmp.right);
67 }
68}
69
70#[cfg(test)]
71mod tests {
72 use super::*;
73 #[test]
74 fn test_heap() {
75 let mut a = vec![SkewHeap::new(); 5];
76
77 for i in 0..30 {
78 a[i % 5].push(i);
79 }
80
81 for (i, e) in a.iter().enumerate() {
82 assert_eq!(e.top().unwrap(), i);
83 }
84
85 for i in 1..5 {
86 let buff = a[i].node.take();
87 SkewHeap::merge(&mut a[0].node, buff);
88 }
89
90 for i in 0..30 {
91 assert_eq!(a[0].pop().unwrap(), i);
92 }
93 }
94}