diff --git a/examples/linked_list.rs b/examples/linked_list.rs index a25c1c8..bce6310 100644 --- a/examples/linked_list.rs +++ b/examples/linked_list.rs @@ -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 { + /// Previous node in the list. prev: usize, + + /// Next node in the list. next: usize, + + /// Actual value stored in node. value: T, } struct List { - arena: VecArena>, + /// This is where nodes are stored. + arena: Arena>, + + /// First node in the list. head: usize, + + /// Last node in the list. tail: usize, } impl List { + /// 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 List { 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 List { 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 List { 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); } diff --git a/examples/splay_tree.rs b/examples/splay_tree.rs index cb77384..46e02ba 100644 --- a/examples/splay_tree.rs +++ b/examples/splay_tree.rs @@ -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 { + /// Parent node. parent: usize, + + /// Left and right child. children: [usize; 2], + + /// Actual value stored in node. value: T, } @@ -22,7 +32,10 @@ impl Node { } struct Splay { - arena: VecArena>, + /// This is where nodes are stored. + arena: Arena>, + + /// The root node. root: usize, } @@ -30,7 +43,7 @@ impl Splay where T: Ord { /// Constructs a new, empty splay tree. fn new() -> Splay { Splay { - arena: VecArena::new(), + arena: Arena::with_capacity(1000000), root: NULL, } } @@ -75,7 +88,7 @@ impl Splay 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 Splay 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 Splay 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); }