Commit d4530758 authored by SirBlueRabbit's avatar SirBlueRabbit
Browse files

fixed evert

parent 7ae1d5f6
......@@ -20,118 +20,132 @@ impl<V> Pool<Node<V>> {
})
}
pub fn find_root(&mut self, label: Label<Node<V>>) -> Label<Node<V>> {
self.expose(label);
let mut root = label;
let mut flipped = self[label].flipped;
while let Some(next) = self[root].children[usize::from(flipped)] {
root = next;
flipped ^= self[next].flipped;
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[usize::from(flipped)] {
r = w;
flipped ^= self[w].flipped;
}
self.expose(root);
root
self.expose(r);
r
}
pub fn cut(&mut self, label: Label<Node<V>>) {
self.expose(label);
let flipped = self[label].flipped;
if let Some(left_label) = self[label].children[usize::from(flipped)] {
self[left_label].parent = None;
self[label].children[usize::from(flipped)] = None;
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)] {
self[l].parent = None;
self[v].children[usize::from(flipped)] = None;
}
}
pub fn link(&mut self, parent_label: Label<Node<V>>, child_label: Label<Node<V>>) {
self.expose(child_label);
self.expose(parent_label);
let child_flipped = self[child_label].flipped;
self[child_label].children[usize::from(child_flipped)] = Some(parent_label);
self[parent_label].parent = Some(child_label);
pub fn link(&mut self, p: Label<Node<V>>, c: Label<Node<V>>) {
self.expose(c);
self.expose(p);
let child_flipped = self[c].flipped;
self[c].children[usize::from(child_flipped)] = Some(p);
self[p].parent = Some(c);
}
pub fn evert(&mut self, label: Label<Node<V>>) {
self.expose(label);
self[label].flipped = !self[label].flipped;
pub fn evert(&mut self, v: Label<Node<V>>) {
self.expose(v);
self[v].flipped = !self[v].flipped;
}
pub fn value_mut(&mut self, label: Label<Node<V>>) -> &mut V {
&mut self[label].value
pub fn value_mut(&mut self, v: Label<Node<V>>) -> &mut V {
&mut self[v].value
}
pub fn value(&self, label: Label<Node<V>>) -> &V {
&self[label].value
pub fn value(&self, v: Label<Node<V>>) -> &V {
&self[v].value
}
fn expose(&mut self, v: Label<Node<V>>) {
self.splay(v);
let v_not_flipped = !self[v].flipped;
if let Some(r) = self[v].children[usize::from(v_not_flipped)] {
if let Some(r) = self[v].children[1] {
self[r].path_parent = Some(v);
self[r].parent = None;
self[v].children[usize::from(v_not_flipped)] = None;
self[v].children[1] = None;
}
while let Some(p) = self[v].path_parent {
self.splay(p);
let p_not_flipped = !self[p].flipped;
if let Some(r) = self[p].children[usize::from(p_not_flipped)] {
if let Some(r) = self[p].children[1] {
self[r].path_parent = Some(p);
self[r].parent = None;
}
self[p].children[usize::from(p_not_flipped)] = Some(v);
self[p].children[1] = Some(v);
self[v].parent = Some(p);
self[v].path_parent = None;
self.rotate(v);
}
}
pub fn splay(&mut self, label: Label<Node<V>>) {
while let Some(p_label) = self[label].parent {
if self[p_label].parent.is_some() {
if self[p_label].flipped
== (self.is_zero_child(label) == self.is_zero_child(p_label))
{
self.rotate(p_label);
self.rotate(label);
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() {
if self[p].flipped == (self.is_zero_child(v) == self.is_zero_child(p)) {
self.rotate(p);
self.rotate(v);
} else {
self.rotate(label);
self.rotate(label);
self.rotate(v);
self.rotate(v);
};
} else {
self.rotate(label);
self.rotate(v);
break;
}
}
}
fn rotate(&mut self, label: Label<Node<V>>) {
let flipped = self[label].flipped;
let p_side = !self.is_zero_child(label);
let p_label = self[label].parent.unwrap();
let b_option = self[label].children[usize::from(flipped ^ !p_side)];
let g_option = self[p_label].parent;
self[label].parent = g_option;
if let Some(g_label) = g_option {
let g_side = !self.is_zero_child(p_label);
self[g_label].children[usize::from(g_side)] = Some(label);
fn cascade_flipped(&mut self, v: Label<Node<V>>) {
if let Some(p) = self[v].parent {
self.cascade_flipped(p);
}
if self[v].flipped {
let [a_opt, b_opt] = self[v].children;
self[v].children = [b_opt, a_opt];
self[v].flipped = false;
if let Some(a) = a_opt {
self[a].flipped = !self[a].flipped;
}
if let Some(b) = b_opt {
self[b].flipped = !self[b].flipped;
}
}
}
fn rotate(&mut self, v: Label<Node<V>>) {
let p_side = !self.is_zero_child(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.is_zero_child(p);
self[g].children[usize::from(g_side)] = Some(v);
} else {
self[label].path_parent = self[p_label].path_parent;
self[p_label].path_parent = None;
self[v].path_parent = self[p].path_parent;
self[p].path_parent = None;
}
self[p_label].children[usize::from(p_side)] = b_option;
self[label].children[usize::from(flipped ^ !p_side)] = Some(p_label);
self[p].children[usize::from(p_side)] = b_opt;
self[v].children[usize::from(!p_side)] = Some(p);
if let Some(b_label) = b_option {
self[b_label].parent = Some(p_label);
if let Some(b) = b_opt {
self[b].parent = Some(p);
}
self[p_label].parent = Some(label);
self[p].parent = Some(v);
}
fn is_zero_child(&self, label: Label<Node<V>>) -> bool {
let parent_label = self[label].parent.unwrap();
if let Some(zero_child_label) = self[parent_label].children[0] {
zero_child_label == label
fn is_zero_child(&self, v: Label<Node<V>>) -> bool {
let p = self[v].parent.unwrap();
if let Some(z) = self[p].children[0] {
z == v
} else {
false
}
......@@ -250,11 +264,12 @@ mod tests {
lct[o].flipped = true;
// rotate
lct.cascade_flipped(o);
lct.rotate(o);
dbg!(&lct);
// check children
assert_eq!(lct[o].children, [Some(p), Some(b)]);
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]);
......@@ -270,6 +285,15 @@ mod tests {
assert_eq!(lct[b].parent, Some(o));
assert_eq!(lct[c].parent, Some(p));
assert_eq!(lct[d].parent, Some(g));
// check flipped
assert!(!lct[o].flipped);
assert!(!lct[p].flipped);
assert!(!lct[g].flipped);
assert!(lct[a].flipped);
assert!(lct[b].flipped);
assert!(!lct[c].flipped);
assert!(!lct[d].flipped);
}
#[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