Commit b5d30af2 authored by tgerstel's avatar tgerstel
Browse files

parent enum

parent e68a0197
......@@ -3,18 +3,23 @@ use super::collections::{Label, Pool};
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Node<V> {
value: V,
path_parent: Option<Label<Node<V>>>,
parent: Option<Label<Node<V>>>,
parent: Parent<V>,
flipped: bool,
children: [Option<Label<Node<V>>>; 2],
}
impl<V> Pool<Node<V>> {
#[derive(Debug, Clone, Copy, PartialEq)]
enum Parent<V> {
Path(Label<Node<V>>),
BinTree(Label<Node<V>>),
Root,
}
impl<V: Clone> Pool<Node<V>> {
pub fn add_node(&mut self, value: V) -> Label<Node<V>> {
self.insert(Node {
value,
path_parent: None,
parent: None,
parent: Parent::Root,
flipped: false,
children: [None, None],
})
......@@ -36,7 +41,7 @@ impl<V> Pool<Node<V>> {
self.expose(v);
let flipped = self[v].flipped;
if let Some(l) = self[v].children[usize::from(flipped)] {
self[l].parent = None;
self[l].parent = Parent::Root;
self[v].children[usize::from(flipped)] = None;
}
}
......@@ -46,7 +51,7 @@ impl<V> Pool<Node<V>> {
self.expose(p);
let child_flipped = self[c].flipped;
self[c].children[usize::from(child_flipped)] = Some(p);
self[p].parent = Some(c);
self[p].parent = Parent::BinTree(c);
}
pub fn evert(&mut self, v: Label<Node<V>>) {
......@@ -65,28 +70,25 @@ impl<V> Pool<Node<V>> {
fn expose(&mut self, v: Label<Node<V>>) {
self.splay(v);
if let Some(r) = self[v].children[1] {
self[r].path_parent = Some(v);
self[r].parent = None;
self[r].parent = Parent::Path(v);
self[v].children[1] = None;
}
while let Some(p) = self[v].path_parent {
while let Parent::Path(p) = self[v].parent {
self.splay(p);
if let Some(r) = self[p].children[1] {
self[r].path_parent = Some(p);
self[r].parent = None;
self[r].parent = Parent::Path(p);
}
self[p].children[1] = Some(v);
self[v].parent = Some(p);
self[v].path_parent = None;
self[v].parent = Parent::BinTree(p);
self.rotate(v);
}
}
fn splay(&mut self, v: Label<Node<V>>) {
self.cascade_flipped(v);
while let Some(p) = self[v].parent {
if self[p].parent.is_some() {
while let Parent::BinTree(p) = self[v].parent {
if let Parent::BinTree(_) = self[p].parent {
if self[p].flipped == (self.side(v) == self.side(p)) {
self.rotate(p);
self.rotate(v);
......@@ -102,7 +104,7 @@ impl<V> Pool<Node<V>> {
}
fn cascade_flipped(&mut self, v: Label<Node<V>>) {
if let Some(p) = self[v].parent {
if let Parent::BinTree(p) = self[v].parent {
self.cascade_flipped(p);
}
......@@ -121,33 +123,36 @@ impl<V> Pool<Node<V>> {
fn rotate(&mut self, v: Label<Node<V>>) {
let p_side = self.side(v);
let p = self[v].parent.unwrap();
let b_opt = self[v].children[usize::from(!p_side)];
let g_opt = self[p].parent;
self[v].parent = g_opt;
if let Some(g) = g_opt {
let g_side = self.side(p);
self[g].children[usize::from(g_side)] = Some(v);
} else {
self[v].path_parent = self[p].path_parent;
self[p].path_parent = None;
}
self[p].children[usize::from(p_side)] = b_opt;
self[v].children[usize::from(!p_side)] = Some(p);
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);
}
if let Some(b) = b_opt {
self[b].parent = Some(p);
}
self[p].parent = 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);
if let Some(b) = b_opt {
self[b].parent = Parent::BinTree(p);
}
self[v].parent = self[p].parent.clone();
self[p].parent = Parent::BinTree(v);
} else {
unreachable!();
};
}
fn side(&self, v: Label<Node<V>>) -> bool {
let p = self[v].parent.unwrap();
if let Some(o) = self[p].children[1] {
o == v
if let Parent::BinTree(p) = self[v].parent {
if let Some(o) = self[p].children[1] {
o == v
} else {
false
}
} else {
false
unreachable!();
}
}
}
......@@ -174,7 +179,7 @@ mod tests {
// link nodes
lct[p].children[0] = Some(o);
lct[o].parent = Some(p);
lct[o].parent = Parent::BinTree(p);
// rotate
lct.rotate(o);
......@@ -185,8 +190,8 @@ mod tests {
assert_eq!(lct[p].children, [None, None]);
// check parents
assert_eq!(lct[o].parent, None);
assert_eq!(lct[p].parent, Some(o));
assert_eq!(lct[o].parent, Parent::Root);
assert_eq!(lct[p].parent, Parent::BinTree(o));
}
#[test]
......@@ -206,12 +211,12 @@ mod tests {
lct[o].children = [Some(a), Some(b)];
lct[p].children = [Some(o), Some(c)];
lct[g].children = [Some(p), Some(d)];
lct[o].parent = Some(p);
lct[p].parent = Some(g);
lct[a].parent = Some(o);
lct[b].parent = Some(o);
lct[c].parent = Some(p);
lct[d].parent = Some(g);
lct[o].parent = Parent::BinTree(p);
lct[p].parent = Parent::BinTree(g);
lct[a].parent = Parent::BinTree(o);
lct[b].parent = Parent::BinTree(o);
lct[c].parent = Parent::BinTree(p);
lct[d].parent = Parent::BinTree(g);
// rotate
lct.rotate(o);
......@@ -227,13 +232,13 @@ mod tests {
assert_eq!(lct[d].children, [None, None]);
// check parents
assert_eq!(lct[o].parent, Some(g));
assert_eq!(lct[p].parent, Some(o));
assert_eq!(lct[g].parent, None);
assert_eq!(lct[a].parent, Some(o));
assert_eq!(lct[b].parent, Some(p));
assert_eq!(lct[c].parent, Some(p));
assert_eq!(lct[d].parent, Some(g));
assert_eq!(lct[o].parent, Parent::BinTree(g));
assert_eq!(lct[p].parent, Parent::BinTree(o));
assert_eq!(lct[g].parent, Parent::Root);
assert_eq!(lct[a].parent, Parent::BinTree(o));
assert_eq!(lct[b].parent, Parent::BinTree(p));
assert_eq!(lct[c].parent, Parent::BinTree(p));
assert_eq!(lct[d].parent, Parent::BinTree(g));
}
#[test]
......@@ -253,12 +258,12 @@ mod tests {
lct[o].children = [Some(a), Some(b)];
lct[p].children = [Some(o), Some(c)];
lct[g].children = [Some(p), Some(d)];
lct[o].parent = Some(p);
lct[p].parent = Some(g);
lct[a].parent = Some(o);
lct[b].parent = Some(o);
lct[c].parent = Some(p);
lct[d].parent = Some(g);
lct[o].parent = Parent::BinTree(p);
lct[p].parent = Parent::BinTree(g);
lct[a].parent = Parent::BinTree(o);
lct[b].parent = Parent::BinTree(o);
lct[c].parent = Parent::BinTree(p);
lct[d].parent = Parent::BinTree(g);
// reverse origin
lct[o].flipped = true;
......@@ -278,13 +283,13 @@ mod tests {
assert_eq!(lct[d].children, [None, None]);
// check parents
assert_eq!(lct[o].parent, Some(g));
assert_eq!(lct[p].parent, Some(o));
assert_eq!(lct[g].parent, None);
assert_eq!(lct[a].parent, Some(p));
assert_eq!(lct[b].parent, Some(o));
assert_eq!(lct[c].parent, Some(p));
assert_eq!(lct[d].parent, Some(g));
assert_eq!(lct[o].parent, Parent::BinTree(g));
assert_eq!(lct[p].parent, Parent::BinTree(o));
assert_eq!(lct[g].parent, Parent::Root);
assert_eq!(lct[a].parent, Parent::BinTree(p));
assert_eq!(lct[b].parent, Parent::BinTree(o));
assert_eq!(lct[c].parent, Parent::BinTree(p));
assert_eq!(lct[d].parent, Parent::BinTree(g));
// check flipped
assert!(!lct[o].flipped);
......@@ -310,21 +315,21 @@ mod tests {
// link nodes
lct[b].children = [None, Some(c)];
lct[d].children = [None, Some(e)];
lct[c].parent = Some(b);
lct[e].parent = Some(d);
lct[b].path_parent = Some(a);
lct[d].path_parent = Some(c);
lct[c].parent = Parent::BinTree(b);
lct[e].parent = Parent::BinTree(d);
lct[b].parent = Parent::Path(a);
lct[d].parent = Parent::Path(c);
// expose
lct.expose(d);
dbg!(&lct);
// check path parents
assert_eq!(lct[a].path_parent, None);
assert_eq!(lct[b].path_parent, None);
assert_eq!(lct[c].path_parent, None);
assert_eq!(lct[d].path_parent, None);
assert_eq!(lct[e].path_parent, Some(d));
// check parents
assert_eq!(lct[a].parent, Parent::BinTree(d));
assert_eq!(lct[b].parent, Parent::BinTree(c));
assert_eq!(lct[c].parent, Parent::BinTree(a));
assert_eq!(lct[d].parent, Parent::Root);
assert_eq!(lct[e].parent, Parent::Path(d));
}
#[test]
......@@ -344,12 +349,12 @@ mod tests {
lct[o].children = [Some(a), Some(b)];
lct[p].children = [Some(o), Some(c)];
lct[g].children = [Some(p), Some(d)];
lct[o].parent = Some(p);
lct[p].parent = Some(g);
lct[a].parent = Some(o);
lct[b].parent = Some(o);
lct[c].parent = Some(p);
lct[d].parent = Some(g);
lct[o].parent = Parent::BinTree(p);
lct[p].parent = Parent::BinTree(g);
lct[a].parent = Parent::BinTree(o);
lct[b].parent = Parent::BinTree(o);
lct[c].parent = Parent::BinTree(p);
lct[d].parent = Parent::BinTree(g);
// find root
assert_eq!(lct.find_root(g), a);
......@@ -369,25 +374,25 @@ mod tests {
// link nodes
lct[b].children = [None, Some(c)];
lct[d].children = [None, Some(e)];
lct[c].parent = Some(b);
lct[e].parent = Some(d);
lct[b].path_parent = Some(a);
lct[d].path_parent = Some(c);
lct[c].parent = Parent::BinTree(b);
lct[e].parent = Parent::BinTree(d);
lct[b].parent = Parent::Path(a);
lct[d].parent = Parent::Path(c);
// cut
lct.cut(c);
dbg!(&lct);
assert_eq!(lct[c].children[0], None);
assert_eq!(lct[c].path_parent, None);
assert_eq!(lct[c].parent, Parent::Root);
assert_eq!(lct[b].children[1], None);
// link
lct.link(b, c);
dbg!(&lct);
assert_eq!(lct[b].parent, Some(c));
assert_eq!(lct[b].parent, Parent::BinTree(c));
assert_eq!(lct[c].children, [Some(b), None]);
assert_eq!(lct[c].parent, None);
assert_eq!(lct[d].path_parent, Some(c));
assert_eq!(lct[c].parent, Parent::Root);
assert_eq!(lct[d].parent, Parent::Path(c));
}
#[test]
......@@ -407,18 +412,16 @@ mod tests {
lct[o].children = [Some(a), Some(b)];
lct[p].children = [Some(o), Some(c)];
lct[g].children = [Some(p), Some(d)];
lct[o].parent = Some(p);
lct[p].parent = Some(g);
lct[a].parent = Some(o);
lct[b].parent = Some(o);
lct[c].parent = Some(p);
lct[d].parent = Some(g);
lct[o].parent = Parent::BinTree(p);
lct[p].parent = Parent::BinTree(g);
lct[a].parent = Parent::BinTree(o);
lct[b].parent = Parent::BinTree(o);
lct[c].parent = Parent::BinTree(p);
lct[d].parent = Parent::BinTree(g);
// evert
lct.evert(o);
dbg!(&lct);
lct.expose(g);
dbg!(&lct);
assert_eq!(lct.find_root(g), 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