1use std::{collections::VecDeque, ops::SubAssign, ptr::NonNull};
2
3#[derive(Debug)]
5pub struct PairingHeap<K, P> {
6 root: Option<NonNull<Inner<K, P>>>,
7 len: usize,
8}
9
10impl<K, P> PairingHeap<K, P> {
11 #[inline]
13 pub fn new() -> Self {
14 Self::default()
15 }
16
17 #[inline]
19 pub fn len(&self) -> usize {
20 self.len
21 }
22
23 #[inline]
25 pub fn is_empty(&self) -> bool {
26 self.len == 0
27 }
28
29 #[inline]
31 pub fn find_min(&self) -> Option<(&K, &P)> {
32 match self.root {
33 Some(node) => unsafe {
34 let r = node.as_ref();
35 Some((&r.key, &r.prio))
36 },
37 None => None,
38 }
39 }
40
41 #[inline]
47 pub fn merge(mut self, mut other: Self) -> Self
48 where
49 P: PartialOrd,
50 {
51 let len = self.len() + other.len();
52 let root = Self::merge_nodes(self.root, other.root);
53
54 self.root = None;
55 other.root = None;
56
57 Self { root, len }
58 }
59
60 #[inline]
61 fn merge_nodes(
62 node1: Option<NonNull<Inner<K, P>>>,
63 node2: Option<NonNull<Inner<K, P>>>,
64 ) -> Option<NonNull<Inner<K, P>>>
65 where
66 P: PartialOrd,
67 {
68 match (node1, node2) {
69 (Some(root1), Some(root2)) => unsafe {
70 let root = if root1.as_ref().prio < root2.as_ref().prio {
71 Self::meld(root1, root2)
72 } else {
73 Self::meld(root2, root1)
74 };
75 Some(root)
76 },
77 (Some(_), None) => node1,
78 (None, Some(_)) => node2,
79 _ => node1,
80 }
81 }
82
83 #[inline(always)]
84 unsafe fn meld(
85 node1: NonNull<Inner<K, P>>,
86 node2: NonNull<Inner<K, P>>,
87 ) -> NonNull<Inner<K, P>> {
88 (*node2.as_ptr()).parent = Some(node1);
89 (*node2.as_ptr()).right = node1.as_ref().left;
90 (*node1.as_ptr()).left = Some(node2);
91 node1
92 }
93
94 #[inline]
96 pub fn insert(&mut self, key: K, prio: P)
97 where
98 P: PartialOrd,
99 {
100 self.insert2(key, prio);
101 }
102
103 #[inline]
105 pub(crate) fn insert2(&mut self, key: K, prio: P) -> HeapElmt<K, P>
106 where
107 P: PartialOrd,
108 {
109 let node = NonNull::new(Box::leak(Box::new(Inner::new(key, prio))));
110
111 self.root = Self::merge_nodes(self.root, node);
112 self.len += 1;
113
114 HeapElmt { inner: node }
115 }
116
117 pub fn decrease_prio(&mut self, key: &K, delta: P)
119 where
120 K: PartialEq,
121 P: PartialOrd + SubAssign,
122 {
123 if let Some(root) = self.root {
124 unsafe {
125 if &root.as_ref().key == key {
126 (*root.as_ptr()).prio -= delta;
127 return;
128 }
129
130 let mut targ = None;
131 let mut prev = None;
132 let mut tmp_nodes = VecDeque::with_capacity(self.len << 2);
133 let mut traverse = root.as_ref().left;
134
135 while let Some(node) = traverse {
136 if &node.as_ref().key == key {
137 targ = traverse;
138 break;
139 }
140
141 prev = traverse;
142 tmp_nodes.push_back(traverse);
143
144 if node.as_ref().right.is_some() {
145 traverse = node.as_ref().right;
146 } else {
147 while let Some(front) = tmp_nodes.pop_front() {
148 traverse = front.unwrap().as_ref().left;
149 if traverse.is_some() {
150 break;
151 }
152 }
153 }
154 }
155
156 if let Some(node) = targ {
157 let parent = node.as_ref().parent.unwrap();
159 (*node.as_ptr()).prio -= delta;
160
161 if parent.as_ref().prio < node.as_ref().prio {
162 return;
163 }
164
165 if parent.as_ref().left == targ {
166 (*parent.as_ptr()).left = node.as_ref().right;
167 }
168
169 if let Some(prev_node) = prev {
170 if prev_node.as_ref().right == targ {
171 (*prev_node.as_ptr()).right = node.as_ref().right;
172 }
173 }
174
175 (*node.as_ptr()).parent = None;
176 (*node.as_ptr()).right = None;
177
178 self.root = Self::merge_nodes(self.root, targ);
179 }
180 }
181 }
182 }
183
184 pub(crate) fn update_prio(&mut self, node: &HeapElmt<K, P>, new_prio: P)
186 where
187 P: PartialOrd,
188 {
189 unsafe {
190 self.update(node.inner, new_prio);
191 }
192 }
193
194 unsafe fn update(&mut self, targ: Option<NonNull<Inner<K, P>>>, new_prio: P)
195 where
196 P: PartialOrd,
197 {
198 if let Some(node) = targ {
199 match node.as_ref().parent {
200 Some(parent) => {
201 let mut prev = parent.as_ref().left;
202
203 while let Some(prev_node) = prev {
204 if prev_node.as_ref().right == targ {
205 break;
206 } else {
207 prev = prev_node.as_ref().right;
208 }
209 }
210
211 (*node.as_ptr()).prio = new_prio;
212
213 if parent.as_ref().prio < node.as_ref().prio {
214 return;
215 }
216
217 if parent.as_ref().left == targ {
218 (*parent.as_ptr()).left = node.as_ref().right;
219 }
220
221 if let Some(prev_node) = prev {
222 if prev_node.as_ref().right == targ {
223 (*prev_node.as_ptr()).right = node.as_ref().right;
224 }
225 }
226
227 (*node.as_ptr()).parent = None;
228 (*node.as_ptr()).right = None;
229
230 self.root = Self::merge_nodes(self.root, targ);
231 }
232 None => {
233 (*node.as_ptr()).prio = new_prio;
234 }
235 };
236 }
237 }
238
239 pub fn delete_min(&mut self) -> Option<(K, P)>
241 where
242 P: PartialOrd,
243 {
244 self.root.map(|root| unsafe {
245 self.len -= 1;
246 let mut targ = (*root.as_ptr()).left.take();
247 if targ.is_none() {
248 self.root = None;
249 } else {
250 let mut tmp_nodes = VecDeque::new();
252
253 while let Some(node) = targ {
255 (*node.as_ptr()).parent = None;
256 let right = (*node.as_ptr()).right.take();
257
258 let node_next = match right {
259 Some(node_right) => {
260 let next = (*node_right.as_ptr()).right.take();
261 (*node_right.as_ptr()).parent = None;
262 next
263 }
264 None => None,
265 };
266
267 tmp_nodes.push_back(Self::merge_nodes(Some(node), right));
268
269 targ = node_next;
270 }
271
272 let mut node = tmp_nodes.pop_back().unwrap();
276
277 while let Some(node_prev) = tmp_nodes.pop_back() {
278 node = Self::merge_nodes(node, node_prev);
279 }
280
281 self.root = node;
282 }
283 let node = Box::from_raw(root.as_ptr());
284 node.into_value()
285 })
286 }
287}
288
289impl<K, P> Default for PairingHeap<K, P> {
290 fn default() -> Self {
291 Self { root: None, len: 0 }
292 }
293}
294
295impl<K, P> Drop for PairingHeap<K, P> {
296 fn drop(&mut self) {
297 unsafe fn remove<K, P>(targ: Option<NonNull<Inner<K, P>>>) -> Option<NonNull<Inner<K, P>>> {
301 if let Some(node) = targ {
302 while let Some(left) = node.as_ref().left {
303 (*node.as_ptr()).left = remove(Some(left));
304 }
305
306 let sibling = (*node.as_ptr()).right.take();
307 (*node.as_ptr()).parent = None;
308 Box::from_raw(node.as_ptr());
309
310 sibling
311 } else {
312 None
313 }
314 }
315
316 unsafe {
317 remove(self.root);
318 }
319
320 self.root = None;
321 }
322}
323
324#[derive(Clone, Debug)]
325pub(crate) struct HeapElmt<K, P> {
326 inner: Option<NonNull<Inner<K, P>>>,
327}
328
329impl<K, P> HeapElmt<K, P> {
330 pub(crate) fn is_none(&self) -> bool {
331 self.inner.is_none()
332 }
333
334 pub(crate) fn none(&mut self) {
335 self.inner = None;
336 }
337}
338
339impl<K, P> Default for HeapElmt<K, P> {
340 fn default() -> Self {
341 Self { inner: None }
342 }
343}
344
345#[derive(Debug)]
346struct Inner<K, P> {
347 parent: Option<NonNull<Inner<K, P>>>,
349 left: Option<NonNull<Inner<K, P>>>,
351 right: Option<NonNull<Inner<K, P>>>,
353 key: K,
354 prio: P,
355}
356
357impl<K, P> Inner<K, P> {
358 fn new(key: K, prio: P) -> Self {
359 Self {
360 key,
361 prio,
362 parent: None,
363 left: None,
364 right: None,
365 }
366 }
367
368 fn into_value(self) -> (K, P) {
369 (self.key, self.prio)
370 }
371}