Commit 0d86c77d authored by tgerstel's avatar tgerstel
Browse files

moved link cut tree

parent 4d2ed8de
use super::{Label, Pool};
use std::fmt::Debug;
use super::collections::{Label, Pool};
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Node<V> {
......@@ -23,32 +22,54 @@ impl<V> Node<V> {
}
impl<V> Pool<Node<V>> {
pub fn add_node(&mut self, value: V) -> Label<Node<V>> {
let node = Node::new(value);
self.insert(node)
pub fn find_root(&mut self, label: Label<Node<V>>) -> Label<Node<V>> {
self.expose(label);
let root = self.leftmost(label);
self.expose(root);
root
}
pub fn cut(&mut self, label: Label<Node<V>>) {
self.expose(label);
self.split_left(label);
}
pub fn link(&mut self, parent_label: Label<Node<V>>, child_label: Label<Node<V>>) {
self.expose(child_label);
self.expose(parent_label);
self.join_left(child_label, parent_label);
}
fn node_mut(&mut self, label: Label<Node<V>>) -> &mut Node<V> {
&mut self[label]
pub fn value_mut(&mut self, label: Label<Node<V>>) -> &mut V {
&mut self[label].value
}
pub fn value(&self, label: Label<Node<V>>) -> &V {
&self[label].value
}
pub fn parent(&self, label: Label<Node<V>>) -> Option<Label<Node<V>>> {
self[label].parent
pub fn add_node(&mut self, value: V) -> Label<Node<V>> {
let node = Node::new(value);
self.insert(node)
}
pub fn path_parent(&self, label: Label<Node<V>>) -> Option<Label<Node<V>>> {
self[label].path_parent
fn expose(&mut self, label: Label<Node<V>>) {
self.splay(label);
self.split_right_and_attach_new(label, None);
let mut v = label;
while let Some(w) = self[v].path_parent {
self.splay(w);
self.split_right_and_attach_new(w, v.into());
v = w;
}
self.splay(label);
}
pub fn left(&self, label: Label<Node<V>>) -> Option<Label<Node<V>>> {
fn left(&self, label: Label<Node<V>>) -> Option<Label<Node<V>>> {
self[label].left
}
pub fn right(&self, label: Label<Node<V>>) -> Option<Label<Node<V>>> {
fn right(&self, label: Label<Node<V>>) -> Option<Label<Node<V>>> {
self[label].right
}
......@@ -63,21 +84,13 @@ impl<V> Pool<Node<V>> {
current_label
}
pub fn root(&self, label: Label<Node<V>>) -> Label<Node<V>> {
self.while_some(label, |label| self.parent(label))
}
pub fn leftmost(&self, label: Label<Node<V>>) -> Label<Node<V>> {
fn leftmost(&self, label: Label<Node<V>>) -> Label<Node<V>> {
self.while_some(label, |label| self.left(label))
}
pub fn rightmost(&self, label: Label<Node<V>>) -> Label<Node<V>> {
self.while_some(label, |label| self.right(label))
}
fn is_left_child(&self, label: Label<Node<V>>) -> bool {
if let Some(self_label) = self
.parent(label)
if let Some(self_label) = self[label]
.parent
.map(|parent_label| self[parent_label].left)
.flatten()
{
......@@ -89,7 +102,7 @@ impl<V> Pool<Node<V>> {
fn update_parent(&mut self, old_root_label: Label<Node<V>>, new_root_label: Label<Node<V>>) {
let b_left = self.is_left_child(old_root_label);
if let Some(parent_label) = self.parent(old_root_label) {
if let Some(parent_label) = self[old_root_label].parent {
if b_left {
self.set_left(parent_label, Some(new_root_label))
} else {
......@@ -119,9 +132,9 @@ impl<V> Pool<Node<V>> {
}
}
pub fn rotate_up(&mut self, label: Label<Node<V>>) {
fn rotate_up(&mut self, label: Label<Node<V>>) {
let b_left = self.is_left_child(label);
if let Some(parent_label) = self.parent(label) {
if let Some(parent_label) = self[label].parent {
if b_left {
self.rotate_right(parent_label);
} else {
......@@ -130,21 +143,21 @@ impl<V> Pool<Node<V>> {
}
}
pub fn set_right(&mut self, parent_label: Label<Node<V>>, right_label: Option<Label<Node<V>>>) {
fn set_right(&mut self, parent_label: Label<Node<V>>, right_label: Option<Label<Node<V>>>) {
self[parent_label].right = right_label;
if let Some(label) = right_label {
self[label].parent = Some(parent_label);
}
}
pub fn set_left(&mut self, parent_label: Label<Node<V>>, left_label: Option<Label<Node<V>>>) {
fn set_left(&mut self, parent_label: Label<Node<V>>, left_label: Option<Label<Node<V>>>) {
self[parent_label].left = left_label;
if let Some(label) = left_label {
self[label].parent = Some(parent_label);
}
}
pub fn splay(&mut self, label: Label<Node<V>>) {
fn splay(&mut self, label: Label<Node<V>>) {
enum SplayType {
NoSplay,
Zig,
......@@ -153,8 +166,8 @@ impl<V> Pool<Node<V>> {
}
loop {
let splay_type = if let Some(parent_label) = self.parent(label) {
if self.parent(parent_label).is_some() {
let splay_type = if let Some(parent_label) = self[label].parent {
if self[parent_label].parent.is_some() {
if self.is_left_child(label) == self.is_left_child(parent_label) {
SplayType::ZigZig
} else {
......@@ -175,43 +188,41 @@ impl<V> Pool<Node<V>> {
self.rotate_up(label);
}
SplayType::ZigZig => {
self.rotate_up(self.parent(label).unwrap());
self.rotate_up(self[label].parent.unwrap());
self.rotate_up(label)
}
}
}
}
pub fn split_right_and_attach_new(
fn split_right_and_attach_new(
&mut self,
label: Label<Node<V>>,
new_right_label: Option<Label<Node<V>>>,
new_right: Option<Label<Node<V>>>,
) {
if let Some(right_label) = self.right(label) {
let right_node = self.node_mut(right_label);
right_node.path_parent = label.into();
right_node.parent = None;
self[right_label].path_parent = label.into();
self[right_label].parent = None;
}
self.node_mut(label).right = new_right_label;
if let Some(new_right_index) = new_right_label {
let new_right = self.node_mut(new_right_index);
new_right.parent = label.into();
new_right.path_parent = None;
self[label].right = new_right;
if let Some(new_right_label) = new_right {
self[new_right_label].parent = label.into();
self[new_right_label].path_parent = None;
}
}
pub fn split_left(&mut self, label: Label<Node<V>>) {
fn split_left(&mut self, label: Label<Node<V>>) {
if let Some(left_label) = self.left(label) {
self.node_mut(left_label).parent = None;
self.node_mut(label).left = None;
self[left_label].parent = None;
self[label].left = None;
}
}
pub fn join_left(&mut self, label: Label<Node<V>>, left_label: Label<Node<V>>) {
assert_eq!(self.node_mut(label).left, None);
self.node_mut(label).left = left_label.into();
self.node_mut(left_label).parent = label.into();
fn join_left(&mut self, label: Label<Node<V>>, left_label: Label<Node<V>>) {
assert_eq!(self[label].left, None);
self[label].left = left_label.into();
self[left_label].parent = label.into();
}
}
......@@ -241,4 +252,135 @@ mod tests {
}
}
}
#[test]
fn basic_tree() {
let mut lct = Pool::with_capacity(10);
let node1 = lct.add_node("1");
assert_eq!(lct.find_root(node1), node1);
}
#[test]
fn multiple_roots() {
let mut lct = Pool::with_capacity(10);
let node1 = lct.add_node("1");
let node2 = lct.add_node("2");
assert_eq!(lct.find_root(node1), node1);
assert_eq!(lct.find_root(node2), node2);
assert_eq!(lct.find_root(node1), node1);
}
#[test]
fn link_basic() {
let mut lct = Pool::with_capacity(10);
let node1 = lct.add_node("1");
let node2 = lct.add_node("2");
lct.link(node1, node2);
assert_eq!(lct.find_root(node1), node1, "original root changed");
assert_eq!(lct.find_root(node2), node1, "new root not updated");
assert_eq!(
lct.find_root(node1),
node1,
"original root changed after one iteration"
);
assert_eq!(
lct.find_root(node1),
node1,
"original root changed after repetition"
);
assert_eq!(lct.find_root(node2), node1, "new root unupdated");
}
#[test]
fn link_multiple() {
let mut lct = Pool::with_capacity(10);
let node1 = lct.add_node(());
let node2 = lct.add_node(());
let node3 = lct.add_node(());
lct.link(node1, node2);
lct.link(node2, node3);
assert_eq!(lct.find_root(node3), node1, "Didn't find grandparent");
assert_eq!(lct.find_root(node2), node1, "Didn't find parent");
assert_eq!(lct.find_root(node2), node1, "Didn't find itself");
}
#[test]
fn many_links_to_one() {
let mut lct = Pool::with_capacity(10);
let node1 = lct.add_node(());
let children = (1..6).map(|_| lct.add_node(())).collect::<Vec<_>>();
for child in &children {
lct.link(node1, *child);
}
for child in &children {
assert_eq!(lct.find_root(*child), node1, "Wrong parent");
}
}
#[test]
fn many_links_to_one_root() {
let mut lct = Pool::with_capacity(15);
let root = lct.add_node(());
let mut all_nodes = vec![root];
let mut last_depth_nodes = vec![root];
let mut current_depth_nodes = vec![];
for _depth in 0..3 {
for parent_label in &last_depth_nodes {
for _ in 0..2 {
let child_label = lct.add_node(());
lct.link(*parent_label, child_label);
current_depth_nodes.push(child_label);
all_nodes.push(child_label);
}
}
last_depth_nodes.clear();
last_depth_nodes.append(&mut current_depth_nodes);
}
for node in all_nodes {
assert_eq!(
lct.find_root(node),
root,
"Failed on node: {:?}",
lct.value(node)
);
}
}
#[test]
fn test_cut_basic() {
let mut lct = Pool::with_capacity(10);
let node1 = lct.add_node(());
let node2 = lct.add_node(());
lct.link(node1, node2);
assert_eq!(lct.find_root(node1), node1, "original root changed");
assert_eq!(lct.find_root(node2), node1, "new root not updated");
lct.cut(node2);
assert_eq!(lct.find_root(node1), node1, "should still be its own root");
assert_eq!(
lct.find_root(node2),
node2,
"should be back to being its own root"
);
}
#[test]
fn many_cut_links() {
let mut lct = Pool::with_capacity(10);
let node1 = lct.add_node(());
let children = (1..6).map(|_| lct.add_node(())).collect::<Vec<_>>();
for child in &children {
lct.link(node1, *child);
}
for child in &children {
lct.cut(*child)
}
for child in &children {
assert_eq!(lct.find_root(*child), *child, "Wrong parent");
}
assert_eq!(lct.find_root(node1), node1);
}
}
mod splay_forest;
use super::collections::{Label, Pool};
pub use splay_forest::Node;
impl<V> Pool<Node<V>> {
fn expose(&mut self, label: Label<Node<V>>) {
self.splay(label);
self.split_right_and_attach_new(label, None);
let mut v = label;
while let Some(w) = self.path_parent(v) {
self.splay(w);
self.split_right_and_attach_new(w, v.into());
v = w;
}
self.splay(label);
}
pub fn find_root(&mut self, label: Label<Node<V>>) -> Label<Node<V>> {
self.expose(label);
let root = self.leftmost(label);
self.expose(root);
root
}
pub fn cut(&mut self, label: Label<Node<V>>) {
self.expose(label);
self.split_left(label);
}
pub fn link(&mut self, parent_label: Label<Node<V>>, child_label: Label<Node<V>>) {
self.expose(child_label);
self.expose(parent_label);
self.join_left(child_label, parent_label);
}
pub fn val(&mut self, label: Label<Node<V>>) -> &V {
self.value(label)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn basic_tree() {
let mut lct = Pool::with_capacity(10);
let node1 = lct.add_node("1");
assert_eq!(lct.find_root(node1), node1);
}
#[test]
fn multiple_roots() {
let mut lct = Pool::with_capacity(10);
let node1 = lct.add_node("1");
let node2 = lct.add_node("2");
assert_eq!(lct.find_root(node1), node1);
assert_eq!(lct.find_root(node2), node2);
assert_eq!(lct.find_root(node1), node1);
}
#[test]
fn link_basic() {
let mut lct = Pool::with_capacity(10);
let node1 = lct.add_node("1");
let node2 = lct.add_node("2");
lct.link(node1, node2);
assert_eq!(lct.find_root(node1), node1, "original root changed");
assert_eq!(lct.find_root(node2), node1, "new root not updated");
assert_eq!(
lct.find_root(node1),
node1,
"original root changed after one iteration"
);
assert_eq!(
lct.find_root(node1),
node1,
"original root changed after repetition"
);
assert_eq!(lct.find_root(node2), node1, "new root unupdated");
}
#[test]
fn link_multiple() {
let mut lct = Pool::with_capacity(10);
let node1 = lct.add_node(());
let node2 = lct.add_node(());
let node3 = lct.add_node(());
lct.link(node1, node2);
lct.link(node2, node3);
assert_eq!(lct.find_root(node3), node1, "Didn't find grandparent");
assert_eq!(lct.find_root(node2), node1, "Didn't find parent");
assert_eq!(lct.find_root(node2), node1, "Didn't find itself");
}
#[test]
fn many_links_to_one() {
let mut lct = Pool::with_capacity(10);
let node1 = lct.add_node(());
let children = (1..6).map(|_| lct.add_node(())).collect::<Vec<_>>();
for child in &children {
lct.link(node1, *child);
}
for child in &children {
assert_eq!(lct.find_root(*child), node1, "Wrong parent");
}
}
#[test]
fn many_links_to_one_root() {
let mut lct = Pool::with_capacity(15);
let root = lct.add_node(());
let mut all_nodes = vec![root];
let mut last_depth_nodes = vec![root];
let mut current_depth_nodes = vec![];
for _depth in 0..3 {
for parent_label in &last_depth_nodes {
for _ in 0..2 {
let child_label = lct.add_node(());
lct.link(*parent_label, child_label);
current_depth_nodes.push(child_label);
all_nodes.push(child_label);
}
}
last_depth_nodes.clear();
last_depth_nodes.append(&mut current_depth_nodes);
}
for node in all_nodes {
assert_eq!(
lct.find_root(node),
root,
"Failed on node: {:?}",
lct.val(node)
);
}
}
#[test]
fn test_cut_basic() {
let mut lct = Pool::with_capacity(10);
let node1 = lct.add_node(());
let node2 = lct.add_node(());
lct.link(node1, node2);
assert_eq!(lct.find_root(node1), node1, "original root changed");
assert_eq!(lct.find_root(node2), node1, "new root not updated");
lct.cut(node2);
assert_eq!(lct.find_root(node1), node1, "should still be its own root");
assert_eq!(
lct.find_root(node2),
node2,
"should be back to being its own root"
);
}
#[test]
fn many_cut_links() {
let mut lct = Pool::with_capacity(10);
let node1 = lct.add_node(());
let children = (1..6).map(|_| lct.add_node(())).collect::<Vec<_>>();
for child in &children {
lct.link(node1, *child);
}
for child in &children {
lct.cut(*child)
}
for child in &children {
assert_eq!(lct.find_root(*child), *child, "Wrong parent");
}
assert_eq!(lct.find_root(node1), node1);
}
}
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