1pub struct SkewHeap<T> {
2 root: Link<T>,
3 len: usize,
4}
5
6type Link<T> = Option<Box<Node<T>>>;
7
8struct Node<T> {
9 elem: T,
10 left: Link<T>,
11 right: Link<T>,
12}
13
14impl<T> Node<T> {
15 pub fn new(elem: T) -> Self { Self { elem, left: None, right: None } }
16}
17
18impl<T: Ord> SkewHeap<T> {
19 pub fn new() -> Self { SkewHeap { root: None, len: 0 } }
20
21 pub fn len(&self) -> usize { self.len }
22 pub fn is_empty(&self) -> bool { self.len == 0 }
23 pub fn clear(&mut self) { while self.pop().is_some() {} }
24
25 pub fn peek(&self) -> Option<&T> {
26 self.root.as_ref().map(|node| &node.elem)
27 }
28
29 pub fn peek_mut(&mut self) -> Option<PeekMut<'_, T>> {
30 if self.is_empty() {
31 None
32 } else {
33 Some(PeekMut { heap: self, tainted: false })
34 }
35 }
36
37 pub fn push(&mut self, elem: T) {
38 self.meld(Self { root: Some(Box::new(Node::new(elem))), len: 1 });
39 }
40
41 pub fn pop(&mut self) -> Option<T> {
42 self.root.take().map(|node| {
43 self.len -= 1;
44 self.root = Self::meld_internal(node.left, node.right);
45 node.elem
46 })
47 }
48
49 pub fn meld(&mut self, other: Self) {
50 self.len += other.len;
51 self.root = Self::meld_internal(self.root.take(), other.root);
52 }
53
54 fn meld_internal(left: Link<T>, right: Link<T>) -> Link<T> {
55 match (left, right) {
56 (left, None) => left,
57 (None, right) => right,
58 (Some(mut left), Some(right)) if left.elem >= right.elem => {
59 std::mem::swap(&mut left.left, &mut left.right);
60 left.left = Self::meld_internal(left.left.take(), Some(right));
61 Some(left)
62 }
63 (left, right) => Self::meld_internal(right, left),
64 }
65 }
66
67 fn fix_root(&mut self) {
68 let root = &self.root.as_ref().unwrap().elem;
69 let left = &self.root.as_ref().unwrap().left;
70 let right = &self.root.as_ref().unwrap().right;
71 if left.as_ref().map(|left| &left.elem > root).unwrap_or(false)
72 || right.as_ref().map(|right| &right.elem > root).unwrap_or(false)
73 {
74 let tmp = self.pop().unwrap();
75 self.push(tmp);
76 }
77 }
78}
79
80impl<T> SkewHeap<T> {
81 #[cfg(test)]
82 fn push_with_dir(&mut self, elem: T, dir: &[bool]) {
83 let mut from = &mut self.root;
84 for &is_right in dir.iter().chain(std::iter::once(&false)) {
85 if let Some(v) = from {
86 from = if is_right { &mut v.right } else { &mut v.left };
87 } else if from.is_none() {
88 *from = Some(Box::new(Node::new(elem)));
89 return;
90 }
91 }
92 }
93
94 #[cfg(test)]
95 fn in_order(&self) -> impl Iterator<Item = &T> {
96 fn dfs<'a, T>(v: &'a Link<T>, vec: &mut Vec<&'a T>) {
97 let v = match v {
98 Some(v) => v,
99 None => return,
100 };
101 dfs(&v.left, vec);
102 vec.push(&v.elem);
103 dfs(&v.right, vec);
104 }
105
106 let mut res = vec![];
107 dfs(&self.root, &mut res);
108 res.into_iter()
109 }
110
111 fn bfs_order(&self) -> impl Iterator<Item = (&T, Option<&T>, Option<&T>)> {
112 use std::collections::VecDeque;
113
114 let mut res = vec![];
115 let mut q = VecDeque::new();
116
117 q.extend(self.root.as_ref());
118 while let Some(v) = q.pop_front() {
119 let left = v.left.as_ref();
120 let right = v.right.as_ref();
121 res.push((&v.elem, left.map(|o| &o.elem), right.map(|o| &o.elem)));
122 q.extend(left.into_iter().chain(right));
123 }
124
125 res.into_iter()
126 }
127}
128
129impl<T: Ord> Extend<T> for SkewHeap<T> {
130 fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
131 for item in iter {
132 self.push(item);
133 }
134 }
135}
136
137use std::iter::FromIterator;
138
139impl<T: Ord> FromIterator<T> for SkewHeap<T> {
140 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
141 let mut heap = Self::new();
142 heap.extend(iter);
143 heap
144 }
145}
146
147pub struct IntoIter<T>(SkewHeap<T>);
148
149impl<T: Ord> IntoIterator for SkewHeap<T> {
150 type IntoIter = IntoIter<T>;
151 type Item = T;
152
153 fn into_iter(self) -> Self::IntoIter { IntoIter(self) }
154}
155
156impl<T: Ord> Iterator for IntoIter<T> {
157 type Item = T;
158
159 fn next(&mut self) -> Option<Self::Item> { self.0.pop() }
160
161 fn size_hint(&self) -> (usize, Option<usize>) {
162 (self.0.len, Some(self.0.len))
163 }
164}
165
166impl<T: Ord> ExactSizeIterator for IntoIter<T> {
167 fn len(&self) -> usize { self.0.len }
168}
169
170pub struct PeekMut<'a, T: 'a + Ord> {
171 heap: &'a mut SkewHeap<T>,
172 tainted: bool,
173}
174
175use std::ops::{Deref, DerefMut};
176
177impl<T: Ord> Drop for PeekMut<'_, T> {
178 fn drop(&mut self) {
179 if self.tainted {
180 self.heap.fix_root();
181 }
182 }
183}
184
185impl<T: Ord> Deref for PeekMut<'_, T> {
186 type Target = T;
187
188 fn deref(&self) -> &T { &self.heap.root.as_ref().unwrap().elem }
189}
190
191impl<T: Ord> DerefMut for PeekMut<'_, T> {
192 fn deref_mut(&mut self) -> &mut T {
193 self.tainted = true;
194 &mut self.heap.root.as_mut().unwrap().elem
195 }
196}
197
198impl<'a, T: Ord> PeekMut<'a, T> {
199 pub fn pop(mut self) -> T {
200 let value = self.heap.pop().unwrap();
201 self.tainted = false;
202 value
203 }
204}
205
206impl<T: Ord> Default for SkewHeap<T> {
207 fn default() -> Self { Self::new() }
208}
209
210use std::fmt;
211
212impl<T: fmt::Debug> fmt::Debug for SkewHeap<T> {
213 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
214 f.debug_list().entries(self.bfs_order().map(|(x, ..)| x)).finish()
215 }
216}
217
218#[cfg(test)]
219mod test {
220 use super::SkewHeap;
221
222 #[test]
223 fn push_with_dir() {
224 let mut tr = SkewHeap::new();
225 tr.push_with_dir(1, &[]);
226 tr.push_with_dir(4, &[false]);
227 tr.push_with_dir(23, &[true]);
228 tr.push_with_dir(63, &[false, false]);
229 tr.push_with_dir(24, &[false, true]);
230 tr.push_with_dir(44, &[true, false]);
231 tr.push_with_dir(28, &[true, true]);
232
233 assert_eq!(tr.in_order().copied().collect::<Vec<_>>(), [
234 63, 4, 24, 1, 44, 23, 28
235 ]);
236 }
237
238 #[test]
239 fn meld() {
240 let mut left = SkewHeap::new();
241 left.push_with_dir(-1, &[]);
242 left.push_with_dir(-4, &[false]);
243 left.push_with_dir(-23, &[true]);
244 left.push_with_dir(-63, &[false, false]);
245 left.push_with_dir(-24, &[false, true]);
246 left.push_with_dir(-44, &[true, false]);
247 left.push_with_dir(-28, &[true, true]);
248
249 assert_eq!(left.in_order().copied().collect::<Vec<_>>(), [
250 -63, -4, -24, -1, -44, -23, -28
251 ]);
252
253 let mut right = SkewHeap::new();
254 right.push_with_dir(-13, &[]);
255 right.push_with_dir(-17, &[false]);
256 right.push_with_dir(-99, &[true]);
257 right.push_with_dir(-57, &[false, false]);
258 right.push_with_dir(-49, &[false, true]);
259 right.push_with_dir(-105, &[true, false]);
260 right.push_with_dir(-201, &[true, true]);
261
262 assert_eq!(right.in_order().copied().collect::<Vec<_>>(), [
263 -57, -17, -49, -13, -105, -99, -201
264 ]);
265
266 left.meld(right);
267 let melded: Vec<_> = left
268 .bfs_order()
269 .map(|(&v, l, r)| (v, l.copied(), r.copied()))
270 .collect();
271 assert_eq!(melded, [
272 (-1, Some(-13), Some(-4)),
273 (-13, Some(-23), Some(-17)),
274 (-4, Some(-63), Some(-24)),
275 (-23, Some(-28), Some(-44)),
276 (-17, Some(-57), Some(-49)),
277 (-63, None, None),
278 (-24, None, None),
279 (-28, Some(-99), None),
280 (-44, None, None),
281 (-57, None, None),
282 (-49, None, None),
283 (-99, Some(-105), Some(-201)),
284 (-105, None, None),
285 (-201, None, None),
286 ]);
287 }
288
289 #[test]
290 fn heap_sort() {
291 let mut a = vec![2, 9, 7, 3, 1, 6, 3, 5, 4, 8];
292 let mut heap = SkewHeap::new();
293 heap.extend(a.iter().copied());
294 a.sort_unstable();
295 a.reverse();
296 let mut b = vec![];
297 while let Some(x) = heap.pop() {
298 b.push(x);
299 }
300 assert_eq!(a, b);
301
302 assert_eq!(heap.len(), 0);
303 assert_eq!(heap.pop(), None);
304 assert_eq!(heap.pop(), None);
305 assert_eq!(heap.len(), 0);
306 }
307
308 #[test]
309 fn into_iter() {
310 let heap: SkewHeap<_> =
311 [2, 5, 1, 3, 4, 6, 6, 1].iter().copied().collect();
312 assert_eq!(heap.len(), 8);
313
314 let mut iter = heap.into_iter();
315 assert_eq!(iter.size_hint(), (8, Some(8)));
316 assert_eq!(iter.len(), 8);
317 assert_eq!(iter.next(), Some(6));
318 assert_eq!(iter.size_hint(), (7, Some(7)));
319 assert_eq!(iter.len(), 7);
320 assert_eq!(iter.next(), Some(6));
321 assert_eq!(iter.next(), Some(5));
322 assert_eq!(iter.len(), 5);
323 assert_eq!(iter.next(), Some(4));
324 assert_eq!(iter.len(), 4);
325 assert_eq!(iter.next(), Some(3));
326 assert_eq!(iter.len(), 3);
327 assert_eq!(iter.next(), Some(2));
328 assert_eq!(iter.len(), 2);
329 assert_eq!(iter.next(), Some(1));
330 assert_eq!(iter.len(), 1);
331 assert_eq!(iter.next(), Some(1));
332 assert_eq!(iter.len(), 0);
333 assert_eq!(iter.next(), None);
334 assert_eq!(iter.len(), 0);
335 }
336
337 #[test]
338 fn peek() {
339 use std::cmp::Reverse;
340
341 let mut heap: SkewHeap<_> =
342 [2, 5, 3, 1, 6, 2].iter().map(|&x| Reverse(x)).collect();
343
344 assert_eq!(heap.peek(), Some(&Reverse(1)));
345 heap.peek_mut().unwrap().0 -= 1; assert_eq!(heap.peek(), Some(&Reverse(0)));
347 heap.peek_mut().unwrap().0 += 4; assert_eq!(heap.peek(), Some(&Reverse(2)));
349 assert_eq!(heap.peek_mut().unwrap().pop().0, 2); assert_eq!(heap.peek(), Some(&Reverse(2)));
351 assert_eq!(heap.peek_mut().unwrap().0, 2);
352 assert_eq!(heap.peek_mut().unwrap().pop().0, 2); assert_eq!(heap.peek(), Some(&Reverse(3)));
354 assert_eq!(heap.pop(), Some(Reverse(3))); assert_eq!(heap.peek(), Some(&Reverse(4)));
356
357 heap.peek_mut().unwrap().0 += 10; assert_eq!(heap.peek(), Some(&Reverse(5)));
359
360 heap.push(Reverse(8)); assert_eq!(heap.peek(), Some(&Reverse(5)));
362 assert_eq!(heap.pop(), Some(Reverse(5))); assert_eq!(heap.pop(), Some(Reverse(6))); assert_eq!(heap.pop(), Some(Reverse(8))); assert_eq!(heap.peek_mut().unwrap().pop().0, 14);
366 assert!(heap.peek_mut().is_none());
367 assert!(heap.peek().is_none());
368 }
369}