use fid::{BitVector, FID};
pub struct Louds(BitVector);
impl Louds {
pub fn new() -> Louds {
let mut bv = BitVector::new();
bv.push(true);
bv.push(false);
Louds(bv)
}
pub fn push_node(&mut self, d: usize) {
for _ in 0..d {
self.0.push(true);
}
self.0.push(false);
}
pub fn push_bit(&mut self, b: bool) {
self.0.push(b);
}
pub fn size(&self) -> usize {
self.0.size()
}
pub fn first_child(&self, i: usize) -> Option<usize> {
let first_child_pos = self.0.select0(i as u64) + 1;
if self.0.get(first_child_pos) {
Some(self.0.rank1(first_child_pos) as usize)
} else {
None
}
}
pub fn last_child(&self, i: usize) -> Option<usize> {
let last_child_pos = self.0.select0(i as u64 + 1) - 1;
if self.0.get(last_child_pos) {
Some(self.0.rank1(last_child_pos) as usize)
} else {
None
}
}
pub fn is_leaf(&self, i: usize) -> bool {
let first_child_pos = self.0.select0(i as u64) + 1;
!self.0.get(first_child_pos)
}
pub fn degree(&self, i: usize) -> usize {
let first_child_pos = self.0.select0(i as u64) + 1;
if self.0.get(first_child_pos) {
let last_child_pos = self.0.select0(i as u64 + 1) - 1;
(last_child_pos - first_child_pos + 1) as usize
} else {
0
}
}
pub fn range_children(&self, i: usize) -> Option<(usize, usize)> {
let first_child_pos = self.0.select0(i as u64) + 1;
if self.0.get(first_child_pos) {
let last_child_pos = self.0.select0(i as u64 + 1) - 1;
let s = self.0.rank1(first_child_pos);
let d = last_child_pos - first_child_pos;
Some((s as usize, (s + d) as usize))
} else {
None
}
}
pub fn sibling(&self, i: usize) -> Option<usize> {
let p = self.0.select1(i as u64);
if self.0.get(p + 1) {
Some(i + 1)
} else {
None
}
}
pub fn child(&self, i: usize, k: usize) -> Option<usize> {
self.range_children(i)
.and_then(|(s, e)| if s + k <= e { Some(s + k) } else { None })
}
pub fn parent(&self, i: usize) -> Option<usize> {
if i > 0 {
let p = self.0.select1(i as u64);
Some(self.0.rank0(p) as usize - 1)
} else {
None
}
}
pub fn depth(&self, i: usize) -> usize {
let mut j = i as u64;
let mut d = 0;
while j > 0 {
let p = self.0.select1(j);
j = self.0.rank0(p) - 1;
d = d + 1;
}
d
}
}
#[cfg(test)]
mod tests {
use super::*;
const NODES_LIGHT: &[usize] = &[2, 3, 2, 0, 2, 1, 1, 0, 0, 0, 0, 0];
const FIRST_CHILDREN_LIGHT: &[Option<usize>] = &[
Some(1),
Some(3),
Some(6),
None,
Some(8),
Some(10),
Some(11),
None,
None,
None,
None,
None,
];
const LAST_CHILDREN_LIGHT: &[Option<usize>] = &[
Some(2),
Some(5),
Some(7),
None,
Some(9),
Some(10),
Some(11),
None,
None,
None,
None,
None,
];
const SIBLINGS_LIGHT: &[Option<usize>] = &[
None,
Some(2),
None,
Some(4),
Some(5),
None,
Some(7),
None,
Some(9),
None,
None,
None,
];
const DEPTH_LIGHT: &[usize] = &[0, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3];
const PARENTS_LIGHT: &[Option<usize>] = &[
None,
Some(0),
Some(0),
Some(1),
Some(1),
Some(1),
Some(2),
Some(2),
Some(4),
Some(4),
Some(5),
Some(6),
];
fn get_tree_light() -> Louds {
let mut louds = Louds::new();
for &d in NODES_LIGHT {
louds.push_node(d);
}
louds
}
#[test]
fn test_first_child() {
let louds = get_tree_light();
for i in 0..NODES_LIGHT.len() {
assert_eq!(
louds.first_child(i),
FIRST_CHILDREN_LIGHT[i],
"The first child of node {} is {:?}",
i,
FIRST_CHILDREN_LIGHT[i]
);
}
}
#[test]
fn test_last_child() {
let louds = get_tree_light();
for i in 0..NODES_LIGHT.len() {
assert_eq!(
louds.last_child(i),
LAST_CHILDREN_LIGHT[i],
"The last child of node {} is {:?}",
i,
LAST_CHILDREN_LIGHT[i]
);
}
}
#[test]
fn test_is_leaf() {
let louds = get_tree_light();
for i in 0..NODES_LIGHT.len() {
let ans = NODES_LIGHT[i] == 0;
assert_eq!(
louds.is_leaf(i),
ans,
"The node {} is {}a leaf node.",
i,
if ans { "" } else { "not " }
);
}
}
#[test]
fn test_degree() {
let louds = get_tree_light();
for (i, d) in NODES_LIGHT.iter().enumerate() {
assert_eq!(louds.degree(i), *d, "The degree of node {} is {}", i, *d);
}
}
#[test]
fn test_range_children() {
let louds = get_tree_light();
for i in 0..NODES_LIGHT.len() {
let f = FIRST_CHILDREN_LIGHT[i];
let l = LAST_CHILDREN_LIGHT[i];
let ans = f.and_then(|a| l.map(|b| (a, b)));
assert_eq!(
louds.range_children(i),
ans,
"The last child of node {} is {:?}",
i,
ans
);
}
}
#[test]
fn test_sibling() {
let louds = get_tree_light();
for i in 0..NODES_LIGHT.len() {
assert_eq!(
louds.sibling(i),
SIBLINGS_LIGHT[i],
"The next sibling of node {} is {:?}",
i,
SIBLINGS_LIGHT[i]
);
}
}
#[test]
fn test_child() {
let louds = get_tree_light();
for i in 0..NODES_LIGHT.len() {
let d = louds.degree(i);
let mut ans = louds.first_child(i);
for k in 0..=d {
let c = louds.child(i, k);
assert_eq!(c, ans, "The {}-th child of node {} is {:?}", k, i, ans);
ans = ans.and_then(|i| louds.sibling(i));
}
}
}
#[test]
fn test_parent() {
let louds = get_tree_light();
for i in 0..NODES_LIGHT.len() {
assert_eq!(
louds.parent(i),
PARENTS_LIGHT[i],
"The parent of node {} is {:?}",
i,
PARENTS_LIGHT[i]
);
}
}
#[test]
fn test_depth() {
let louds = get_tree_light();
for i in 0..NODES_LIGHT.len() {
assert_eq!(
louds.depth(i),
DEPTH_LIGHT[i],
"The depth of node {} is {:?}",
i,
DEPTH_LIGHT[i]
);
}
}
}