From 846a5424deed9185178bb9975ff64c66225ff827 Mon Sep 17 00:00:00 2001 From: Michael Bradley Date: Fri, 31 Jan 2025 01:02:16 -0500 Subject: [PATCH] Implement IndexedBinaryHeap API Still missing core sift functions, but passes 3/27 tests now --- src/backing/indexed/binary_heap.rs | 90 ++++++++++++++++++++++++++---- 1 file changed, 79 insertions(+), 11 deletions(-) diff --git a/src/backing/indexed/binary_heap.rs b/src/backing/indexed/binary_heap.rs index 84415ec..d438dce 100644 --- a/src/backing/indexed/binary_heap.rs +++ b/src/backing/indexed/binary_heap.rs @@ -1,49 +1,117 @@ use std::{collections::HashMap, hash::Hash}; -use crate::backing::{containers::Pair, indexed::IndexedBacking}; +use crate::backing::{ + containers::{Pair, SiftResult}, + indexed::IndexedBacking, +}; -pub struct IndexedBinaryHeap { +pub struct IndexedBinaryHeap< + D: Hash + Eq + Clone + Send + Sync, + P: PartialOrd + Clone + Send + Sync, +> { data: Vec>, indices: HashMap, } -impl IndexedBinaryHeap { +impl + IndexedBinaryHeap +{ pub fn new() -> Self { Self { data: Vec::new(), indices: HashMap::new(), } } + + fn sift_up(&mut self, i: usize) -> SiftResult { + todo!() + } + + fn sift_down(&mut self, i: usize) -> SiftResult { + todo!() + } + + fn delete_pair(&mut self, i: usize) -> Option> { + if i >= self.data.len() { + return None; + } + let pair = self.data[i].clone(); + if i < self.data.len() - 1 { + self.data[i] = self.data.pop().unwrap(); + if self.data[i] < pair { + self.sift_up(i).unwrap(); + } else { + self.sift_down(i).unwrap(); + } + } + self.indices.remove(pair.get_data()); + Some(pair) + } } -impl FromIterator<(D, P)> +impl FromIterator<(D, P)> for IndexedBinaryHeap { fn from_iter>(iter: T) -> Self { - todo!() + let mut this = Self::new(); + for (i, (data, priority)) in iter.into_iter().enumerate() { + this.indices.insert(data.clone(), i); + this.data.push(Pair::new(data, priority)); + } + for i in (0..=(this.data.len() / 2)).rev() { + this.sift_down(i).expect("Index error during heapify"); + } + this } } -impl IndexedBacking +impl IndexedBacking for IndexedBinaryHeap { fn len(&self) -> usize { - todo!() + self.data.len() } fn contains(&self, data: &D) -> bool { - todo!() + self.indices.contains_key(data) } fn set(&mut self, data: D, priority: P) { - todo!() + if let Some(index) = self.indices.get(&data) { + let pair = self.data.get_mut(*index).unwrap(); + let old_priority = pair.get_priority(); + if priority < *old_priority { + pair.set_priority(priority); + self.sift_up(*index).unwrap(); + } else { + pair.set_priority(priority); + self.sift_down(*index).unwrap(); + } + } else { + let final_index = self.data.len(); + self.indices.insert(data.clone(), final_index); + self.data.push(Pair::new(data, priority)); + self.sift_up(final_index).unwrap(); + } } fn remove(&mut self, data: D) -> Option

{ - todo!() + if let Some(index) = self.indices.get(&data) { + if let Some(pair) = self.delete_pair(*index) { + Some(pair.get_priority().clone()) + } else { + None + } + } else { + None + } } fn pop(&mut self) -> Option { - todo!() + if let Some(pair) = self.delete_pair(0) { + Some(pair.data()) + } else { + None + } } }