diff --git a/src/backing/item.rs b/src/backing/item.rs new file mode 100644 index 0000000..424bf45 --- /dev/null +++ b/src/backing/item.rs @@ -0,0 +1,41 @@ +use std::cmp::Ordering; + +/// Helper struct to associate an item with its priority +#[derive(Debug, Clone, Copy)] +pub struct Item { + data: D, + priority: P, +} + +impl Item { + /// Creates a new instance + fn new(data: D, priority: P) -> Self { + Self { data, priority } + } + + /// Retrieve the internal data, it would be nicer to implement this using [`From`] or [`Into`], but I don't see a way to do that using generics + fn data(self) -> D { + self.data + } +} + +// The relevant Ord implementations are based just on the priority +impl Ord for Item { + fn cmp(&self, other: &Self) -> Ordering { + self.priority.cmp(&other.priority) + } +} + +impl PartialOrd for Item { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl PartialEq for Item { + fn eq(&self, other: &Self) -> bool { + self.priority == other.priority + } +} + +impl Eq for Item {} diff --git a/src/backing/keyed/mod.rs b/src/backing/keyed/mod.rs index a574e73..58077c5 100644 --- a/src/backing/keyed/mod.rs +++ b/src/backing/keyed/mod.rs @@ -1,34 +1,5 @@ /// Data structures for the "keyed" min-queues, supporting priority updates and arbitrary removals, but no duplicates -use super::pure::PureBacking; -use std::cmp::Ordering; - -/// Helper struct to associate an item with its priority -#[derive(Debug, Copy, Clone)] -pub struct Item { - data: D, - priority: P, -} - -// The relevant Ord implementations are based just on the priority -impl Ord for Item { - fn cmp(&self, other: &Self) -> Ordering { - self.priority.cmp(&other.priority) - } -} - -impl PartialOrd for Item { - fn partial_cmp(&self, other: &Self) -> Option { - Some(self.cmp(other)) - } -} - -impl PartialEq for Item { - fn eq(&self, other: &Self) -> bool { - self.priority == other.priority - } -} - -impl Eq for Item {} +use super::{item::Item, pure::PureBacking}; /// A data structure usable for backing a "keyed" queue pub trait KeyedBacking: PureBacking> { diff --git a/src/backing/mod.rs b/src/backing/mod.rs index ea87b12..f66e16c 100644 --- a/src/backing/mod.rs +++ b/src/backing/mod.rs @@ -1,2 +1,3 @@ +pub mod item; pub mod keyed; pub mod pure; diff --git a/src/backing/pure/binary_heap.rs b/src/backing/pure/binary_heap.rs index 5195756..4d79d97 100644 --- a/src/backing/pure/binary_heap.rs +++ b/src/backing/pure/binary_heap.rs @@ -103,6 +103,18 @@ impl BinaryHeap { } } +impl FromIterator for BinaryHeap { + fn from_iter>(iter: U) -> Self { + let mut this = Self { + data: Vec::from_iter(iter), + }; + for i in (0..=(this.data.len() / 2)).rev() { + this.sift_down(i); + } + this + } +} + impl PureBacking for BinaryHeap { fn new() -> Self { Self { data: vec![] } diff --git a/src/backing/pure/mod.rs b/src/backing/pure/mod.rs index 24f69c9..9d82347 100644 --- a/src/backing/pure/mod.rs +++ b/src/backing/pure/mod.rs @@ -2,7 +2,7 @@ pub mod binary_heap; /// A data structure usable for backing a "pure" queue -pub trait PureBacking { +pub trait PureBacking: FromIterator { /// Instantiates a new data structure fn new() -> Self; /// Places an item into the queue diff --git a/tests/pure_binary_heap.rs b/tests/pure_binary_heap.rs index a6326c2..597d6eb 100644 --- a/tests/pure_binary_heap.rs +++ b/tests/pure_binary_heap.rs @@ -3,26 +3,26 @@ mod tests { use pyority_queue::backing::pure::{binary_heap::BinaryHeap, PureBacking}; #[test] - fn test_pure_binary_heap() { + fn test_pure_binary_heap_manual_creation() { let mut heap = BinaryHeap::new(); - assert_eq!(heap.len(), 0); heap.add(4); - assert_eq!(heap.len(), 1); heap.add(-3); - assert_eq!(heap.len(), 2); heap.add(6); - assert_eq!(heap.len(), 3); heap.add(1); - assert_eq!(heap.len(), 4); assert_eq!(heap.pop(), Some(-3)); - assert_eq!(heap.len(), 3); assert_eq!(heap.pop(), Some(1)); - assert_eq!(heap.len(), 2); assert_eq!(heap.pop(), Some(4)); - assert_eq!(heap.len(), 1); assert_eq!(heap.pop(), Some(6)); - assert_eq!(heap.len(), 0); assert_eq!(heap.pop(), None); - assert_eq!(heap.len(), 0); + } + + #[test] + fn test_pure_binary_heap_from_iter() { + let mut heap = BinaryHeap::from_iter(vec![7, 3, 6, 9]); + assert_eq!(heap.pop(), Some(3)); + assert_eq!(heap.pop(), Some(6)); + assert_eq!(heap.pop(), Some(7)); + assert_eq!(heap.pop(), Some(9)); + assert_eq!(heap.pop(), None); } }