Commit 4d2ed8de authored by tgerstel's avatar tgerstel
Browse files

replace match option with if let some

parent f43db9c4
......@@ -3,81 +3,58 @@ mod splay_forest;
use super::collections::{Label, Pool};
pub use splay_forest::Node;
use std::fmt::Debug;
#[derive(Clone, Debug)]
pub struct LinkCutTree<V> {
nodes: Pool<Node<V>>,
}
impl<V> LinkCutTree<V> {
pub fn with_capacity(capacity: usize) -> Self {
LinkCutTree {
nodes: Pool::<Node<V>>::with_capacity(capacity),
}
}
pub fn make_tree(&mut self, val: V) -> Label<Node<V>> {
self.nodes.add_node(val)
}
pub fn expose(&mut self, label: Label<Node<V>>) {
self.nodes.splay(label);
self.nodes.split_right_and_attach_new(label, None);
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;
loop {
match self.nodes.path_parent(v) {
None => {
break;
}
Some(w) => {
self.nodes.splay(w);
self.nodes.split_right_and_attach_new(w, v.into());
v = w;
}
}
while let Some(w) = self.path_parent(v) {
self.splay(w);
self.split_right_and_attach_new(w, v.into());
v = w;
}
self.nodes.splay(label);
self.splay(label);
}
pub fn find_root(&mut self, label: Label<Node<V>>) -> Label<Node<V>> {
self.expose(label);
let root = self.nodes.leftmost(label);
let root = self.leftmost(label);
self.expose(root);
root
}
pub fn cut(&mut self, label: Label<Node<V>>) {
self.expose(label);
self.nodes.split_left(label);
self.split_left(label);
}
pub fn link(&mut self, parent_idx: Label<Node<V>>, child_idx: Label<Node<V>>) {
self.expose(child_idx);
self.expose(parent_idx);
self.nodes.join_left(child_idx, parent_idx);
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.nodes.value(label)
self.value(label)
}
}
#[cfg(test)]
mod tests {
use super::LinkCutTree;
use super::*;
#[test]
fn basic_tree() {
let mut lct: LinkCutTree<&str> = LinkCutTree::with_capacity(10);
let node1 = lct.make_tree("1");
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: LinkCutTree<&str> = LinkCutTree::with_capacity(10);
let node1 = lct.make_tree("1");
let node2 = lct.make_tree("2");
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);
......@@ -85,9 +62,9 @@ mod tests {
#[test]
fn link_basic() {
let mut lct: LinkCutTree<&str> = LinkCutTree::with_capacity(10);
let node1 = lct.make_tree("1");
let node2 = lct.make_tree("2");
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");
......@@ -106,10 +83,10 @@ mod tests {
#[test]
fn link_multiple() {
let mut lct: LinkCutTree<()> = LinkCutTree::with_capacity(10);
let node1 = lct.make_tree(());
let node2 = lct.make_tree(());
let node3 = lct.make_tree(());
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");
......@@ -119,9 +96,9 @@ mod tests {
#[test]
fn many_links_to_one() {
let mut lct: LinkCutTree<()> = LinkCutTree::with_capacity(10);
let node1 = lct.make_tree(());
let children = (1..6).map(|_| lct.make_tree(())).collect::<Vec<_>>();
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);
}
......@@ -133,18 +110,18 @@ mod tests {
#[test]
fn many_links_to_one_root() {
let mut lct: LinkCutTree<()> = LinkCutTree::with_capacity(15);
let root = lct.make_tree(());
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_idx in &last_depth_nodes {
for parent_label in &last_depth_nodes {
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);
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();
......@@ -163,9 +140,9 @@ mod tests {
#[test]
fn test_cut_basic() {
let mut lct: LinkCutTree<()> = LinkCutTree::with_capacity(10);
let node1 = lct.make_tree(());
let node2 = lct.make_tree(());
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");
......@@ -180,9 +157,9 @@ mod tests {
#[test]
fn many_cut_links() {
let mut lct: LinkCutTree<()> = LinkCutTree::with_capacity(10);
let node1 = lct.make_tree(());
let children = (1..6).map(|_| lct.make_tree(())).collect::<Vec<_>>();
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);
}
......
......@@ -28,10 +28,6 @@ impl<V> Pool<Node<V>> {
self.insert(node)
}
/* fn node(&self, label: Label<Node<V>>) -> &Node<V> {
&self[label]
}
*/
fn node_mut(&mut self, label: Label<Node<V>>) -> &mut Node<V> {
&mut self[label]
}
......@@ -56,21 +52,15 @@ impl<V> Pool<Node<V>> {
self[label].right
}
fn while_some<F>(&self, label: Label<Node<V>>, func: F) -> Label<Node<V>>
fn while_some<F>(&self, label: Label<Node<V>>, f: F) -> Label<Node<V>>
where
F: Fn(Label<Node<V>>) -> Option<Label<Node<V>>>,
{
let mut current_label = label;
loop {
match func(current_label) {
None => {
return current_label;
}
Some(next_label) => {
current_label = next_label;
}
}
while let Some(next_label) = f(current_label) {
current_label = next_label;
}
current_label
}
pub fn root(&self, label: Label<Node<V>>) -> Label<Node<V>> {
......@@ -86,70 +76,56 @@ impl<V> Pool<Node<V>> {
}
fn is_left_child(&self, label: Label<Node<V>>) -> bool {
match self.parent(label).map(|parent_label| &self[parent_label]) {
Some(parent) => match parent.left {
Some(left_label) => left_label == label,
None => false,
},
None => false,
if let Some(self_label) = self
.parent(label)
.map(|parent_label| self[parent_label].left)
.flatten()
{
self_label == label
} else {
false
}
}
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[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[new_root_label].path_parent = self[old_root_label].path_parent;
self[old_root_label].path_parent = None;
}
Some(parent_label) => {
if b_left {
self.set_left(parent_label, Some(new_root_label))
} else {
self.set_right(parent_label, Some(new_root_label));
}
if let Some(parent_label) = self.parent(old_root_label) {
if b_left {
self.set_left(parent_label, Some(new_root_label))
} else {
self.set_right(parent_label, Some(new_root_label));
}
} else {
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[new_root_label].path_parent = self[old_root_label].path_parent;
self[old_root_label].path_parent = None;
}
}
fn rotate_right(&mut self, root_label: Label<Node<V>>) {
let left_label = self[root_label].left;
match left_label {
None => {}
Some(new_root_label) => {
self.set_left(root_label, self[new_root_label].right);
self.update_parent(root_label, new_root_label);
self.set_right(new_root_label, Some(root_label));
}
if let Some(new_root_label) = self[root_label].left {
self.set_left(root_label, self[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_label: Label<Node<V>>) {
let right_label = self[root_label].right;
match right_label {
None => {}
Some(new_root_label) => {
self.set_right(root_label, self[new_root_label].left);
self.update_parent(root_label, new_root_label);
self.set_left(new_root_label, Some(root_label));
}
if let Some(new_root_label) = self[root_label].right {
self.set_right(root_label, self[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, label: Label<Node<V>>) {
let b_left = self.is_left_child(label);
let parent = self.parent(label);
match parent {
None => {}
Some(parent_label) => {
if b_left {
self.rotate_right(parent_label);
} else {
self.rotate_left(parent_label);
}
if let Some(parent_label) = self.parent(label) {
if b_left {
self.rotate_right(parent_label);
} else {
self.rotate_left(parent_label);
}
}
}
......@@ -177,18 +153,18 @@ impl<V> Pool<Node<V>> {
}
loop {
let splay_type = match self.parent(label) {
None => SplayType::NoSplay,
Some(parent_label) => match self.parent(parent_label) {
None => SplayType::Zig,
Some(_) => {
if self.is_left_child(label) == self.is_left_child(parent_label) {
SplayType::ZigZig
} else {
SplayType::ZigZag
}
let splay_type = if let Some(parent_label) = self.parent(label) {
if self.parent(parent_label).is_some() {
if self.is_left_child(label) == self.is_left_child(parent_label) {
SplayType::ZigZig
} else {
SplayType::ZigZag
}
},
} else {
SplayType::Zig
}
} else {
SplayType::NoSplay
};
match splay_type {
......
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