Commit fb866dcb authored by SirBlueRabbit's avatar SirBlueRabbit
Browse files

basic depth test

parent 0fc1058b
......@@ -57,25 +57,55 @@ impl<V> PartialEq for Parent<V> {
}
}
#[derive(Copy, Clone, Debug, PartialEq)]
enum ChildType {
Left,
Right,
Path,
Root,
}
impl ChildType {
fn mirror(&self) -> Option<Self> {
match self {
ChildType::Left => Some(ChildType::Right),
ChildType::Right => Some(ChildType::Left),
_ => None,
}
}
}
impl From<bool> for ChildType {
fn from(var: bool) -> Self {
if var {
ChildType::Right
} else {
ChildType::Left
}
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
struct Children<V>(Option<Label<Node<V>>>, Option<Label<Node<V>>>);
impl<V> Index<bool> for Children<V> {
impl<V> Index<ChildType> for Children<V> {
type Output = Option<Label<Node<V>>>;
fn index(&self, side: bool) -> &Self::Output {
match side {
false => &self.0,
true => &self.1,
fn index(&self, child_type: ChildType) -> &Self::Output {
match child_type {
ChildType::Left => &self.0,
ChildType::Right => &self.1,
_ => unreachable!(),
}
}
}
impl<V> IndexMut<bool> for Children<V> {
fn index_mut(&mut self, side: bool) -> &mut Self::Output {
match side {
false => &mut self.0,
true => &mut self.1,
impl<V> IndexMut<ChildType> for Children<V> {
fn index_mut(&mut self, child_type: ChildType) -> &mut Self::Output {
match child_type {
ChildType::Left => &mut self.0,
ChildType::Right => &mut self.1,
_ => unreachable!(),
}
}
}
......@@ -104,7 +134,7 @@ impl<V> Pool<Node<V>> {
self.expose(u);
let mut x = u;
let mut d_flip = self[u].d_flip;
while let Some(y) = self[x].children[d_flip] {
while let Some(y) = self[x].children[ChildType::from(d_flip)] {
x = y;
d_flip ^= self[x].d_flip;
}
......@@ -115,9 +145,9 @@ impl<V> Pool<Node<V>> {
pub fn cut(&mut self, c: Label<Node<V>>) {
self.expose(c);
let d_flip = self[c].d_flip;
if let Some(p) = self[c].children[d_flip] {
if let Some(p) = self[c].children[ChildType::from(d_flip)] {
self[p].parent = Parent::Root;
self[c].children[d_flip] = None;
self[c].children[ChildType::from(d_flip)] = None;
self[p].d_depth = self[c].d_depth - 1;
self[c].d_depth = 0;
......@@ -128,7 +158,7 @@ impl<V> Pool<Node<V>> {
self.expose(c);
self.expose(p);
let d_flip = self[c].d_flip;
self[c].children[d_flip] = Some(p);
self[c].children[ChildType::from(d_flip)] = Some(p);
self[p].parent = Parent::BinTree(c);
self[c].d_depth = self[p].d_depth + 1;
......@@ -138,6 +168,7 @@ impl<V> Pool<Node<V>> {
pub fn evert(&mut self, u: Label<Node<V>>) {
self.expose(u);
self[u].d_flip = !self[u].d_flip;
self[u].d_depth = 0;
}
pub fn first_ancestor(&mut self, u: Label<Node<V>>, v: Label<Node<V>>) -> Label<Node<V>> {
......@@ -156,6 +187,33 @@ impl<V> Pool<Node<V>> {
}
}
pub fn depth(&self, u: Label<Node<V>>) -> usize {
let mut label = u;
let mut depth: isize = 0;
loop {
if self.parent(label).is_some() {
let d_depth = self[label].d_depth as isize;
let d_flip = self[self.parent(label).unwrap()].d_flip;
let child_type = self.child_type(label);
match child_type {
ChildType::Left => depth -= d_depth,
ChildType::Right => depth += d_depth,
ChildType::Path => depth += d_depth,
ChildType::Root => unreachable!(),
}
if d_flip {
depth = -depth;
}
label = self.parent(label).unwrap();
} else {
let d_depth = self[label].d_depth as isize;
return (depth + d_depth).abs() as usize;
}
}
}
pub fn value_mut(&mut self, u: Label<Node<V>>) -> &mut V {
&mut self[u].value
}
......@@ -166,17 +224,17 @@ impl<V> Pool<Node<V>> {
fn expose(&mut self, u: Label<Node<V>>) {
self.splay(u);
if let Some(c) = self[u].children[true] {
if let Some(c) = self[u].children[ChildType::from(true)] {
self[c].parent = Parent::Path(u);
self[u].children[true] = None;
self[u].children[ChildType::from(true)] = None;
}
while let Parent::Path(p) = self[u].parent {
self.splay(p);
if let Some(x) = self[p].children[true] {
if let Some(x) = self[p].children[ChildType::from(true)] {
self[x].parent = Parent::Path(p);
}
self[p].children[true] = Some(u);
self[p].children[ChildType::from(true)] = Some(u);
self[u].parent = Parent::BinTree(p);
self.rotate(u);
}
......@@ -186,7 +244,7 @@ impl<V> Pool<Node<V>> {
self.cascade_flipped(u);
while let Parent::BinTree(p) = self[u].parent {
if let Parent::BinTree(_) = self[p].parent {
if self[p].d_flip == (self.side(u) == self.side(p)) {
if self[p].d_flip == (self.child_type(u) == self.child_type(p)) {
self.rotate(p);
self.rotate(u);
} else {
......@@ -219,15 +277,15 @@ impl<V> Pool<Node<V>> {
}
fn rotate(&mut self, u: Label<Node<V>>) {
let u_side = self.side(u);
let x_opt = self[u].children[!u_side];
let u_child_type = self.child_type(u);
let x_opt = self[u].children[u_child_type.mirror().unwrap()];
if let Parent::BinTree(p) = self[u].parent {
let u_d_depth = self[u].d_depth;
let p_d_depth = self[p].d_depth;
self[p].d_depth = u_d_depth;
self[u].d_depth = if let Parent::BinTree(_) = self[p].parent {
if self[p].d_flip ^ (self.side(u) == self.side(p)) {
if self[p].d_flip ^ (self.child_type(u) == self.child_type(p)) {
u_d_depth + p_d_depth
} else {
u_d_depth.abs_diff(p_d_depth)
......@@ -242,12 +300,12 @@ impl<V> Pool<Node<V>> {
}
if let Parent::BinTree(g) = self[p].parent {
let p_side = self.side(p);
self[g].children[p_side] = Some(u);
let p_child_type = self.child_type(p);
self[g].children[p_child_type] = Some(u);
}
self[p].children[u_side] = x_opt;
self[u].children[!u_side] = Some(p);
self[p].children[u_child_type] = x_opt;
self[u].children[u_child_type.mirror().unwrap()] = Some(p);
if let Some(x) = x_opt {
self[x].parent = Parent::BinTree(p);
......@@ -260,19 +318,45 @@ impl<V> Pool<Node<V>> {
};
}
fn side(&self, u: Label<Node<V>>) -> bool {
if let Parent::BinTree(p) = self[u].parent {
if let Some(x) = self[p].children[true] {
u == x
} else {
false
fn child_type(&self, u: Label<Node<V>>) -> ChildType {
match self[u].parent {
Parent::BinTree(parent) => {
if let Some(x) = self[parent].children[ChildType::from(false)] {
if u == x {
return ChildType::Left;
}
}
if let Some(x) = self[parent].children[ChildType::from(true)] {
if u == x {
return ChildType::Right;
}
}
unreachable!();
}
} else {
unreachable!();
Parent::Path(_) => ChildType::Path,
Parent::Root => ChildType::Root,
} /*
if let Parent::BinTree(p) = self[u].parent {
if let Some(x) = self[p].children[true] {
Some(u == x)
} else {
Some(false)
}
} else {
None
} */
}
fn parent(&self, u: Label<Node<V>>) -> Option<Label<Node<V>>> {
match self[u].parent {
Parent::BinTree(parent) => Some(parent),
Parent::Path(parent) => Some(parent),
Parent::Root => None,
}
}
// assume that u is the root of its binary tree
/* // assume that u is the root of its binary tree
#[cfg(test)]
fn sequence(&self, u: Label<Node<V>>) -> Vec<Label<Node<V>>> {
let mut queue = vec![u];
......@@ -296,9 +380,9 @@ impl<V> Pool<Node<V>> {
}
}
seq
}
} */
#[cfg(test)]
/* #[cfg(test)]
fn flipped(&self, u: Label<Node<V>>) -> bool {
let mut flipped = false;
let mut u = u;
......@@ -310,7 +394,7 @@ impl<V> Pool<Node<V>> {
};
flipped ^= self[u].d_flip;
}
}
} */
}
#[cfg(test)]
......@@ -334,7 +418,7 @@ mod tests {
let p = lct.add_node("parent");
// link nodes
lct[p].children[false] = Some(o);
lct[p].children[ChildType::from(false)] = Some(o);
lct[o].parent = Parent::BinTree(p);
// rotate
......@@ -561,7 +645,7 @@ mod tests {
assert_eq!(lct.find_root(g), o);
}
#[test]
/* #[test]
fn basic_sequence() {
let mut lct = Pool::with_capacity(7);
......@@ -589,6 +673,34 @@ mod tests {
lct.splay(o);
let seq2 = lct.sequence(o);
assert_eq!(seq1, seq2);
} */
#[test]
fn basic_depth() {
// generate a basic lct
let size = 3;
let mut lct = Pool::with_capacity(size);
for i in 0..size {
let _ = lct.add_node(i);
}
for i in 0..(size - 1) {
let parent = Label::from(i);
let child = Label::from(i + 1);
lct.link(parent, child);
}
// check initial depth
for i in 0..size {
let label = Label::from(i);
assert_eq!(lct.depth(label), i);
}
// evert middle node and check new depths
lct.evert(Label::from(1));
dbg!(&lct);
assert_eq!(lct.depth(Label::from(0)), 1);
assert_eq!(lct.depth(Label::from(1)), 0);
assert_eq!(lct.depth(Label::from(2)), 1);
}
#[test]
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment