Commit ab5aa29e authored by SirBlueRabbit's avatar SirBlueRabbit
Browse files

add left-right, still broken

parent 54fac573
......@@ -8,7 +8,8 @@ use super::collections::{Label, Pool};
enum Parent<V> {
Path(Label<Node<V>>),
BinTree(Label<Node<V>>),
Left(Label<Node<V>>),
Right(Label<Node<V>>),
Root,
}
......@@ -27,8 +28,12 @@ impl<V> fmt::Debug for Parent<V> {
.debug_struct("Parent::Path")
.field("label", label)
.finish(),
Parent::BinTree(label) => f
.debug_struct("Parent::BinTree")
Parent::Left(label) => f
.debug_struct("Parent::Left")
.field("label", label)
.finish(),
Parent::Right(label) => f
.debug_struct("Parent::Right")
.field("label", label)
.finish(),
Parent::Root => f.debug_struct("Parent::Root").finish(),
......@@ -39,25 +44,35 @@ impl<V> fmt::Debug for Parent<V> {
impl<V> PartialEq for Parent<V> {
fn eq(&self, other: &Self) -> bool {
match self {
Parent::Path(label1) => {
if let Parent::Path(label2) = other {
label1 == label2
} else {
false
}
}
Parent::BinTree(label1) => {
if let Parent::BinTree(label2) = other {
label1 == label2
} else {
false
}
}
Parent::Path(label1) => match other {
Parent::Path(label2) => label1 == label2,
_ => false,
},
Parent::Left(label1) => match other {
Parent::Left(label2) => label1 == label2,
Parent::Right(label2) => label1 == label2,
_ => false,
},
Parent::Right(label1) => match other {
Parent::Left(label2) => label1 == label2,
Parent::Right(label2) => label1 == label2,
_ => false,
},
Parent::Root => matches!(other, Parent::Root),
}
}
}
impl<V> Parent<V> {
fn from_bool(side: bool, label: Label<Node<V>>) -> Self {
if side {
Parent::Right(label)
} else {
Parent::Left(label)
}
}
}
#[derive(Copy, Clone, Debug, PartialEq)]
enum ChildType {
Left,
......@@ -74,6 +89,14 @@ impl ChildType {
_ => None,
}
}
fn as_bool(&self) -> Option<bool> {
match self {
ChildType::Left => Some(false),
ChildType::Right => Some(true),
_ => None,
}
}
}
impl From<bool> for ChildType {
......@@ -160,7 +183,7 @@ impl<V> Pool<Node<V>> {
self.expose(p);
let d_flip = self[c].d_flip;
self[c].children[ChildType::from(d_flip)] = Some(p);
self[p].parent = Parent::BinTree(c);
self[p].parent = Parent::from_bool(d_flip, c);
self[c].d_depth = self[p].d_depth + 1;
self[p].d_depth = 1;
......@@ -196,23 +219,24 @@ impl<V> Pool<Node<V>> {
// always expose before indexing
pub fn index_depth(&self, u: Label<Node<V>>, i: usize) -> Label<Node<V>> {
assert!(i <= self.depth(u));
let mut label = u;
let mut x = u;
let mut flip = self[u].d_flip;
let mut depth = self[u].d_depth;
loop {
let side = match i.cmp(&depth) {
Ordering::Less => flip,
Ordering::Equal => return label,
Ordering::Equal => return x,
Ordering::Greater => !flip,
};
label = self[label].children[ChildType::from(side)].unwrap();
x = self[x].children[ChildType::from(side)].unwrap();
if flip ^ side {
depth += self[label].d_depth;
depth += self[x].d_depth;
} else {
depth -= self[label].d_depth;
depth -= self[x].d_depth;
}
flip ^= self[label].d_flip;
flip ^= self[x].d_flip;
}
}
......@@ -239,15 +263,15 @@ impl<V> Pool<Node<V>> {
self[x].parent = Parent::Path(u);
}
if let Some(c) = c_opt {
self[c].parent = Parent::BinTree(u);
self[c].parent = Parent::from_bool(true, u);
}
self[u].children[ChildType::from(true)] = c_opt;
}
fn splay(&mut self, u: Label<Node<V>>) {
self.cascade_flipped(u);
while let Parent::BinTree(p) = self[u].parent {
if let Parent::BinTree(_) = self[p].parent {
while let Some(p) = self.bintree_parent(u) {
if let Some(_) = self.bintree_parent(p) {
if self[p].d_flip == (self.child_type(u) == self.child_type(p)) {
self.rotate(p);
self.rotate(u);
......@@ -263,7 +287,7 @@ impl<V> Pool<Node<V>> {
}
fn cascade_flipped(&mut self, u: Label<Node<V>>) {
if let Parent::BinTree(p) = self[u].parent {
if let Some(p) = self.bintree_parent(u) {
self.cascade_flipped(p);
}
......@@ -283,12 +307,12 @@ impl<V> Pool<Node<V>> {
fn rotate(&mut self, u: Label<Node<V>>) {
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 {
if let Some(p) = self.bintree_parent(u) {
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 {
self[u].d_depth = if let Some(_) = self.bintree_parent(p) {
if self[p].d_flip ^ (self.child_type(u) == self.child_type(p)) {
u_d_depth + p_d_depth
} else {
......@@ -319,7 +343,7 @@ impl<V> Pool<Node<V>> {
self[x].d_depth = x_d_depth.abs_diff(u_d_depth);
}
if let Parent::BinTree(g) = self[p].parent {
if let Some(g) = self.bintree_parent(p) {
let p_child_type = self.child_type(p);
self[g].children[p_child_type] = Some(u);
}
......@@ -328,11 +352,11 @@ impl<V> Pool<Node<V>> {
self[u].children[u_child_type.mirror().unwrap()] = Some(p);
if let Some(x) = x_opt {
self[x].parent = Parent::BinTree(p);
self[x].parent = Parent::from_bool(u_child_type.as_bool().unwrap(), p);
}
self[u].parent = self[p].parent;
self[p].parent = Parent::BinTree(u);
self[p].parent = Parent::from_bool(!u_child_type.as_bool().unwrap(), u);
} else {
unreachable!();
};
......@@ -340,20 +364,8 @@ impl<V> Pool<Node<V>> {
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!();
}
Parent::Left(_) => ChildType::Left,
Parent::Right(_) => ChildType::Right,
Parent::Path(_) => ChildType::Path,
Parent::Root => ChildType::Root,
}
......@@ -361,11 +373,21 @@ impl<V> Pool<Node<V>> {
fn parent(&self, u: Label<Node<V>>) -> Option<Label<Node<V>>> {
match self[u].parent {
Parent::BinTree(parent) => Some(parent),
Parent::Left(parent) => Some(parent),
Parent::Right(parent) => Some(parent),
Parent::Path(parent) => Some(parent),
Parent::Root => None,
}
}
fn bintree_parent(&self, u: Label<Node<V>>) -> Option<Label<Node<V>>> {
match self[u].parent {
Parent::Left(parent) => Some(parent),
Parent::Right(parent) => Some(parent),
Parent::Path(_) => None,
Parent::Root => None,
}
}
}
#[cfg(test)]
......@@ -390,7 +412,7 @@ mod tests {
// link nodes
lct[p].children[ChildType::from(false)] = Some(o);
lct[o].parent = Parent::BinTree(p);
lct[o].parent = Parent::Left(p);
// rotate
lct.rotate(o);
......@@ -401,7 +423,7 @@ mod tests {
// check parents
assert_eq!(lct[o].parent, Parent::Root);
assert_eq!(lct[p].parent, Parent::BinTree(o));
assert_eq!(lct[p].parent, Parent::Right(o));
}
#[test]
......@@ -421,12 +443,12 @@ mod tests {
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);
lct[b].parent = Parent::BinTree(o);
lct[c].parent = Parent::BinTree(p);
lct[d].parent = Parent::BinTree(g);
lct[o].parent = Parent::Left(p);
lct[p].parent = Parent::Left(g);
lct[a].parent = Parent::Left(o);
lct[b].parent = Parent::Right(o);
lct[c].parent = Parent::Right(p);
lct[d].parent = Parent::Right(g);
// rotate
lct.rotate(o);
......@@ -442,13 +464,13 @@ mod tests {
assert_eq!(lct[d].children, Children(None, None));
// check parents
assert_eq!(lct[o].parent, Parent::BinTree(g));
assert_eq!(lct[p].parent, Parent::BinTree(o));
assert_eq!(lct[o].parent, Parent::Left(g));
assert_eq!(lct[p].parent, Parent::Right(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));
assert_eq!(lct[a].parent, Parent::Left(o));
assert_eq!(lct[b].parent, Parent::Left(p));
assert_eq!(lct[c].parent, Parent::Right(p));
assert_eq!(lct[d].parent, Parent::Right(g));
}
#[test]
......@@ -468,12 +490,12 @@ mod tests {
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);
lct[b].parent = Parent::BinTree(o);
lct[c].parent = Parent::BinTree(p);
lct[d].parent = Parent::BinTree(g);
lct[o].parent = Parent::Left(p);
lct[p].parent = Parent::Left(g);
lct[a].parent = Parent::Left(o);
lct[b].parent = Parent::Right(o);
lct[c].parent = Parent::Right(p);
lct[d].parent = Parent::Right(g);
// reverse origin
lct[o].d_flip = true;
......@@ -493,13 +515,13 @@ mod tests {
assert_eq!(lct[d].children, Children(None, None));
// check parents
assert_eq!(lct[o].parent, Parent::BinTree(g));
assert_eq!(lct[p].parent, Parent::BinTree(o));
assert_eq!(lct[o].parent, Parent::Left(g));
assert_eq!(lct[p].parent, Parent::Right(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));
assert_eq!(lct[a].parent, Parent::Left(p));
assert_eq!(lct[b].parent, Parent::Left(o));
assert_eq!(lct[c].parent, Parent::Right(p));
assert_eq!(lct[d].parent, Parent::Right(g));
// check flipped
assert!(!lct[o].d_flip);
......@@ -525,8 +547,8 @@ mod tests {
// link nodes
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[c].parent = Parent::Right(b);
lct[e].parent = Parent::Right(d);
lct[b].parent = Parent::Path(a);
lct[d].parent = Parent::Path(c);
......@@ -535,9 +557,9 @@ mod tests {
dbg!(&lct);
// 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[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));
}
......@@ -559,12 +581,12 @@ mod tests {
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);
lct[b].parent = Parent::BinTree(o);
lct[c].parent = Parent::BinTree(p);
lct[d].parent = Parent::BinTree(g);
lct[o].parent = Parent::Left(p);
lct[p].parent = Parent::Left(g);
lct[a].parent = Parent::Left(o);
lct[b].parent = Parent::Right(o);
lct[c].parent = Parent::Right(p);
lct[d].parent = Parent::Right(g);
// find root
assert_eq!(lct.find_root(g), a);
......@@ -602,12 +624,12 @@ mod tests {
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);
lct[b].parent = Parent::BinTree(o);
lct[c].parent = Parent::BinTree(p);
lct[d].parent = Parent::BinTree(g);
lct[o].parent = Parent::Left(p);
lct[p].parent = Parent::Left(g);
lct[a].parent = Parent::Left(o);
lct[b].parent = Parent::Right(o);
lct[c].parent = Parent::Right(p);
lct[d].parent = Parent::Right(g);
// evert
lct.evert(o);
......@@ -641,6 +663,9 @@ mod tests {
assert_eq!(lct.depth(Label::from(0)), 1);
assert_eq!(lct.depth(Label::from(1)), 0);
assert_eq!(lct.depth(Label::from(2)), 1);
// check clean
assert_clean(&lct);
}
#[test]
......@@ -659,6 +684,9 @@ mod tests {
// check depth
assert_eq!(lct.depth(a), 0);
assert_eq!(lct.depth(b), 1);
// check clean
assert_clean(&lct);
}
#[test]
......@@ -680,6 +708,9 @@ mod tests {
assert_eq!(lct.depth(a), 0);
assert_eq!(lct.depth(b), 1);
assert_eq!(lct.depth(c), 2);
// check clean
assert_clean(&lct);
}
#[test]
......@@ -701,6 +732,9 @@ mod tests {
assert_eq!(lct.depth(a), 0);
assert_eq!(lct.depth(b), 1);
assert_eq!(lct.depth(c), 2);
// check clean
assert_clean(&lct);
}
#[test]
......@@ -774,23 +808,23 @@ mod tests {
}
}
fn assert_clean<V>(lct: &Pool<Node<V>>) {
fn assert_clean<V: fmt::Debug>(lct: &Pool<Node<V>>) {
for label in lct.labels() {
// check parent reciprocrity
match lct[label].parent {
Parent::Root => (),
Parent::Path(_) => (),
Parent::BinTree(p) => {
assert!(lct[p].children.0 == Some(label) || lct[p].children.1 == Some(label))
}
Parent::Left(p) => assert_eq!(lct[p].children.0, Some(label)),
Parent::Right(p) => assert_eq!(lct[p].children.1, Some(label)),
}
// check child reciprocrity
if let Some(c) = lct[label].children.0 {
assert_eq!(lct[c].parent, Parent::BinTree(label));
assert_eq!(lct[c].parent, Parent::Left(label));
}
if let Some(c) = lct[label].children.1 {
assert_eq!(lct[c].parent, Parent::BinTree(label));
dbg!(&lct);
assert_eq!(lct[c].parent, Parent::Right(label));
}
}
}
......
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