Commit 5f4dda3b authored by tgerstel's avatar tgerstel
Browse files

better child indexing

parent b5d30af2
use std::ops::{Index, IndexMut};
use super::collections::{Label, Pool};
#[derive(Debug, Clone, Copy, PartialEq)]
......@@ -5,7 +7,30 @@ pub struct Node<V> {
value: V,
parent: Parent<V>,
flipped: bool,
children: [Option<Label<Node<V>>>; 2],
children: Children<V>,
}
#[derive(Debug, Clone, Copy, PartialEq)]
struct Children<V>(Option<Label<Node<V>>>, Option<Label<Node<V>>>);
impl<V: Clone> Index<bool> for Children<V> {
type Output = Option<Label<Node<V>>>;
fn index(&self, side: bool) -> &Self::Output {
match side {
false => &self.0,
true => &self.1,
}
}
}
impl<V: Clone> 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,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
......@@ -21,7 +46,7 @@ impl<V: Clone> Pool<Node<V>> {
value,
parent: Parent::Root,
flipped: false,
children: [None, None],
children: Children(None, None),
})
}
......@@ -29,7 +54,7 @@ impl<V: Clone> Pool<Node<V>> {
self.expose(v);
let mut r = v;
let mut flipped = self[v].flipped;
while let Some(w) = self[r].children[usize::from(flipped)] {
while let Some(w) = self[r].children[(flipped)] {
r = w;
flipped ^= self[w].flipped;
}
......@@ -40,9 +65,9 @@ impl<V: Clone> Pool<Node<V>> {
pub fn cut(&mut self, v: Label<Node<V>>) {
self.expose(v);
let flipped = self[v].flipped;
if let Some(l) = self[v].children[usize::from(flipped)] {
if let Some(l) = self[v].children[(flipped)] {
self[l].parent = Parent::Root;
self[v].children[usize::from(flipped)] = None;
self[v].children[(flipped)] = None;
}
}
......@@ -50,7 +75,7 @@ impl<V: Clone> Pool<Node<V>> {
self.expose(c);
self.expose(p);
let child_flipped = self[c].flipped;
self[c].children[usize::from(child_flipped)] = Some(p);
self[c].children[(child_flipped)] = Some(p);
self[p].parent = Parent::BinTree(c);
}
......@@ -69,17 +94,17 @@ impl<V: Clone> Pool<Node<V>> {
fn expose(&mut self, v: Label<Node<V>>) {
self.splay(v);
if let Some(r) = self[v].children[1] {
if let Some(r) = self[v].children[true] {
self[r].parent = Parent::Path(v);
self[v].children[1] = None;
self[v].children[true] = None;
}
while let Parent::Path(p) = self[v].parent {
self.splay(p);
if let Some(r) = self[p].children[1] {
if let Some(r) = self[p].children[true] {
self[r].parent = Parent::Path(p);
}
self[p].children[1] = Some(v);
self[p].children[true] = Some(v);
self[v].parent = Parent::BinTree(p);
self.rotate(v);
}
......@@ -109,8 +134,8 @@ impl<V: Clone> Pool<Node<V>> {
}
if self[v].flipped {
let [a_opt, b_opt] = self[v].children;
self[v].children = [b_opt, a_opt];
let Children(a_opt, b_opt) = self[v].children;
self[v].children = Children(b_opt, a_opt);
self[v].flipped = false;
if let Some(a) = a_opt {
self[a].flipped = !self[a].flipped;
......@@ -126,12 +151,12 @@ impl<V: Clone> Pool<Node<V>> {
if let Parent::BinTree(p) = self[v].parent {
if let Parent::BinTree(g) = self[p].parent {
let g_side = self.side(p);
self[g].children[usize::from(g_side)] = Some(v);
self[g].children[(g_side)] = Some(v);
}
let b_opt = self[v].children[usize::from(!p_side)];
self[p].children[usize::from(p_side)] = b_opt;
self[v].children[usize::from(!p_side)] = Some(p);
let b_opt = self[v].children[(!p_side)];
self[p].children[(p_side)] = b_opt;
self[v].children[(!p_side)] = Some(p);
if let Some(b) = b_opt {
self[b].parent = Parent::BinTree(p);
......@@ -146,7 +171,7 @@ impl<V: Clone> Pool<Node<V>> {
fn side(&self, v: Label<Node<V>>) -> bool {
if let Parent::BinTree(p) = self[v].parent {
if let Some(o) = self[p].children[1] {
if let Some(o) = self[p].children[true] {
o == v
} else {
false
......@@ -178,7 +203,7 @@ mod tests {
let p = lct.add_node("parent");
// link nodes
lct[p].children[0] = Some(o);
lct[p].children[false] = Some(o);
lct[o].parent = Parent::BinTree(p);
// rotate
......@@ -186,8 +211,8 @@ mod tests {
dbg!(&lct);
// check children
assert_eq!(lct[o].children, [None, Some(p)]);
assert_eq!(lct[p].children, [None, None]);
assert_eq!(lct[o].children, Children(None, Some(p)));
assert_eq!(lct[p].children, Children(None, None));
// check parents
assert_eq!(lct[o].parent, Parent::Root);
......@@ -208,9 +233,9 @@ mod tests {
let d = lct.add_node("d");
// link nodes
lct[o].children = [Some(a), Some(b)];
lct[p].children = [Some(o), Some(c)];
lct[g].children = [Some(p), Some(d)];
lct[o].children = Children(Some(a), Some(b));
lct[p].children = Children(Some(o), Some(c));
lct[g].children = Children(Some(p), Some(d));
lct[o].parent = Parent::BinTree(p);
lct[p].parent = Parent::BinTree(g);
lct[a].parent = Parent::BinTree(o);
......@@ -223,13 +248,13 @@ mod tests {
dbg!(&lct);
// check children
assert_eq!(lct[o].children, [Some(a), Some(p)]);
assert_eq!(lct[p].children, [Some(b), Some(c)]);
assert_eq!(lct[g].children, [Some(o), Some(d)]);
assert_eq!(lct[a].children, [None, None]);
assert_eq!(lct[b].children, [None, None]);
assert_eq!(lct[c].children, [None, None]);
assert_eq!(lct[d].children, [None, None]);
assert_eq!(lct[o].children, Children(Some(a), Some(p)));
assert_eq!(lct[p].children, Children(Some(b), Some(c)));
assert_eq!(lct[g].children, Children(Some(o), Some(d)));
assert_eq!(lct[a].children, Children(None, None));
assert_eq!(lct[b].children, Children(None, None));
assert_eq!(lct[c].children, Children(None, None));
assert_eq!(lct[d].children, Children(None, None));
// check parents
assert_eq!(lct[o].parent, Parent::BinTree(g));
......@@ -255,9 +280,9 @@ mod tests {
let d = lct.add_node("d");
// link nodes
lct[o].children = [Some(a), Some(b)];
lct[p].children = [Some(o), Some(c)];
lct[g].children = [Some(p), Some(d)];
lct[o].children = Children(Some(a), Some(b));
lct[p].children = Children(Some(o), Some(c));
lct[g].children = Children(Some(p), Some(d));
lct[o].parent = Parent::BinTree(p);
lct[p].parent = Parent::BinTree(g);
lct[a].parent = Parent::BinTree(o);
......@@ -274,13 +299,13 @@ mod tests {
dbg!(&lct);
// check children
assert_eq!(lct[o].children, [Some(b), Some(p)]);
assert_eq!(lct[p].children, [Some(a), Some(c)]);
assert_eq!(lct[g].children, [Some(o), Some(d)]);
assert_eq!(lct[a].children, [None, None]);
assert_eq!(lct[b].children, [None, None]);
assert_eq!(lct[c].children, [None, None]);
assert_eq!(lct[d].children, [None, None]);
assert_eq!(lct[o].children, Children(Some(b), Some(p)));
assert_eq!(lct[p].children, Children(Some(a), Some(c)));
assert_eq!(lct[g].children, Children(Some(o), Some(d)));
assert_eq!(lct[a].children, Children(None, None));
assert_eq!(lct[b].children, Children(None, None));
assert_eq!(lct[c].children, Children(None, None));
assert_eq!(lct[d].children, Children(None, None));
// check parents
assert_eq!(lct[o].parent, Parent::BinTree(g));
......@@ -313,8 +338,8 @@ mod tests {
let e = lct.add_node("e");
// link nodes
lct[b].children = [None, Some(c)];
lct[d].children = [None, Some(e)];
lct[b].children = Children(None, Some(c));
lct[d].children = Children(None, Some(e));
lct[c].parent = Parent::BinTree(b);
lct[e].parent = Parent::BinTree(d);
lct[b].parent = Parent::Path(a);
......@@ -346,9 +371,9 @@ mod tests {
let d = lct.add_node("d");
// link nodes
lct[o].children = [Some(a), Some(b)];
lct[p].children = [Some(o), Some(c)];
lct[g].children = [Some(p), Some(d)];
lct[o].children = Children(Some(a), Some(b));
lct[p].children = Children(Some(o), Some(c));
lct[g].children = Children(Some(p), Some(d));
lct[o].parent = Parent::BinTree(p);
lct[p].parent = Parent::BinTree(g);
lct[a].parent = Parent::BinTree(o);
......@@ -372,8 +397,8 @@ mod tests {
let e = lct.add_node("e");
// link nodes
lct[b].children = [None, Some(c)];
lct[d].children = [None, Some(e)];
lct[b].children = Children(None, Some(c));
lct[d].children = Children(None, Some(e));
lct[c].parent = Parent::BinTree(b);
lct[e].parent = Parent::BinTree(d);
lct[b].parent = Parent::Path(a);
......@@ -382,15 +407,15 @@ mod tests {
// cut
lct.cut(c);
dbg!(&lct);
assert_eq!(lct[c].children[0], None);
assert_eq!(lct[c].children[false], None);
assert_eq!(lct[c].parent, Parent::Root);
assert_eq!(lct[b].children[1], None);
assert_eq!(lct[b].children[true], None);
// link
lct.link(b, c);
dbg!(&lct);
assert_eq!(lct[b].parent, Parent::BinTree(c));
assert_eq!(lct[c].children, [Some(b), None]);
assert_eq!(lct[c].children, Children(Some(b), None));
assert_eq!(lct[c].parent, Parent::Root);
assert_eq!(lct[d].parent, Parent::Path(c));
}
......@@ -409,9 +434,9 @@ mod tests {
let d = lct.add_node("d");
// link nodes
lct[o].children = [Some(a), Some(b)];
lct[p].children = [Some(o), Some(c)];
lct[g].children = [Some(p), Some(d)];
lct[o].children = Children(Some(a), Some(b));
lct[p].children = Children(Some(o), Some(c));
lct[g].children = Children(Some(p), Some(d));
lct[o].parent = Parent::BinTree(p);
lct[p].parent = Parent::BinTree(g);
lct[a].parent = Parent::BinTree(o);
......
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