More comments

This commit is contained in:
Stjepan Glavina 2016-10-28 02:31:37 +02:00
parent 4e6040f247
commit 89b77b634c
1 changed files with 87 additions and 46 deletions

View File

@ -23,7 +23,8 @@ struct Splay<T> {
root: usize, root: usize,
} }
impl<T> Splay<T> where T: Ord + Eq + Clone { impl<T> Splay<T> where T: Ord {
/// Constructs a new, empty splay tree.
fn new() -> Splay<T> { fn new() -> Splay<T> {
Splay { Splay {
arena: VecArena::new(), arena: VecArena::new(),
@ -31,83 +32,120 @@ impl<T> Splay<T> where T: Ord + Eq + Clone {
} }
} }
// #[inline(always)] /// Links nodes `p` and `c` as parent and child with the specified direction.
fn rotate(&mut self, a: usize, b: usize) { #[inline(always)]
let p = self.arena[a].parent; fn link(&mut self, p: usize, c: usize, dir: usize) {
self.arena[p].children[dir] = c;
let dir = if self.arena[a].children[0] == b { 0 } else { 1 }; if c != !0 {
let t = self.arena[b].children[dir ^ 1]; self.arena[c].parent = p;
self.arena[a].children[dir] = t;
if t != !0 {
self.arena[t].parent = a;
} }
self.arena[b].children[dir ^ 1] = a; }
self.arena[a].parent = b;
if p == !0 { /// Performs a rotation on node `c`, whose parent is node `p`.
self.root = b; #[inline(always)]
self.arena[b].parent = !0; fn rotate(&mut self, p: usize, c: usize) {
// Variables:
// - `c` is the child node
// - `p` is it's parent
// - `g` is it's grandparent
// Find the grandparent.
let g = self.arena[p].parent;
// The direction of p-c relationship.
let dir = if self.arena[p].children[0] == c { 0 } else { 1 };
// This is the child of `c` that needs to be reassigned to `p`.
let t = self.arena[c].children[dir ^ 1];
self.link(p, t, dir);
self.link(c, p, dir ^ 1);
if g == !0 {
// There is no grandparent, so `c` becomes the root.
self.root = c;
self.arena[c].parent = !0;
} else { } else {
let dir = if self.arena[p].children[0] == a { 0 } else { 1 }; // Link `g` and `c` together.
self.arena[p].children[dir] = b; let dir = if self.arena[g].children[0] == p { 0 } else { 1 };
self.arena[b].parent = p; self.link(g, c, dir);
} }
} }
fn splay(&mut self, a: usize) { /// Splays node
fn splay(&mut self, c: usize) {
loop { loop {
let b = self.arena[a].parent; // Variables:
if b == !0 { // - `c` is the current node
// - `p` is it's parent
// - `g` is it's grandparent
// Find the parent.
let p = self.arena[c].parent;
if p == !0 {
// There is no parent. That means `c` is the root.
break; break;
} }
let c = self.arena[b].parent; // Find the grandparent.
if c == !0 { let g = self.arena[p].parent;
self.rotate(b, a); if g == !0 {
// There is no grandparent. Just one rotation is left.
// Zig step.
self.rotate(p, c);
break; break;
} }
let is_l = self.arena[c].children[0] == b && self.arena[b].children[0] == a; if (self.arena[g].children[0] == p) == (self.arena[p].children[0] == c) {
let is_r = self.arena[c].children[1] == b && self.arena[b].children[1] == a; // Zig-zig step.
self.rotate(g, p);
if is_l || is_r { self.rotate(p, c);
self.rotate(c, b);
self.rotate(b, a);
} else { } else {
self.rotate(b, a); // Zig-zag step.
self.rotate(c, a); self.rotate(p, c);
self.rotate(g, c);
} }
} }
} }
/// Inserts a new node with specified `value`.
fn insert(&mut self, value: T) { fn insert(&mut self, value: T) {
let node = self.arena.insert(Node::new(value)); // Variables:
// - `n` is the new node
// - `p` will be it's parent
// - `c` is the present child of `p`
let n = self.arena.insert(Node::new(value));
if self.root == !0 { if self.root == !0 {
self.root = node; self.root = n;
} else { } else {
let mut curr = self.root; let mut p = self.root;
loop { loop {
let dir = if self.arena[node].value < self.arena[curr].value { 0 } else { 1 }; // Decide whether to go left or right.
let next = self.arena[curr].children[dir]; let dir = if self.arena[n].value < self.arena[p].value { 0 } else { 1 };
let c = self.arena[p].children[dir];
if next == !0 { if c == !0 {
self.arena[curr].children[dir] = node; self.link(p, n, dir);
self.arena[node].parent = curr; self.splay(n);
self.splay(node);
break; break;
} else {
curr = next;
} }
p = c;
} }
} }
} }
/// Pretty-prints the subtree rooted at `node`, indented by `depth` spaces.
fn print(&self, node: usize, depth: usize) where T: std::fmt::Display { fn print(&self, node: usize, depth: usize) where T: std::fmt::Display {
if node != !0 { if node != !0 {
// Print the left subtree.
self.print(self.arena[node].children[0], depth + 1); self.print(self.arena[node].children[0], depth + 1);
// Print the current node.
println!("{:width$}{}", "", self.arena[node].value, width = depth * 3); println!("{:width$}{}", "", self.arena[node].value, width = depth * 3);
// Print the right subtree.
self.print(self.arena[node].children[1], depth + 1); self.print(self.arena[node].children[1], depth + 1);
} }
} }
@ -116,10 +154,13 @@ impl<T> Splay<T> where T: Ord + Eq + Clone {
fn main() { fn main() {
let mut splay = Splay::new(); let mut splay = Splay::new();
// Insert a bunch of pseudorandom numbers.
let mut num = 1u32; let mut num = 1u32;
for _ in 0..1000000 { for _ in 0..30 {
num = num.wrapping_mul(17).wrapping_add(255); num = num.wrapping_mul(17).wrapping_add(255);
splay.insert(num); splay.insert(num);
} }
// splay.print(splay.root, 0);
// Display the whole splay tree.
splay.print(splay.root, 0);
} }