go_heap_rs/
lib.rs

1//! # Go Heap in Rust
2//!
3//! `go_heap_rs` implements the Go's [heap](https://golang.org/pkg/container/heap/) interface in Rust
4//! The heap it self is backed by another collection which it must implement the `Heap` trait for it
5//!
6//! # Advantages
7//! * More control over swap method
8//! * Added `fix` and `remove` methods
9//! * Full access to underlying data
10//!
11//! # Disadvantages
12//! * Must be backed by a collection like Vector
13//! * Not really easy to work with
14//! * Lack of some methods like `from`
15
16use std::marker::PhantomData;
17
18/// All types which you want to create heap from them must implement this trait
19///
20/// # Example of Min Heap
21/// ```
22/// use go_heap_rs::Heap;
23/// struct MinHeap(Vec<i32>);
24/// impl Heap<i32> for MinHeap {
25///     fn len(&self) -> usize {
26///         self.0.len()
27///     }
28///
29///     fn less(&self, i: usize, j: usize) -> bool {
30///         self.0[i] < self.0[j]
31///     }
32///
33///     fn swap(&mut self, i: usize, j: usize) {
34///         self.0.swap(i, j);
35///     }
36///
37///     fn push(&mut self, x: i32) {
38///         self.0.push(x);
39///     }
40///
41///     fn pop(&mut self) -> i32 {
42///         self.0.pop().expect("pop on an empty vec!")
43///     }
44///
45///     fn peak(&self) -> Option<&i32> {
46///         self.0.get(0)
47///     }
48/// }
49/// ```
50pub trait Heap<T> {
51    /// length must return the length of the heap
52    fn len(&self) -> usize;
53    /// Compares two elements of the heap at i and j index
54    /// It is guaranteed that the i and j are always valid
55    fn less(&self, i: usize, j: usize) -> bool;
56    /// This function must swap the i and j element in the heap array
57    /// It is guaranteed that the i and j are always valid
58    fn swap(&mut self, i: usize, j: usize);
59    /// push is just like push in vector. It should add x to the last of array
60    fn push(&mut self, x: T);
61    /// This method should remove the last element of array and return it
62    /// This function is guaranteed to be called when at least one element in available
63    fn pop(&mut self) -> T;
64    /// This method must return first element in your collection
65    fn peak(&self) -> Option<&T>;
66}
67
68/// A heap structure which holds a type which derives from Heap
69pub struct HeapType<T, E> where T: Heap<E> {
70    pub data: T,
71    #[doc(hidden)]
72    phantom: PhantomData<E>,
73}
74
75impl<T: Heap<E>, E> HeapType<T, E> {
76    /// Initialized a new heap from a Heap type
77    ///
78    /// # Arguments
79    ///
80    /// * `init`: The Heap type to be initialized
81    ///
82    /// returns: HeapType<T, E> which is your heap data structure
83    ///
84    /// # Examples
85    ///
86    /// ```
87    /// use go_heap_rs::{HeapType, MinHeap};
88    ///
89    /// let my_vec = MinHeap(vec![4, 3, 2, 1]); // see min heap implementation in Heap trait
90    /// let mut heap = HeapType::new(my_vec);
91    /// assert_eq!(heap.peak(), Some(&1));
92    /// ```
93    pub fn new(init: T) -> HeapType<T, E> where T: Heap<E> {
94        let mut data = HeapType {
95            data: init,
96            phantom: PhantomData,
97        };
98        // Init
99        let n = data.data.len();
100        if n != 0 {
101            for i in (0..=n / 2 - 1).rev() {
102                data.down(i, n);
103            }
104        }
105        data
106    }
107
108    /// Pushes an element into heap
109    ///
110    /// # Arguments
111    ///
112    /// * `x`: The element to push it into heap
113    pub fn push(&mut self, x: E) {
114        self.data.push(x);
115        self.up(self.data.len() - 1);
116    }
117
118    /// Removes the greatest item from the binary heap and returns it, or None if it is empty.
119    ///
120    /// returns E: The first element in list
121    pub fn pop(&mut self) -> Option<E> {
122        if self.data.len() == 0 { // empty heap
123            return None;
124        }
125        let n = self.data.len() - 1;
126        self.data.swap(0, n);
127        self.down(0, n);
128        Some(self.data.pop())
129    }
130
131    /// Removes an element from heap by it's index in it's underlying container
132    ///
133    /// # Arguments
134    ///
135    /// * `i`: The index to remove
136    ///
137    /// returns E: The element which as been removed
138    ///
139    /// # Panics
140    /// This method might panic (based on implementation of `swap`) if `i` is bigger than `len()`
141    ///
142    /// # Examples
143    ///
144    /// ```
145    /// use go_heap_rs::{HeapType, MinHeap};
146    ///
147    /// let my_vec = MinHeap(vec![1, 4, 3]);
148    /// let mut heap = HeapType::new(my_vec); // [1, 4, 3]
149    /// assert_eq!(heap.remove(1), 4);
150    /// assert_eq!(heap.pop(), Some(1));
151    /// assert_eq!(heap.pop(), Some(3));
152    /// assert_eq!(heap.pop(), None);
153    /// ```
154    pub fn remove(&mut self, i: usize) -> E {
155        let n = self.data.len() - 1;
156        if n != i {
157            self.data.swap(i, n);
158            if !self.down(i, n) {
159                self.up(i);
160            }
161        }
162        self.data.pop()
163    }
164
165
166    /// Fix re-establishes the heap ordering after the element at index i has changed its value.
167    /// Changing the value of the element at index i and then calling Fix is equivalent to,
168    /// but less expensive than, calling Remove(h, i) followed by a Push of the new value.
169    ///
170    /// # Arguments
171    ///
172    /// * `i`: The index to fix
173    ///
174    /// # Examples
175    ///
176    /// ```
177    /// use go_heap_rs::{HeapType, MinHeap};
178    ///
179    /// let my_vec = MinHeap(vec![10, 4, 3]);
180    /// let mut heap = HeapType::new(my_vec); // [3, 4, 10]
181    /// heap.data.0[1] = 0;
182    /// heap.fix(0);
183    /// assert_eq!(heap.pop(), Some(0));
184    /// assert_eq!(heap.pop(), Some(3));
185    /// assert_eq!(heap.pop(), Some(10));
186    /// assert_eq!(heap.pop(), None);
187    /// ```
188    pub fn fix(&mut self, i: usize) {
189        if !self.down(i, self.data.len()) {
190            self.up(i);
191        }
192    }
193
194    /// peak will return the top of heap if available
195    pub fn peak(&self) -> Option<&E> {
196        self.data.peak()
197    }
198
199    /// len will simply call `self.data.len()`
200    pub fn len(&self) -> usize {
201        self.data.len()
202    }
203
204    fn up(&mut self, mut j: usize) {
205        loop {
206            let i = (((j as isize) - 1) / 2) as usize; // parent
207            if i == j || !self.data.less(j, i) {
208                break;
209            }
210            self.data.swap(i, j);
211            j = i
212        }
213    }
214
215    fn down(&mut self, i0: usize, n: usize) -> bool {
216        let mut i = i0;
217        loop {
218            let j1: isize = (2 * i + 1) as isize;
219            if j1 >= n as isize || j1 < 0 { // j1 < 0 after int overflow
220                break;
221            }
222            let mut j = j1 as usize; // left child
223            let j2 = j1 as usize + 1;
224            if j2 < n && self.data.less(j2, j1 as usize) {
225                j = j2 // = 2*i + 2  // right child
226            }
227            if !self.data.less(j, i) {
228                break;
229            }
230            self.data.swap(i, j);
231            i = j
232        }
233        return i > i0;
234    }
235}
236
237/// A very simple min heap implementation
238pub struct MinHeap<T: Ord>(pub Vec<T>);
239
240impl<T: Ord> Heap<T> for MinHeap<T> {
241    fn len(&self) -> usize {
242        self.0.len()
243    }
244
245    fn less(&self, i: usize, j: usize) -> bool {
246        self.0[i] < self.0[j]
247    }
248
249    fn swap(&mut self, i: usize, j: usize) {
250        self.0.swap(i, j);
251    }
252
253    fn push(&mut self, x: T) {
254        self.0.push(x);
255    }
256
257    fn pop(&mut self) -> T {
258        self.0.pop().expect("pop on an empty vec!")
259    }
260
261    fn peak(&self) -> Option<&T> {
262        self.0.get(0)
263    }
264}
265
266#[cfg(test)]
267mod tests {
268    use crate::{Heap, HeapType, MinHeap};
269    use std::collections::HashSet;
270    use rand::{thread_rng, Rng};
271
272    #[test]
273    fn simple_vec() {
274        // Create a vector
275        let my_vec = MinHeap(vec![2, 4, 3, 1]);
276        let mut heap = HeapType::new(my_vec);
277        // Change it a bit
278        assert_eq!(heap.peak().unwrap(), &1);
279        assert_eq!(heap.pop().unwrap(), 1);
280        heap.push(-1);
281        assert_eq!(heap.pop().unwrap(), -1);
282        assert_eq!(heap.pop().unwrap(), 2);
283        assert_eq!(heap.pop().unwrap(), 3);
284        assert_eq!(heap.pop().unwrap(), 4);
285        assert_eq!(heap.data.len(), 0);
286    }
287
288    #[test]
289    fn simple_remove() {
290        let my_vec = MinHeap(vec![1, 4, 3]);
291        let mut heap = HeapType::new(my_vec); // [1, 4, 3]
292        assert_eq!(heap.remove(1), 4);
293        assert_eq!(heap.pop(), Some(1));
294        assert_eq!(heap.pop(), Some(3));
295        assert_eq!(heap.pop(), None);
296    }
297
298    #[test]
299    fn simple_fix() {
300        let my_vec = MinHeap(vec![10, 4, 3]);
301        let mut heap = HeapType::new(my_vec); // [3, 4, 10]
302        heap.data.0[1] = 0;
303        heap.fix(0);
304        assert_eq!(heap.pop(), Some(0));
305        assert_eq!(heap.pop(), Some(3));
306        assert_eq!(heap.pop(), Some(10));
307        assert_eq!(heap.pop(), None);
308    }
309
310    #[test]
311    fn empty_test() {
312        let mut heap = HeapType::new(MinHeap(vec![]));
313        heap.push(2);
314        heap.push(1);
315        assert_eq!(heap.pop(), Some(1));
316        assert_eq!(heap.pop(), Some(2));
317        assert_eq!(heap.pop(), None);
318    }
319
320    //noinspection DuplicatedCode
321    fn verify(h: &MinHeap<i32>, i: usize) {
322        let n = h.len();
323        let j1 = 2 * i + 1;
324        let j2 = 2 * i + 2;
325        if j1 < n {
326            assert!(!h.less(j1, i), "heap invariant invalidated [{}] = {} > [{}] = {}", i, h.0[i], j1, h.0[j1]);
327            verify(h, j1);
328        }
329        if j2 < n {
330            assert!(!h.less(j2, i), "heap invariant invalidated [{}] = {} > [{}] = {}", i, h.0[i], j1, h.0[j2]);
331            verify(h, j2);
332        }
333    }
334
335    #[test]
336    fn go_init0() {
337        let h = vec![0; 20];
338        let mut h = HeapType::new(MinHeap(h));
339        verify(&h.data, 0);
340
341        let mut i = 1;
342        while h.len() > 0 {
343            let x = h.pop().unwrap();
344            verify(&h.data, 0);
345            assert_eq!(x, 0, "{}.th pop got {}; want {}", i, x, 0);
346            i += 1;
347        }
348    }
349
350    #[test]
351    fn go_init1() {
352        let mut h = vec![];
353        for i in 1..=20 {
354            h.push(i);
355        }
356        let mut h = HeapType::new(MinHeap(h));
357        verify(&h.data, 0);
358
359        let mut i = 1;
360        while h.len() > 0 {
361            let x = h.pop().unwrap();
362            verify(&h.data, 0);
363            assert_eq!(x, i, "{}.th pop got {}; want {}", i, x, i);
364            i += 1;
365        }
366    }
367
368    #[test]
369    fn go_test() {
370        let mut h = MinHeap(Vec::new());
371        verify(&h, 0);
372        for i in (11..=20).rev() {
373            h.push(i);
374        }
375        let mut h = HeapType::new(h);
376        verify(&h.data, 0);
377        for i in (1..=10).rev() {
378            h.push(i);
379            verify(&h.data, 0);
380        }
381
382        let mut i = 1;
383        while h.len() > 0 {
384            let x = h.pop().unwrap();
385            if i < 20 {
386                h.push(20 + i);
387            }
388            verify(&h.data, 0);
389            assert_eq!(x, i, "{}.th pop got {}; want {}", i, x, i);
390            i += 1;
391        }
392    }
393
394    #[test]
395    fn go_test_remove0() {
396        let mut h = HeapType::new(MinHeap(vec![]));
397        for i in 0..10 {
398            h.push(i);
399        }
400        verify(&h.data, 0);
401
402        while h.len() > 0 {
403            let i = h.len() - 1;
404            let x = h.remove(i);
405            assert_eq!(x, i as i32, "Remove({}) got {}; want {}", i, x, i);
406            verify(&h.data, 0);
407        }
408    }
409
410    #[test]
411    fn go_test_remove1() {
412        let mut h = HeapType::new(MinHeap(vec![]));
413        for i in 0..10 {
414            h.push(i);
415        }
416        verify(&h.data, 0);
417
418        let mut i = 0;
419        while h.len() > 0 {
420            let x = h.remove(0);
421            assert_eq!(x, i as i32, "Remove(0) got {}; want {}", x, i);
422            verify(&h.data, 0);
423            i += 1;
424        }
425    }
426
427    #[test]
428    fn go_test_remove2() {
429        const N: i32 = 10;
430        let mut h = HeapType::new(MinHeap(vec![]));
431        for i in 0..N {
432            h.push(i);
433        }
434        verify(&h.data, 0);
435
436        let mut m = HashSet::new();
437        while h.len() > 0 {
438            m.insert(h.remove((h.len() - 1) / 2));
439            verify(&h.data, 0);
440        }
441        assert_eq!(m.len(), N as usize, "len(m) = {}; want {}", m.len(), N);
442        for i in 0..N {
443            assert!(m.contains(&i), "m[{}] doesn't exist", i);
444        }
445    }
446
447    #[test]
448    fn go_test_fix() {
449        let mut h = HeapType::new(MinHeap(vec![]));
450        let mut i = 200;
451        while i > 0 {
452            h.push(i);
453            i -= 10;
454        }
455        verify(&h.data, 0);
456
457        assert_eq!(h.peak(), Some(&10), "Expected head to be 10, was {:?}", h.peak());
458        h.data.0[0] = 210;
459        h.fix(0);
460        verify(&h.data, 0);
461
462        let mut rng = thread_rng();
463        for i in 0..100 {
464            let elem = rng.gen_range(0..h.len());
465            if i % 2 == 0 {
466                h.data.0[elem] *= 2;
467            } else {
468                h.data.0[elem] /= 2;
469            }
470            h.fix(elem);
471            verify(&h.data, 0);
472        }
473    }
474}