binomial_heap/
node.rs

1use std::mem;
2
3#[derive(Clone)]
4pub struct Node<T> {
5    item: T,
6    order: usize,
7    next: Option<Box<Node<T>>>,
8    child: Option<Box<Node<T>>>,
9}
10
11pub fn append<T: Ord>(root: &mut Box<Node<T>>, other: Option<Box<Node<T>>>) {
12    if let Some(other) = other {
13        merge(root, other);
14        coalesce(root);
15    }
16}
17
18pub fn push<T: Ord>(root: &mut Option<Box<Node<T>>>, item: T) {
19    let node = Some(Box::new(Node { item: item, order: 0, next: None, child: None }));
20
21    match *root {
22        None => *root = node,
23        Some(ref mut root) => append(root, node),
24    }
25}
26
27pub fn peek<T: Ord>(root: &Option<Box<Node<T>>>) -> Option<&T> {
28    root.as_ref().map(|mut max| {
29        let mut a = &max.next;
30
31        while let Some(ref b) = *a {
32            if b.item > max.item { max = b; }
33            a = &b.next;
34        }
35
36        &max.item
37    })
38}
39
40pub fn pop<T: Ord>(root: &mut Option<Box<Node<T>>>, len: &mut usize) -> Option<T> {
41    remove_max(root).map(|max| {
42        let max = *max;
43        let Node { item, child, order: _order, next: _next } = max;
44
45        match *root {
46            None => *root = child,
47            Some(ref mut root) => append(root, child),
48        }
49
50        *len -= 1;
51        item
52    })
53}
54
55pub fn iter<T>(root: &Option<Box<Node<T>>>, len: usize) -> Iter<T> {
56    debug_assert!(root.is_some() ^ (len == 0));
57    Iter { nodes: root.as_ref().map(|root| &**root).into_iter().collect(), len: len }
58}
59
60pub fn into_iter<T>(root: Option<Box<Node<T>>>, len: usize) -> IntoIter<T> {
61    debug_assert!(root.is_some() ^ (len == 0));
62    IntoIter { nodes: root.into_iter().collect(), len: len }
63}
64
65/// An iterator that yields references to the items in a `BinomialHeap` in arbitrary order.
66///
67/// Acquire through [`BinomialHeap::iter`](struct.BinomialHeap.html#method.iter).
68pub struct Iter<'a, T: 'a> {
69    nodes: Vec<&'a Node<T>>,
70    len: usize,
71}
72
73impl<'a, T> Clone for Iter<'a, T> {
74    fn clone(&self) -> Self {
75        Iter { nodes: self.nodes.clone(), len: self.len }
76    }
77}
78
79impl<'a, T> Iterator for Iter<'a, T> {
80    type Item = &'a T;
81
82    fn next(&mut self) -> Option<&'a T> {
83        self.nodes.pop().map(|node| {
84            self.len -= 1;
85
86            if let Some(ref next) = node.next { self.nodes.push(next); }
87            if let Some(ref child) = node.child { self.nodes.push(child); }
88
89            &node.item
90        })
91    }
92
93    fn size_hint(&self) -> (usize, Option<usize>) {
94        (self.len, Some(self.len))
95    }
96}
97
98impl<'a, T> ExactSizeIterator for Iter<'a, T> {
99    fn len(&self) -> usize {
100        self.len
101    }
102}
103
104/// An iterator that yields the items in a `BinomialHeap` in arbitrary order.
105///
106/// Acquire through [`IntoIterator::into_iter`](struct.BinomialHeap.html#method.into_iter).
107pub struct IntoIter<T> {
108    nodes: Vec<Box<Node<T>>>,
109    len: usize,
110}
111
112impl<T> Iterator for IntoIter<T> {
113    type Item = T;
114
115    fn next(&mut self) -> Option<T> {
116        self.nodes.pop().map(|node| {
117            self.len -= 1;
118
119            let node = *node;
120            let Node { item, next, child, order: _order } = node;
121
122            if let Some(next) = next { self.nodes.push(next); }
123            if let Some(child) = child { self.nodes.push(child); }
124
125            item
126        })
127    }
128
129    fn size_hint(&self) -> (usize, Option<usize>) {
130        (self.len, Some(self.len))
131    }
132}
133
134impl<T> ExactSizeIterator for IntoIter<T> {
135    fn len(&self) -> usize {
136        self.len
137    }
138}
139
140/// Merges the sibling list rooted at `b` into the sibling list rooted at `a` such that the
141/// resulting list is monotonically increasing by order.
142///
143/// The lists rooted at `a` and `b` must be monotonically increasing by order.
144///
145/// This method should always be followed by `coalesce(a)`.
146fn merge<T>(mut a: &mut Box<Node<T>>, mut b: Box<Node<T>>) {
147    loop {
148        let a_ = a;
149
150        if a_.order > b.order {
151            mem::swap(a_, &mut b);
152        }
153
154        match a_.next {
155            None => return a_.next = Some(b),
156            Some(ref mut next) => a = next,
157        }
158    }
159}
160
161/// Makes `b` a child of `a`.
162fn link<T: Ord>(a: &mut Node<T>, mut b: Box<Node<T>>) {
163    debug_assert!(a.order == b.order);
164    debug_assert!(b.next.is_none());
165    debug_assert!(a.item >= b.item);
166
167    b.next = a.child.take();
168    a.child = Some(b);
169    a.order += 1;
170}
171
172/// Coalesces nodes in the given sibling list in order to restore the binomial heap property that
173/// no two nodes in the list have the same order.
174///
175/// The list rooted at `a` must be monotonically increasing by order and its individual nodes must
176/// be valid max-heaps.
177///
178/// This method should always be preceded by `merge`.
179fn coalesce<T: Ord>(mut a: &mut Box<Node<T>>) {
180    enum Case {
181        A,
182        B,
183        C,
184    }
185
186    loop {
187        let a_ = a;
188
189        let case = match a_.next {
190            None => return,
191            Some(ref b) =>
192                if a_.order != b.order || b.next.as_ref().map_or(false, |c| c.order == b.order) {
193                    Case::A
194                } else if a_.item >= b.item {
195                    Case::B
196                } else {
197                    Case::C
198                },
199        };
200
201        match case {
202            Case::A => a = a_.next.as_mut().unwrap(),
203            Case::B => {
204                let mut b = a_.next.take().unwrap();
205                a_.next = b.next.take();
206                link(a_, b);
207
208                match a_.next {
209                    None => return,
210                    Some(ref mut c) => a = c,
211                }
212            }
213            Case::C => {
214                let mut b = a_.next.take().unwrap();
215                mem::swap(a_, &mut b);
216                link(a_, b);
217                a = a_;
218            }
219        }
220    }
221}
222
223/// Removes and returns the node with the maximum item from the sibling list rooted at `a`.
224fn remove_max<T: Ord>(mut a: &mut Option<Box<Node<T>>>) -> Option<Box<Node<T>>> {
225    a.take().map(|mut max| {
226        *a = max.next.take();
227
228        loop {
229            let a_ = a;
230
231            match *a_ {
232                None => return max,
233                Some(ref mut b) => {
234                    if b.item > max.item {
235                        max.next = b.next.take();
236                        mem::swap(&mut max, b);
237                    }
238                }
239            }
240
241            a = &mut a_.as_mut().unwrap().next;
242        }
243    })
244}