diff --git a/Cargo.toml b/Cargo.toml index a0c17de..6956caa 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,6 @@ [workspace] members = [ "euklid-clocks", + "euklid-kmerge", "euklid-num", ] diff --git a/euklid-kmerge/Cargo.toml b/euklid-kmerge/Cargo.toml new file mode 100644 index 0000000..ddcdd49 --- /dev/null +++ b/euklid-kmerge/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "euklid-kmerge" +version = "0.1.0" +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/euklid-kmerge/examples/kmerge.rs b/euklid-kmerge/examples/kmerge.rs new file mode 100644 index 0000000..09c0e61 --- /dev/null +++ b/euklid-kmerge/examples/kmerge.rs @@ -0,0 +1,77 @@ +use std::cmp::Ordering; +use std::cmp::Reverse; +use std::collections::BinaryHeap; + +#[derive(Debug, Eq)] +struct Item<'a> { + arr: &'a Vec, + idx: usize, +} + +impl<'a> PartialEq for Item<'a> { + fn eq(&self, other: &Self) -> bool { + self.get_item() == other.get_item() + } +} + +impl<'a> PartialOrd for Item<'a> { + fn partial_cmp(&self, other: &Self) -> Option { + self.get_item().partial_cmp(&other.get_item()) + } +} + +impl<'a> Ord for Item<'a> { + fn cmp(&self, other: &Self) -> Ordering { + self.get_item().cmp(&other.get_item()) + } +} + +impl<'a> Item<'a> { + fn new(arr: &'a Vec, idx: usize) -> Self { + Self { arr, idx } + } + + fn get_item(&self) -> i32 { + self.arr[self.idx] + } +} + +fn merge(arrays: Vec>) -> Vec { + let mut sorted = vec![]; + + let mut heap = BinaryHeap::with_capacity(arrays.len()); + + // From each vector we build an item which + // stores the array and the current index. + for arr in &arrays { + let item = Item::new(arr, 0); + println!("item={:?}", item); + heap.push(Reverse(item)); + } + + while !heap.is_empty() { + // Get the item with the smallest head. + let mut it = heap.pop().unwrap(); + println!("poped: {:?}", it.0); + sorted.push(it.0.get_item()); + + // Increment the index + it.0.idx += 1; + + // If there are still elements in the array + // we push back the item in the heap, so the + // heap is reordered. + if it.0.idx < it.0.arr.len() { + heap.push(it) + } + } + + sorted +} + +fn main() { + let a = vec![1, 5, 7]; + let b = vec![-2, 3, 4]; + let v = vec![a, b]; + dbg!(merge(v)); +} diff --git a/euklid-kmerge/src/lib.rs b/euklid-kmerge/src/lib.rs new file mode 100644 index 0000000..b2bc49a --- /dev/null +++ b/euklid-kmerge/src/lib.rs @@ -0,0 +1 @@ +//! A crate for merging algorithms