Commit 222df455 authored by tgerstel's avatar tgerstel
Browse files

added depth

parent 369f3e1b
use std::ops::{Index, IndexMut};
use std::{
fmt::Debug,
ops::{Index, IndexMut},
};
use super::collections::{Label, Pool};
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Node<V> {
value: V,
parent: Parent<V>,
children: Children<V>,
flipped: bool,
#[derive(Debug, PartialEq)]
enum Parent<V> {
Path(Label<Node<V>>),
BinTree(Label<Node<V>>),
Root,
}
impl<V> Copy for Parent<V> {}
impl<V> Clone for Parent<V> {
fn clone(&self) -> Parent<V> {
*self
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
struct Children<V>(Option<Label<Node<V>>>, Option<Label<Node<V>>>);
impl<V: Clone> Index<bool> for Children<V> {
impl<V> Index<bool> for Children<V> {
type Output = Option<Label<Node<V>>>;
fn index(&self, side: bool) -> &Self::Output {
......@@ -24,7 +34,7 @@ impl<V: Clone> Index<bool> for Children<V> {
}
}
impl<V: Clone> IndexMut<bool> for Children<V> {
impl<V> IndexMut<bool> for Children<V> {
fn index_mut(&mut self, side: bool) -> &mut Self::Output {
match side {
false => &mut self.0,
......@@ -34,127 +44,134 @@ impl<V: Clone> IndexMut<bool> for Children<V> {
}
#[derive(Debug, Clone, Copy, PartialEq)]
enum Parent<V> {
Path(Label<Node<V>>),
BinTree(Label<Node<V>>),
Root,
pub struct Node<V> {
value: V,
parent: Parent<V>,
children: Children<V>,
flipped: bool,
depth: usize,
}
impl<V: Clone> Pool<Node<V>> {
impl<V: Debug> Pool<Node<V>> {
pub fn add_node(&mut self, value: V) -> Label<Node<V>> {
self.insert(Node {
value,
parent: Parent::Root,
children: Children(None, None),
flipped: false,
depth: 0,
})
}
pub fn find_root(&mut self, v: Label<Node<V>>) -> Label<Node<V>> {
self.expose(v);
let mut r = v;
let mut flipped = self[v].flipped;
while let Some(w) = self[r].children[flipped] {
r = w;
flipped ^= self[w].flipped;
pub fn find_root(&mut self, u: Label<Node<V>>) -> Label<Node<V>> {
self.expose(u);
let mut x = u;
let mut flipped = self[u].flipped;
while let Some(y) = self[x].children[flipped] {
x = y;
flipped ^= self[x].flipped;
}
self.expose(r);
r
self.expose(x);
x
}
pub fn cut(&mut self, v: Label<Node<V>>) {
self.expose(v);
let flipped = self[v].flipped;
if let Some(l) = self[v].children[flipped] {
self[l].parent = Parent::Root;
self[v].children[flipped] = None;
pub fn cut(&mut self, c: Label<Node<V>>) {
self.expose(c);
let flipped = self[c].flipped;
if let Some(p) = self[c].children[flipped] {
self[p].parent = Parent::Root;
self[c].children[flipped] = None;
self[p].depth = self[c].depth - 1;
self[c].depth = 0;
}
}
pub fn link(&mut self, p: Label<Node<V>>, c: Label<Node<V>>) {
self.expose(c);
self.expose(p);
let c_flipped = self[c].flipped;
self[c].children[c_flipped] = Some(p);
let flipped = self[c].flipped;
self[c].children[flipped] = Some(p);
self[p].parent = Parent::BinTree(c);
self[c].depth = self[p].depth + 1;
self[p].depth = 1;
}
pub fn evert(&mut self, v: Label<Node<V>>) {
self.expose(v);
self[v].flipped = !self[v].flipped;
pub fn evert(&mut self, u: Label<Node<V>>) {
self.expose(u);
self[u].flipped = !self[u].flipped;
}
pub fn first_ancestor(&mut self, v: Label<Node<V>>, w: Label<Node<V>>) -> Label<Node<V>> {
pub fn first_ancestor(&mut self, u: Label<Node<V>>, v: Label<Node<V>>) -> Label<Node<V>> {
self.expose(u);
self.expose(v);
self.expose(w);
let mut x = v;
while let Parent::BinTree(p) = self[x].parent {
if x == w {
return w;
}
x = p;
let mut x = u;
while let Parent::BinTree(y) = self[x].parent {
x = y;
}
match self[x].parent {
Parent::BinTree(_) => unreachable!(),
Parent::Path(p) => p,
Parent::Path(y) => y,
Parent::Root => v,
}
}
pub fn value_mut(&mut self, v: Label<Node<V>>) -> &mut V {
&mut self[v].value
pub fn value_mut(&mut self, u: Label<Node<V>>) -> &mut V {
&mut self[u].value
}
pub fn value(&self, v: Label<Node<V>>) -> &V {
&self[v].value
pub fn value(&self, u: Label<Node<V>>) -> &V {
&self[u].value
}
fn expose(&mut self, v: Label<Node<V>>) {
self.splay(v);
if let Some(r) = self[v].children[true] {
self[r].parent = Parent::Path(v);
self[v].children[true] = None;
fn expose(&mut self, u: Label<Node<V>>) {
self.splay(u);
if let Some(c) = self[u].children[true] {
self[c].parent = Parent::Path(u);
self[u].children[true] = None;
}
while let Parent::Path(p) = self[v].parent {
while let Parent::Path(p) = self[u].parent {
self.splay(p);
if let Some(r) = self[p].children[true] {
self[r].parent = Parent::Path(p);
if let Some(x) = self[p].children[true] {
self[x].parent = Parent::Path(p);
}
self[p].children[true] = Some(v);
self[v].parent = Parent::BinTree(p);
self.rotate(v);
self[p].children[true] = Some(u);
self[u].parent = Parent::BinTree(p);
self.rotate(u);
}
}
fn splay(&mut self, v: Label<Node<V>>) {
self.cascade_flipped(v);
while let Parent::BinTree(p) = self[v].parent {
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 {
if self[p].flipped == (self.side(v) == self.side(p)) {
if self[p].flipped == (self.side(u) == self.side(p)) {
self.rotate(p);
self.rotate(v);
self.rotate(u);
} else {
self.rotate(v);
self.rotate(v);
self.rotate(u);
self.rotate(u);
};
} else {
self.rotate(v);
self.rotate(u);
break;
}
}
}
fn cascade_flipped(&mut self, v: Label<Node<V>>) {
if let Parent::BinTree(p) = self[v].parent {
fn cascade_flipped(&mut self, u: Label<Node<V>>) {
if let Parent::BinTree(p) = self[u].parent {
self.cascade_flipped(p);
}
if self[v].flipped {
let Children(a_opt, b_opt) = self[v].children;
self[v].children = Children(b_opt, a_opt);
self[v].flipped = false;
if self[u].flipped {
let Children(a_opt, b_opt) = self[u].children;
self[u].children = Children(b_opt, a_opt);
self[u].flipped = false;
if let Some(a) = a_opt {
self[a].flipped = !self[a].flipped;
}
......@@ -164,37 +181,57 @@ impl<V: Clone> Pool<Node<V>> {
}
}
fn rotate(&mut self, v: Label<Node<V>>) {
let p_side = self.side(v);
if let Parent::BinTree(p) = self[v].parent {
fn rotate(&mut self, u: Label<Node<V>>) {
let u_side = self.side(u);
let x_opt = self[u].children[!u_side];
if let Parent::BinTree(p) = self[u].parent {
let u_depth = self[u].depth;
let p_depth = self[p].depth;
self[p].depth = u_depth;
self[u].depth = if let Parent::BinTree(_) = self[p].parent {
if self[p].flipped ^ (self.side(u) == self.side(p)) {
u_depth + p_depth
} else {
u_depth.abs_diff(p_depth)
}
} else {
u_depth.abs_diff(p_depth)
};
if let Some(x) = x_opt {
let x_depth = self[x].depth;
self[x].depth = x_depth.abs_diff(u_depth);
}
if let Parent::BinTree(g) = self[p].parent {
let g_side = self.side(p);
self[g].children[g_side] = Some(v);
let p_side = self.side(p);
self[g].children[p_side] = Some(u);
}
let b_opt = self[v].children[!p_side];
self[p].children[p_side] = b_opt;
self[v].children[!p_side] = Some(p);
self[p].children[u_side] = x_opt;
self[u].children[!u_side] = Some(p);
if let Some(b) = b_opt {
self[b].parent = Parent::BinTree(p);
if let Some(x) = x_opt {
self[x].parent = Parent::BinTree(p);
}
self[v].parent = self[p].parent.clone();
self[p].parent = Parent::BinTree(v);
self[u].parent = self[p].parent;
self[p].parent = Parent::BinTree(u);
} else {
unreachable!();
};
}
fn side(&self, v: Label<Node<V>>) -> bool {
if let Parent::BinTree(p) = self[v].parent {
if let Some(o) = self[p].children[true] {
o == 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
}
} else {
//dbg!(&self[u]);
unreachable!();
}
}
......@@ -404,38 +441,18 @@ mod tests {
}
#[test]
fn cut_link() {
let mut lct = Pool::with_capacity(5);
fn link_cut() {
let mut lct = Pool::with_capacity(2);
// define nodes
let a = lct.add_node("a");
let b = lct.add_node("b");
let c = lct.add_node("c");
let d = lct.add_node("d");
let e = lct.add_node("e");
// 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[b].parent = Parent::Path(a);
lct[d].parent = Parent::Path(c);
// cut
lct.cut(c);
dbg!(&lct);
assert_eq!(lct[c].children[false], None);
assert_eq!(lct[c].parent, Parent::Root);
assert_eq!(lct[b].children[true], None);
lct.link(a, b);
// link
lct.link(b, c);
dbg!(&lct);
assert_eq!(lct[b].parent, Parent::BinTree(c));
assert_eq!(lct[c].children, Children(Some(b), None));
assert_eq!(lct[c].parent, Parent::Root);
assert_eq!(lct[d].parent, Parent::Path(c));
// cut nodes
lct.cut(b);
}
#[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