Document examples

This commit is contained in:
Stjepan Glavina 2016-11-14 20:41:37 +01:00
parent 821eac2764
commit 42d0ba31a6
2 changed files with 66 additions and 25 deletions

View File

@ -1,49 +1,65 @@
extern crate vec_arena;
use vec_arena::VecArena;
use vec_arena::Arena;
/// The null index, akin to null pointers.
///
/// Just like a null pointer indicates an address no object is ever stored at,
/// the null index indicates an index no object is ever stored at.
///
/// Number `!0` is the largest possible value representable by `usize`.
const NULL: usize = !0;
struct Node<T> {
/// Previous node in the list.
prev: usize,
/// Next node in the list.
next: usize,
/// Actual value stored in node.
value: T,
}
struct List<T> {
arena: VecArena<Node<T>>,
/// This is where nodes are stored.
arena: Arena<Node<T>>,
/// First node in the list.
head: usize,
/// Last node in the list.
tail: usize,
}
impl<T> List<T> {
/// Constructs a new, empty doubly linked list.
fn new() -> Self {
List {
arena: VecArena::new(),
arena: Arena::new(),
head: NULL,
tail: NULL,
}
}
/// Returns the number of elements in the list.
fn len(&self) -> usize {
self.arena.len()
}
fn new_node(&mut self, value: T) -> usize {
self.arena.insert(Node {
prev: NULL,
next: NULL,
value: value,
})
}
/// Links nodes `a` and `b` together, so that `a` comes before `b` in the list.
fn link(&mut self, a: usize, b: usize) {
if a != NULL { self.arena[a].next = b; }
if b != NULL { self.arena[b].prev = a; }
}
/// Appends `value` to the back of the list.
fn push_back(&mut self, value: T) -> usize {
let node = self.new_node(value);
let node = self.arena.insert(Node {
prev: NULL,
next: NULL,
value: value,
});
let tail = self.tail;
self.link(tail, node);
@ -55,8 +71,9 @@ impl<T> List<T> {
node
}
/// Pops and returns the value at the front of the list.
fn pop_front(&mut self) -> T {
let node = self.arena.remove(self.head);
let node = self.arena.remove(self.head).unwrap();
self.link(NULL, node.next);
self.head = node.next;
@ -66,8 +83,9 @@ impl<T> List<T> {
node.value
}
/// Removes the element specified by `index`.
fn remove(&mut self, index: usize) -> T {
let node = self.arena.remove(index);
let node = self.arena.remove(index).unwrap();
self.link(node.prev, node.next);
if self.head == index { self.head = node.next; }
@ -80,19 +98,27 @@ impl<T> List<T> {
fn main() {
let mut list = List::new();
// The list is now [].
let one = list.push_back(1);
list.push_back(2);
list.push_back(3);
// The list is now [1, 2, 3].
list.push_back(10);
let twenty = list.push_back(20);
list.push_back(30);
// The list is now [1, 2, 3, 10, 20, 30].
assert!(list.len() == 6);
assert!(list.remove(one) == 1);
assert!(list.remove(twenty) == 20);
// The list is now [2, 3, 10, 30].
assert!(list.len() == 4);
assert!(list.pop_front() == 2);
@ -100,5 +126,7 @@ fn main() {
assert!(list.pop_front() == 10);
assert!(list.pop_front() == 30);
// The list is now [].
assert!(list.len() == 0);
}

View File

@ -1,13 +1,23 @@
extern crate vec_arena;
use vec_arena::VecArena;
use vec_arena::Arena;
/// The null index, akin to null pointers.
///
/// Just like a null pointer indicates an address no object is ever stored at,
/// the null index indicates an index no object is ever stored at.
///
/// Number `!0` is the largest possible value representable by `usize`.
const NULL: usize = !0;
struct Node<T> {
/// Parent node.
parent: usize,
/// Left and right child.
children: [usize; 2],
/// Actual value stored in node.
value: T,
}
@ -22,7 +32,10 @@ impl<T> Node<T> {
}
struct Splay<T> {
arena: VecArena<Node<T>>,
/// This is where nodes are stored.
arena: Arena<Node<T>>,
/// The root node.
root: usize,
}
@ -30,7 +43,7 @@ impl<T> Splay<T> where T: Ord {
/// Constructs a new, empty splay tree.
fn new() -> Splay<T> {
Splay {
arena: VecArena::new(),
arena: Arena::with_capacity(1000000),
root: NULL,
}
}
@ -75,7 +88,7 @@ impl<T> Splay<T> where T: Ord {
}
}
/// Splays node
/// Splays a node, rebalancing the tree in process.
fn splay(&mut self, c: usize) {
loop {
// Variables:
@ -93,7 +106,7 @@ impl<T> Splay<T> where T: Ord {
// Find the grandparent.
let g = self.arena[p].parent;
if g == NULL {
// There is no grandparent. Just one rotation is left.
// There is no grandparent. Just one more rotation is left.
// Zig step.
self.rotate(p, c);
break;
@ -139,17 +152,17 @@ impl<T> Splay<T> where T: Ord {
}
}
/// Pretty-prints the subtree rooted at `node`, indented by `depth` spaces.
fn print(&self, node: usize, depth: usize) where T: std::fmt::Display {
/// Pretty-prints the subtree rooted at `node`, indented by `indent` spaces.
fn print(&self, node: usize, indent: usize) where T: std::fmt::Display {
if node != NULL {
// Print the left subtree.
self.print(self.arena[node].children[0], depth + 1);
self.print(self.arena[node].children[0], indent + 3);
// Print the current node.
println!("{:width$}{}", "", self.arena[node].value, width = depth * 3);
println!("{:width$}{}", "", self.arena[node].value, width = indent);
// Print the right subtree.
self.print(self.arena[node].children[1], depth + 1);
self.print(self.arena[node].children[1], indent + 3);
}
}
}
@ -159,7 +172,7 @@ fn main() {
// Insert a bunch of pseudorandom numbers.
let mut num = 1u32;
for _ in 0..30 {
for i in 0..30 {
num = num.wrapping_mul(17).wrapping_add(255);
splay.insert(num);
}