use crate::prelude::PositionType;
#[derive(Debug)]
pub struct HeapTree<T> {
pub(crate) tree: Vec<T>,
pub height: usize,
}
impl<T> HeapTree<T>
where
T: Default + Clone,
{
pub fn new(height: usize) -> Self {
let tree = vec![T::default(); 2usize.pow(height as u32) - 1];
Self { tree, height }
}
}
impl<T> HeapTree<T>
where
T: Clone,
{
pub fn new_with(height: usize, default: T) -> Self {
let tree = vec![default; 2usize.pow(height as u32) - 1];
Self { tree, height }
}
}
impl<T> HeapTree<T> {
#[inline]
pub fn get_index(&self, depth: usize, path: PositionType) -> usize {
debug_assert!(depth < self.height);
let level_offset = (1 << depth) - 1;
let mask = level_offset as PositionType;
level_offset + (path & mask) as usize
}
#[inline]
pub fn get_path_at_depth(&self, depth: usize, path: PositionType) -> &T {
let index = self.get_index(depth, path);
&self.tree[index]
}
#[inline]
pub fn get_path_at_depth_mut(&mut self, depth: usize, path: PositionType) -> &mut T {
let index = self.get_index(depth, path);
&mut self.tree[index]
}
pub fn get_sibling(&self, depth: usize, path: PositionType) -> &T {
let new_path = path ^ (1 << (depth - 1));
self.get_path_at_depth(depth, new_path)
}
}
#[cfg(test)]
mod tests {
use crate::prelude::PositionType;
fn print_depth_pos_index(height: usize, depth: usize, path: PositionType) {
debug_assert!(depth < height);
let level_offset = (1 << depth) - 1;
let mask = level_offset as PositionType;
let _ret = level_offset + (path & mask) as usize;
}
#[test]
fn print_heap_tree_info() {
for depth in 0..3 {
for path in 0..4 {
print_depth_pos_index(3, depth, path);
}
}
}
}