Implement IndexedBinaryHeap API

Still missing core sift functions, but passes 3/27 tests now
This commit is contained in:
Michael Bradley 2025-01-31 01:02:16 -05:00
parent d56d2cf117
commit 846a5424de
Signed by: MichaelBradley
SSH key fingerprint: SHA256:cj/YZ5VT+QOKncqSkx+ibKTIn0Obg7OIzwzl9BL8EO8

View file

@ -1,49 +1,117 @@
use std::{collections::HashMap, hash::Hash}; use std::{collections::HashMap, hash::Hash};
use crate::backing::{containers::Pair, indexed::IndexedBacking}; use crate::backing::{
containers::{Pair, SiftResult},
indexed::IndexedBacking,
};
pub struct IndexedBinaryHeap<D: Hash + Clone + Send + Sync, P: PartialOrd + Clone + Send + Sync> { pub struct IndexedBinaryHeap<
D: Hash + Eq + Clone + Send + Sync,
P: PartialOrd + Clone + Send + Sync,
> {
data: Vec<Pair<D, P>>, data: Vec<Pair<D, P>>,
indices: HashMap<D, usize>, indices: HashMap<D, usize>,
} }
impl<D: Hash + Clone + Send + Sync, P: PartialOrd + Clone + Send + Sync> IndexedBinaryHeap<D, P> { impl<D: Hash + Eq + Clone + Send + Sync, P: PartialOrd + Clone + Send + Sync>
IndexedBinaryHeap<D, P>
{
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
data: Vec::new(), data: Vec::new(),
indices: HashMap::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<Pair<D, P>> {
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<D: Hash + Clone + Send + Sync, P: PartialOrd + Clone + Send + Sync> FromIterator<(D, P)> impl<D: Hash + Eq + Clone + Send + Sync, P: PartialOrd + Clone + Send + Sync> FromIterator<(D, P)>
for IndexedBinaryHeap<D, P> for IndexedBinaryHeap<D, P>
{ {
fn from_iter<T: IntoIterator<Item = (D, P)>>(iter: T) -> Self { fn from_iter<T: IntoIterator<Item = (D, P)>>(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<D: Hash + Clone + Send + Sync, P: PartialOrd + Clone + Send + Sync> IndexedBacking<D, P> impl<D: Hash + Eq + Clone + Send + Sync, P: PartialOrd + Clone + Send + Sync> IndexedBacking<D, P>
for IndexedBinaryHeap<D, P> for IndexedBinaryHeap<D, P>
{ {
fn len(&self) -> usize { fn len(&self) -> usize {
todo!() self.data.len()
} }
fn contains(&self, data: &D) -> bool { fn contains(&self, data: &D) -> bool {
todo!() self.indices.contains_key(data)
} }
fn set(&mut self, data: D, priority: P) { 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<P> { fn remove(&mut self, data: D) -> Option<P> {
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<D> { fn pop(&mut self) -> Option<D> {
todo!() if let Some(pair) = self.delete_pair(0) {
Some(pair.data())
} else {
None
}
} }
} }