Commit 35cf8110 authored by tgerstel's avatar tgerstel
Browse files

consolidation

parent 0d86c77d
......@@ -22,22 +22,34 @@ 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);
let mut root = label;
while let Some(next) = self.left(root) {
root = next;
}
self.expose(root);
root
}
pub fn cut(&mut self, label: Label<Node<V>>) {
self.expose(label);
self.split_left(label);
if let Some(left_label) = self.left(label) {
self[left_label].parent = None;
self[label].left = None;
}
}
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);
self[child_label].left = parent_label.into();
self[parent_label].parent = child_label.into();
}
pub fn value_mut(&mut self, label: Label<Node<V>>) -> &mut V {
......@@ -48,11 +60,6 @@ impl<V> Pool<Node<V>> {
&self[label].value
}
pub fn add_node(&mut self, value: V) -> Label<Node<V>> {
let node = Node::new(value);
self.insert(node)
}
fn expose(&mut self, label: Label<Node<V>>) {
self.splay(label);
self.split_right_and_attach_new(label, None);
......@@ -65,27 +72,21 @@ impl<V> Pool<Node<V>> {
self.splay(label);
}
fn left(&self, label: Label<Node<V>>) -> Option<Label<Node<V>>> {
self[label].left
}
fn right(&self, label: Label<Node<V>>) -> Option<Label<Node<V>>> {
self[label].right
}
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;
while let Some(next_label) = f(current_label) {
current_label = next_label;
fn splay(&mut self, label: Label<Node<V>>) {
while 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) {
self.rotate_up(self[label].parent.unwrap());
self.rotate_up(label);
} else {
self.rotate_up(label);
self.rotate_up(label);
};
} else {
self.rotate_up(label);
break;
}
}
current_label
}
fn leftmost(&self, label: Label<Node<V>>) -> Label<Node<V>> {
self.while_some(label, |label| self.left(label))
}
fn is_left_child(&self, label: Label<Node<V>>) -> bool {
......@@ -100,19 +101,13 @@ 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[old_root_label].parent {
if b_left {
self.set_left(parent_label, Some(new_root_label))
fn rotate_up(&mut self, label: Label<Node<V>>) {
if let Some(parent_label) = self[label].parent {
if self.is_left_child(label) {
self.rotate_right(parent_label);
} else {
self.set_right(parent_label, Some(new_root_label));
self.rotate_left(parent_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;
}
}
......@@ -132,17 +127,29 @@ impl<V> Pool<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[label].parent {
if b_left {
self.rotate_right(parent_label);
fn update_parent(&mut self, old_root_label: Label<Node<V>>, new_root_label: Label<Node<V>>) {
if let Some(parent_label) = self[old_root_label].parent {
if self.is_left_child(old_root_label) {
self.set_left(parent_label, Some(new_root_label))
} else {
self.rotate_left(parent_label);
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 left(&self, label: Label<Node<V>>) -> Option<Label<Node<V>>> {
self[label].left
}
fn right(&self, label: Label<Node<V>>) -> Option<Label<Node<V>>> {
self[label].right
}
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 {
......@@ -157,44 +164,6 @@ impl<V> Pool<Node<V>> {
}
}
fn splay(&mut self, label: Label<Node<V>>) {
enum SplayType {
NoSplay,
Zig,
ZigZig,
ZigZag,
}
loop {
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 {
SplayType::ZigZag
}
} else {
SplayType::Zig
}
} else {
SplayType::NoSplay
};
match splay_type {
SplayType::NoSplay => return,
SplayType::Zig => self.rotate_up(label),
SplayType::ZigZag => {
self.rotate_up(label);
self.rotate_up(label);
}
SplayType::ZigZig => {
self.rotate_up(self[label].parent.unwrap());
self.rotate_up(label)
}
}
}
}
fn split_right_and_attach_new(
&mut self,
label: Label<Node<V>>,
......@@ -211,19 +180,6 @@ impl<V> Pool<Node<V>> {
self[new_right_label].path_parent = None;
}
}
fn split_left(&mut self, label: Label<Node<V>>) {
if let Some(left_label) = self.left(label) {
self[left_label].parent = None;
self[label].left = None;
}
}
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();
}
}
#[cfg(test)]
......@@ -272,7 +228,7 @@ mod tests {
#[test]
fn link_basic() {
let mut lct = Pool::with_capacity(10);
let mut lct = Pool::<Node<&str>>::with_capacity(10);
let node1 = lct.add_node("1");
let node2 = lct.add_node("2");
lct.link(node1, node2);
......
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