Commit 4c92a7d1 authored by SirBlueRabbit's avatar SirBlueRabbit
Browse files

integrate pool into link cut tree

parent 3c925eaa
mod splay_forest;
pub use splay_forest::{NodeIdx, SplayForest};
use super::collections::{Label, Pool};
pub use splay_forest::Node;
use std::fmt::Debug;
pub struct LinkCutTree<V> {
rep: SplayForest<V>,
#[derive(Clone, Debug)]
pub struct LinkCutTree<V: Copy> {
rep: Pool<Node<V>>,
}
impl<V: Debug> Default for LinkCutTree<V> {
fn default() -> Self {
impl<V: Copy + PartialEq + Debug> LinkCutTree<V> {
pub fn with_capacity(capacity: usize) -> Self {
LinkCutTree {
rep: SplayForest::default(),
rep: Pool::<Node<V>>::with_capacity(capacity),
}
}
}
impl<V: Debug> LinkCutTree<V> {
pub fn make_tree(&mut self, val: V) -> NodeIdx {
pub fn make_tree(&mut self, val: V) -> Label<Node<V>> {
self.rep.add_node(val)
}
pub fn access(&mut self, node_idx: NodeIdx) {
pub fn expose(&mut self, node_idx: Label<Node<V>>) {
self.rep.splay(node_idx);
self.rep.split_right_and_attach_new(node_idx, None);
let mut v = node_idx;
loop {
match self.rep.get_path_parent(v) {
match self.rep.path_parent(v) {
None => {
break;
}
......@@ -39,26 +39,26 @@ impl<V: Debug> LinkCutTree<V> {
self.rep.splay(node_idx);
}
pub fn find_root(&mut self, node_idx: NodeIdx) -> NodeIdx {
self.access(node_idx);
let root = self.rep.get_leftmost(node_idx);
self.access(root);
pub fn find_root(&mut self, node_idx: Label<Node<V>>) -> Label<Node<V>> {
self.expose(node_idx);
let root = self.rep.leftmost(node_idx);
self.expose(root);
root
}
pub fn cut(&mut self, node_idx: NodeIdx) {
self.access(node_idx);
pub fn cut(&mut self, node_idx: Label<Node<V>>) {
self.expose(node_idx);
self.rep.split_left(node_idx);
}
pub fn link(&mut self, parent_idx: NodeIdx, child_idx: NodeIdx) {
self.access(child_idx);
self.access(parent_idx);
pub fn link(&mut self, parent_idx: Label<Node<V>>, child_idx: Label<Node<V>>) {
self.expose(child_idx);
self.expose(parent_idx);
self.rep.join_left(child_idx, parent_idx);
}
pub fn get_val(&mut self, node_idx: NodeIdx) -> &V {
self.rep.get_value(node_idx)
pub fn val(&mut self, node_idx: Label<Node<V>>) -> &V {
self.rep.value(node_idx)
}
}
......@@ -68,14 +68,14 @@ mod tests {
#[test]
fn basic_tree() {
let mut lct: LinkCutTree<&str> = LinkCutTree::default();
let mut lct: LinkCutTree<&str> = LinkCutTree::with_capacity(10);
let node1 = lct.make_tree("1");
assert_eq!(lct.find_root(node1), node1);
}
#[test]
fn multiple_roots() {
let mut lct: LinkCutTree<&str> = LinkCutTree::default();
let mut lct: LinkCutTree<&str> = LinkCutTree::with_capacity(10);
let node1 = lct.make_tree("1");
let node2 = lct.make_tree("2");
assert_eq!(lct.find_root(node1), node1);
......@@ -85,7 +85,7 @@ mod tests {
#[test]
fn link_basic() {
let mut lct: LinkCutTree<&str> = LinkCutTree::default();
let mut lct: LinkCutTree<&str> = LinkCutTree::with_capacity(10);
let node1 = lct.make_tree("1");
let node2 = lct.make_tree("2");
lct.link(node1, node2);
......@@ -106,10 +106,10 @@ mod tests {
#[test]
fn link_multiple() {
let mut lct: LinkCutTree<&str> = LinkCutTree::default();
let node1 = lct.make_tree("Grandparent");
let node2 = lct.make_tree("Parent");
let node3 = lct.make_tree("Child");
let mut lct: LinkCutTree<()> = LinkCutTree::with_capacity(10);
let node1 = lct.make_tree(());
let node2 = lct.make_tree(());
let node3 = lct.make_tree(());
lct.link(node1, node2);
lct.link(node2, node3);
assert_eq!(lct.find_root(node3), node1, "Didn't find grandparent");
......@@ -119,11 +119,9 @@ mod tests {
#[test]
fn many_links_to_one() {
let mut lct: LinkCutTree<String> = LinkCutTree::default();
let node1 = lct.make_tree("Parent".into());
let children = (1..6)
.map(|i| lct.make_tree(format!("Child {}", i)))
.collect::<Vec<_>>();
let mut lct: LinkCutTree<()> = LinkCutTree::with_capacity(10);
let node1 = lct.make_tree(());
let children = (1..6).map(|_| lct.make_tree(())).collect::<Vec<_>>();
for child in &children {
lct.link(node1, *child);
}
......@@ -135,16 +133,15 @@ mod tests {
#[test]
fn many_links_to_one_root() {
let mut lct: LinkCutTree<String> = LinkCutTree::default();
let root = lct.make_tree("Root".into());
let mut lct: LinkCutTree<()> = LinkCutTree::with_capacity(14);
let root = lct.make_tree(());
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_idx in &last_depth_nodes {
for child_num in 1..3 {
let child_name = format!("{}({})", lct.get_val(*parent_idx), child_num);
let child_idx = lct.make_tree(child_name);
for _ in 0..2 {
let child_idx = lct.make_tree(());
lct.link(*parent_idx, child_idx);
current_depth_nodes.push(child_idx);
all_nodes.push(child_idx);
......@@ -158,17 +155,17 @@ mod tests {
assert_eq!(
lct.find_root(node),
root,
"Failed on node: {}",
lct.get_val(node)
"Failed on node: {:?}",
lct.val(node)
);
}
}
#[test]
fn test_cut_basic() {
let mut lct: LinkCutTree<&str> = LinkCutTree::default();
let node1 = lct.make_tree("1");
let node2 = lct.make_tree("2");
let mut lct: LinkCutTree<()> = LinkCutTree::with_capacity(10);
let node1 = lct.make_tree(());
let node2 = lct.make_tree(());
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");
......@@ -183,11 +180,9 @@ mod tests {
#[test]
fn many_cut_links() {
let mut lct: LinkCutTree<String> = LinkCutTree::default();
let node1 = lct.make_tree("Parent".into());
let children = (1..6)
.map(|i| lct.make_tree(format!("Child {}", i)))
.collect::<Vec<_>>();
let mut lct: LinkCutTree<()> = LinkCutTree::with_capacity(10);
let node1 = lct.make_tree(());
let children = (1..6).map(|_| lct.make_tree(())).collect::<Vec<_>>();
for child in &children {
lct.link(node1, *child);
}
......
use std::collections::HashSet;
use std::convert::TryFrom;
use std::fmt;
use std::fmt::{Debug, Formatter};
use std::num::NonZeroUsize;
#[derive(PartialEq, Eq, Copy, Clone, Hash, Debug)]
pub struct NodeIdx(NonZeroUsize);
impl NodeIdx {
#[inline]
pub fn new(idx: usize) -> Self {
NodeIdx(NonZeroUsize::try_from(idx + 1).unwrap())
}
use super::{Label, Pool};
use std::fmt::Debug;
#[inline]
fn get(self) -> usize {
self.0.get() - 1
}
}
impl From<usize> for NodeIdx {
fn from(idx: usize) -> Self {
NodeIdx::new(idx)
}
}
#[derive(Debug)]
pub struct Node<V> {
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Node<V: Copy> {
value: V,
path_parent: Option<NodeIdx>,
parent: Option<NodeIdx>,
left: Option<NodeIdx>,
right: Option<NodeIdx>,
}
struct NodeDebug<'a, V> {
forest: &'a SplayForest<V>,
idx: Option<NodeIdx>,
path_parent: Option<Label<Node<V>>>,
parent: Option<Label<Node<V>>>,
left: Option<Label<Node<V>>>,
right: Option<Label<Node<V>>>,
}
impl<'a, V: Debug> Debug for NodeDebug<'a, V> {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
match self.idx {
None => {
let none: Option<()> = None;
none.fmt(f)
}
Some(idx) => {
let mut debug_struct = f.debug_struct("Node");
debug_struct.field("Idx", &idx.get());
if let Some(path_parent_idx) = self.forest.get_node(idx).path_parent {
debug_struct.field("PathParent", &path_parent_idx.get());
}
debug_struct.field("Val", &self.forest.get_node(idx).value);
let left_child = self.forest.get_node(idx).left;
let left_debug = NodeDebug {
forest: self.forest,
idx: left_child,
};
debug_struct.field("Left", &left_debug);
let right_child = self.forest.get_node(idx).right;
let right_debug = NodeDebug {
forest: self.forest,
idx: right_child,
};
debug_struct.field("Right", &right_debug);
debug_struct.finish()
}
}
}
}
impl<V> Node<V> {
impl<V: Copy> Node<V> {
pub fn new(value: V) -> Self {
Node {
value,
......@@ -83,172 +22,153 @@ impl<V> Node<V> {
}
}
pub struct SplayForest<V> {
pub forest: Vec<Node<V>>,
}
impl<V> Default for SplayForest<V> {
fn default() -> Self {
SplayForest { forest: Vec::new() }
}
}
impl<V> SplayForest<V> {
pub fn add_node(&mut self, node: V) -> NodeIdx {
let cur_idx = self.forest.len().into();
let node = Node::new(node);
self.forest.push(node);
cur_idx
impl<V: Copy + PartialEq + Debug> Pool<Node<V>> {
pub fn add_node(&mut self, value: V) -> Label<Node<V>> {
let node = Node::new(value);
self.insert(node)
}
fn get_node(&self, node_idx: NodeIdx) -> &Node<V> {
&self.forest[node_idx.get()]
fn node(&self, label: Label<Node<V>>) -> &Node<V> {
&self[label]
}
fn get_node_mut(&mut self, node_idx: NodeIdx) -> &mut Node<V> {
&mut self.forest[node_idx.get()]
fn node_mut(&mut self, label: Label<Node<V>>) -> &mut Node<V> {
&mut self[label]
}
pub fn get_value(&self, node_idx: NodeIdx) -> &V {
&self.get_node(node_idx).value
pub fn value(&self, label: Label<Node<V>>) -> &V {
&self.node(label).value
}
pub fn get_parent(&self, node_idx: NodeIdx) -> Option<NodeIdx> {
self.get_node(node_idx).parent
pub fn parent(&self, label: Label<Node<V>>) -> Option<Label<Node<V>>> {
self.node(label).parent
}
pub fn get_path_parent(&self, node_idx: NodeIdx) -> Option<NodeIdx> {
self.get_node(node_idx).path_parent
pub fn path_parent(&self, label: Label<Node<V>>) -> Option<Label<Node<V>>> {
self.node(label).path_parent
}
pub fn get_left(&self, node_idx: NodeIdx) -> Option<NodeIdx> {
self.get_node(node_idx).left
pub fn left(&self, label: Label<Node<V>>) -> Option<Label<Node<V>>> {
self.node(label).left
}
pub fn get_right(&self, node_idx: NodeIdx) -> Option<NodeIdx> {
self.get_node(node_idx).right
pub fn right(&self, label: Label<Node<V>>) -> Option<Label<Node<V>>> {
self.node(label).right
}
fn get_while_some<F>(&self, node_idx: NodeIdx, func: F) -> NodeIdx
fn while_some<F>(&self, label: Label<Node<V>>, func: F) -> Label<Node<V>>
where
F: Fn(NodeIdx) -> Option<NodeIdx>,
F: Fn(Label<Node<V>>) -> Option<Label<Node<V>>>,
{
let mut current_node_idx = node_idx;
let mut current_label = label;
loop {
match func(current_node_idx) {
match func(current_label) {
None => {
return current_node_idx;
return current_label;
}
Some(next_node_idx) => {
current_node_idx = next_node_idx;
Some(next_label) => {
current_label = next_label;
}
}
}
}
pub fn get_root(&self, node_idx: NodeIdx) -> NodeIdx {
self.get_while_some(node_idx, |node_idx| self.get_parent(node_idx))
pub fn root(&self, label: Label<Node<V>>) -> Label<Node<V>> {
self.while_some(label, |label| self.parent(label))
}
pub fn get_leftmost(&self, node_idx: NodeIdx) -> NodeIdx {
self.get_while_some(node_idx, |node_idx| self.get_left(node_idx))
pub fn leftmost(&self, label: Label<Node<V>>) -> Label<Node<V>> {
self.while_some(label, |label| self.left(label))
}
pub fn get_rightmost(&self, node_idx: NodeIdx) -> NodeIdx {
self.get_while_some(node_idx, |node_idx| self.get_right(node_idx))
pub fn rightmost(&self, label: Label<Node<V>>) -> Label<Node<V>> {
self.while_some(label, |label| self.right(label))
}
fn is_left_child(&self, node_idx: NodeIdx) -> bool {
match self.get_parent(node_idx).map(|idx| self.get_node(idx)) {
fn is_left_child(&self, label: Label<Node<V>>) -> bool {
match self.parent(label).map(|label| self.node(label)) {
None => false,
Some(parent) => match parent.left {
None => false,
Some(left_idx) => left_idx.get() == node_idx.get(),
Some(left_label) => left_label == label,
},
}
}
fn update_parent(&mut self, old_root_idx: NodeIdx, new_root_idx: NodeIdx) {
let b_left = self.is_left_child(old_root_idx);
match self.get_parent(old_root_idx) {
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);
match self.parent(old_root_label) {
None => {
self.forest[new_root_idx.get()].parent = None;
self[new_root_label].parent = None;
// Only need to update path parent if original was the root, as only the root has the path_parent
self.forest[new_root_idx.get()].path_parent =
self.forest[old_root_idx.get()].path_parent;
self.forest[old_root_idx.get()].path_parent = None;
self[new_root_label].path_parent = self[old_root_label].path_parent;
self[old_root_label].path_parent = None;
}
Some(parent_idx) => {
Some(parent_label) => {
if b_left {
self.set_left(parent_idx, Some(new_root_idx))
self.set_left(parent_label, Some(new_root_label))
} else {
self.set_right(parent_idx, Some(new_root_idx));
self.set_right(parent_label, Some(new_root_label));
}
}
}
}
fn rotate_right(&mut self, root_idx: NodeIdx) {
let left_idx = self.get_node(root_idx).left;
match left_idx {
fn rotate_right(&mut self, root_label: Label<Node<V>>) {
let left_label = self.node(root_label).left;
match left_label {
None => {}
Some(new_root_idx) => {
self.set_left(root_idx, self.get_node(new_root_idx).right);
self.update_parent(root_idx, new_root_idx);
self.set_right(new_root_idx, Some(root_idx));
Some(new_root_label) => {
self.set_left(root_label, self.node(new_root_label).right);
self.update_parent(root_label, new_root_label);
self.set_right(new_root_label, Some(root_label));
}
}
}
fn rotate_left(&mut self, root_idx: NodeIdx) {
let right_idx = self.get_node(root_idx).right;
match right_idx {
fn rotate_left(&mut self, root_label: Label<Node<V>>) {
let right_label = self.node(root_label).right;
match right_label {
None => {}
Some(new_root_idx) => {
self.set_right(root_idx, self.get_node(new_root_idx).left);
self.update_parent(root_idx, new_root_idx);
self.set_left(new_root_idx, Some(root_idx));
Some(new_root_label) => {
self.set_right(root_label, self.node(new_root_label).left);
self.update_parent(root_label, new_root_label);
self.set_left(new_root_label, Some(root_label));
}
}
}
pub fn rotate_up(&mut self, node_idx: NodeIdx) {
let b_left = self.is_left_child(node_idx);
let parent = self.get_parent(node_idx);
pub fn rotate_up(&mut self, label: Label<Node<V>>) {
let b_left = self.is_left_child(label);
let parent = self.parent(label);
match parent {
None => {}
Some(parent_idx) => {
Some(parent_label) => {
if b_left {
self.rotate_right(parent_idx);
self.rotate_right(parent_label);
} else {
self.rotate_left(parent_idx);
self.rotate_left(parent_label);
}
}
}
}
pub fn set_right(&mut self, node_idx: NodeIdx, right_idx: Option<NodeIdx>) {
self.forest[node_idx.get()].right = right_idx;
match right_idx {
None => {}
Some(idx) => {
self.forest[idx.get()].parent = Some(node_idx);
}
pub 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, node_idx: NodeIdx, left_idx: Option<NodeIdx>) {
self.forest[node_idx.get()].left = left_idx;
match left_idx {
None => {}
Some(idx) => {
self.forest[idx.get()].parent = Some(node_idx);
}
pub 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, node_idx: NodeIdx) {
pub fn splay(&mut self, label: Label<Node<V>>) {
enum SplayType {
NoSplay,
Zig,
......@@ -257,12 +177,12 @@ impl<V> SplayForest<V> {
}
loop {
let splay_type = match self.get_parent(node_idx) {
let splay_type = match self.parent(label) {
None => SplayType::NoSplay,
Some(parent_idx) => match self.get_parent(parent_idx) {
Some(parent_label) => match self.parent(parent_label) {
None => SplayType::Zig,
Some(_) => {
if self.is_left_child(node_idx) == self.is_left_child(parent_idx) {
if self.is_left_child(label) == self.is_left_child(parent_label) {
SplayType::ZigZig
} else {
SplayType::ZigZag
......@@ -273,14 +193,14 @@ impl<V> SplayForest<V> {
match splay_type {
SplayType::NoSplay => return,
SplayType::Zig => self.rotate_up(node_idx),
SplayType::Zig => self.rotate_up(label),
SplayType::ZigZag => {
self.rotate_up(node_idx);
self.rotate_up(node_idx);
self.rotate_up(label);
self.rotate_up(label);
}
SplayType::ZigZig => {
self.rotate_up(self.get_parent(node_idx).unwrap());
self.rotate_up(node_idx)
self.rotate_up(self.parent(label).unwrap());
self.rotate_up(label)
}
}
}
......@@ -288,54 +208,34 @@ impl<V> SplayForest<V> {
pub fn split_right_and_attach_new(
&mut self,
node_idx: NodeIdx,
new_right_idx: Option<NodeIdx>,