|
|
@ -1,18 +1,16 @@
|
|
|
|
#![allow(dead_code)]
|
|
|
|
#![allow(dead_code)]
|
|
|
|
|
|
|
|
|
|
|
|
extern crate rand;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// An ordered collection of `T`s.
|
|
|
|
// An ordered collection of `T`s.
|
|
|
|
enum BinaryTree<T> {
|
|
|
|
enum BinaryTree<T> {
|
|
|
|
Empty,
|
|
|
|
Empty,
|
|
|
|
NonEmpty(Box<TreeNode<T>>)
|
|
|
|
NonEmpty(Box<TreeNode<T>>),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// A part of a BinaryTree.
|
|
|
|
// A part of a BinaryTree.
|
|
|
|
struct TreeNode<T> {
|
|
|
|
struct TreeNode<T> {
|
|
|
|
element: T,
|
|
|
|
element: T,
|
|
|
|
left: BinaryTree<T>,
|
|
|
|
left: BinaryTree<T>,
|
|
|
|
right: BinaryTree<T>
|
|
|
|
right: BinaryTree<T>,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
#[test]
|
|
|
@ -26,37 +24,42 @@ fn binary_tree_size() {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
#[test]
|
|
|
|
fn test_hand_building_tree_of_planets() {
|
|
|
|
fn build_binary_tree() {
|
|
|
|
use self::BinaryTree::*;
|
|
|
|
use self::BinaryTree::*;
|
|
|
|
let jupiter_tree = NonEmpty(Box::new(TreeNode {
|
|
|
|
let jupiter_tree = NonEmpty(Box::new(TreeNode {
|
|
|
|
element: "Jupiter",
|
|
|
|
element: "Jupiter",
|
|
|
|
left: Empty,
|
|
|
|
left: Empty,
|
|
|
|
right: Empty
|
|
|
|
right: Empty,
|
|
|
|
}));
|
|
|
|
}));
|
|
|
|
|
|
|
|
|
|
|
|
let mercury_tree = NonEmpty(Box::new(TreeNode {
|
|
|
|
let mercury_tree = NonEmpty(Box::new(TreeNode {
|
|
|
|
element: "Mercury",
|
|
|
|
element: "Mercury",
|
|
|
|
left: Empty,
|
|
|
|
left: Empty,
|
|
|
|
right: Empty
|
|
|
|
right: Empty,
|
|
|
|
}));
|
|
|
|
}));
|
|
|
|
|
|
|
|
|
|
|
|
let mars_tree = NonEmpty(Box::new(TreeNode {
|
|
|
|
let mars_tree = NonEmpty(Box::new(TreeNode {
|
|
|
|
element: "Mars",
|
|
|
|
element: "Mars",
|
|
|
|
left: jupiter_tree,
|
|
|
|
left: jupiter_tree,
|
|
|
|
right: mercury_tree
|
|
|
|
right: mercury_tree,
|
|
|
|
}));
|
|
|
|
}));
|
|
|
|
|
|
|
|
|
|
|
|
let venus_tree = NonEmpty(Box::new(TreeNode {
|
|
|
|
let venus_tree = NonEmpty(Box::new(TreeNode {
|
|
|
|
element: "Venus",
|
|
|
|
element: "Venus",
|
|
|
|
left: Empty,
|
|
|
|
left: Empty,
|
|
|
|
right: Empty
|
|
|
|
right: Empty,
|
|
|
|
}));
|
|
|
|
}));
|
|
|
|
|
|
|
|
|
|
|
|
let uranus_tree = NonEmpty(Box::new(TreeNode {
|
|
|
|
let uranus_tree = NonEmpty(Box::new(TreeNode {
|
|
|
|
element: "Uranus",
|
|
|
|
element: "Uranus",
|
|
|
|
left: Empty,
|
|
|
|
left: Empty,
|
|
|
|
right: venus_tree
|
|
|
|
right: venus_tree,
|
|
|
|
}));
|
|
|
|
}));
|
|
|
|
|
|
|
|
|
|
|
|
let tree = NonEmpty(Box::new(TreeNode {
|
|
|
|
let tree = NonEmpty(Box::new(TreeNode {
|
|
|
|
element: "Saturn",
|
|
|
|
element: "Saturn",
|
|
|
|
left: mars_tree,
|
|
|
|
left: mars_tree,
|
|
|
|
right: uranus_tree
|
|
|
|
right: uranus_tree,
|
|
|
|
}));
|
|
|
|
}));
|
|
|
|
|
|
|
|
|
|
|
|
assert_eq!(tree.walk(),
|
|
|
|
assert_eq!(tree.walk(),
|
|
|
@ -80,13 +83,14 @@ impl<T: Clone> BinaryTree<T> {
|
|
|
|
impl<T: Ord> BinaryTree<T> {
|
|
|
|
impl<T: Ord> BinaryTree<T> {
|
|
|
|
fn add(&mut self, value: T) {
|
|
|
|
fn add(&mut self, value: T) {
|
|
|
|
match *self {
|
|
|
|
match *self {
|
|
|
|
BinaryTree::Empty =>
|
|
|
|
BinaryTree::Empty => {
|
|
|
|
*self = BinaryTree::NonEmpty(Box::new(TreeNode {
|
|
|
|
*self = BinaryTree::NonEmpty(Box::new(TreeNode {
|
|
|
|
element: value,
|
|
|
|
element: value,
|
|
|
|
left: BinaryTree::Empty,
|
|
|
|
left: BinaryTree::Empty,
|
|
|
|
right: BinaryTree::Empty
|
|
|
|
right: BinaryTree::Empty,
|
|
|
|
})),
|
|
|
|
}))
|
|
|
|
BinaryTree::NonEmpty(ref mut node) =>
|
|
|
|
}
|
|
|
|
|
|
|
|
BinaryTree::NonEmpty(ref mut node) => {
|
|
|
|
if value <= node.element {
|
|
|
|
if value <= node.element {
|
|
|
|
node.left.add(value);
|
|
|
|
node.left.add(value);
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
@ -94,6 +98,7 @@ impl<T: Ord> BinaryTree<T> {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
#[test]
|
|
|
@ -117,14 +122,18 @@ fn test_add_method_2() {
|
|
|
|
tree.add(planet);
|
|
|
|
tree.add(planet);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
assert_eq!(tree.walk(),
|
|
|
|
assert_eq!(
|
|
|
|
vec!["Jupiter", "Mars", "Mercury", "Saturn", "Uranus", "Venus"]);
|
|
|
|
tree.walk(),
|
|
|
|
|
|
|
|
vec!["Jupiter", "Mars", "Mercury", "Saturn", "Uranus", "Venus"]
|
|
|
|
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// From chapter 15: Iterators
|
|
|
|
|
|
|
|
|
|
|
|
use self::BinaryTree::*;
|
|
|
|
use self::BinaryTree::*;
|
|
|
|
|
|
|
|
|
|
|
|
// The state of an in-order traversal of a `BinaryTree`.
|
|
|
|
// The state of an in-order traversal of a `BinaryTree`.
|
|
|
|
struct TreeIter<'a, T: 'a> {
|
|
|
|
struct TreeIter<'a, T> {
|
|
|
|
// A stack of references to tree nodes. Since we use `Vec`'s
|
|
|
|
// A stack of references to tree nodes. Since we use `Vec`'s
|
|
|
|
// `push` and `pop` methods, the top of the stack is the end of the
|
|
|
|
// `push` and `pop` methods, the top of the stack is the end of the
|
|
|
|
// vector.
|
|
|
|
// vector.
|
|
|
@ -164,14 +173,13 @@ impl<'a, T> Iterator for TreeIter<'a, T> {
|
|
|
|
type Item = &'a T;
|
|
|
|
type Item = &'a T;
|
|
|
|
fn next(&mut self) -> Option<&'a T> {
|
|
|
|
fn next(&mut self) -> Option<&'a T> {
|
|
|
|
// Find the node this iteration must produce,
|
|
|
|
// Find the node this iteration must produce,
|
|
|
|
// or finish the iteration.
|
|
|
|
// or finish the iteration. (Use the `?` operator
|
|
|
|
let node = match self.unvisited.pop() {
|
|
|
|
// to return immediately if it's `None`.)
|
|
|
|
None => return None,
|
|
|
|
let node = self.unvisited.pop()?;
|
|
|
|
Some(n) => n
|
|
|
|
|
|
|
|
};
|
|
|
|
// After `node`, the next thing we produce must be the leftmost
|
|
|
|
|
|
|
|
// child in `node`'s right subtree, so push the path from here
|
|
|
|
// The next node after this one is the leftmost child of
|
|
|
|
// down. Our helper method turns out to be just what we need.
|
|
|
|
// this node's right child, so push the path from here down.
|
|
|
|
|
|
|
|
self.push_left_edge(&node.right);
|
|
|
|
self.push_left_edge(&node.right);
|
|
|
|
|
|
|
|
|
|
|
|
// Produce a reference to this node's value.
|
|
|
|
// Produce a reference to this node's value.
|
|
|
@ -188,24 +196,40 @@ fn external_iterator() {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Build a small tree.
|
|
|
|
// Build a small tree.
|
|
|
|
let subtree_l = make_node(Empty, "mecha", Empty);
|
|
|
|
let mut tree = BinaryTree::Empty;
|
|
|
|
let subtree_rl = make_node(Empty, "droid", Empty);
|
|
|
|
tree.add("jaeger");
|
|
|
|
let subtree_r = make_node(subtree_rl, "robot", Empty);
|
|
|
|
tree.add("robot");
|
|
|
|
let tree = make_node(subtree_l, "Jaeger", subtree_r);
|
|
|
|
tree.add("droid");
|
|
|
|
|
|
|
|
tree.add("mecha");
|
|
|
|
|
|
|
|
|
|
|
|
// Iterate over it.
|
|
|
|
// Iterate over it.
|
|
|
|
let mut v = Vec::new();
|
|
|
|
let mut v = Vec::new();
|
|
|
|
for kind in &tree {
|
|
|
|
for kind in &tree {
|
|
|
|
v.push(*kind);
|
|
|
|
v.push(*kind);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
assert_eq!(v, ["mecha", "Jaeger", "droid", "robot"]);
|
|
|
|
assert_eq!(v, ["droid", "jaeger", "mecha", "robot"]);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
assert_eq!(tree.iter()
|
|
|
|
|
|
|
|
.map(|name| format!("mega-{}", name))
|
|
|
|
|
|
|
|
.collect::<Vec<_>>(),
|
|
|
|
|
|
|
|
vec!["mega-droid", "mega-jaeger",
|
|
|
|
|
|
|
|
"mega-mecha", "mega-robot"]);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let mut iterator = (&tree).into_iter();
|
|
|
|
|
|
|
|
assert_eq!(iterator.next(), Some(&"droid"));
|
|
|
|
|
|
|
|
assert_eq!(iterator.next(), Some(&"jaeger"));
|
|
|
|
|
|
|
|
assert_eq!(iterator.next(), Some(&"mecha"));
|
|
|
|
|
|
|
|
assert_eq!(iterator.next(), Some(&"robot"));
|
|
|
|
|
|
|
|
assert_eq!(iterator.next(), None);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Construct a tree by hand.
|
|
|
|
let left_subtree = make_node(Empty, "mecha", Empty);
|
|
|
|
let left_subtree = make_node(Empty, "mecha", Empty);
|
|
|
|
let right_subtree = make_node(make_node(Empty, "droid", Empty),
|
|
|
|
let right_subtree = make_node(make_node(Empty, "droid", Empty),
|
|
|
|
"robot",
|
|
|
|
"robot",
|
|
|
|
Empty);
|
|
|
|
Empty);
|
|
|
|
let tree = make_node(left_subtree, "Jaeger", right_subtree);
|
|
|
|
let tree = make_node(left_subtree, "Jaeger", right_subtree);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Try initializing the iterator ourselves and see if it runs.
|
|
|
|
let mut v = Vec::new();
|
|
|
|
let mut v = Vec::new();
|
|
|
|
let mut iter = TreeIter { unvisited: vec![] };
|
|
|
|
let mut iter = TreeIter { unvisited: vec![] };
|
|
|
|
iter.push_left_edge(&tree);
|
|
|
|
iter.push_left_edge(&tree);
|
|
|
@ -214,33 +238,23 @@ fn external_iterator() {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
assert_eq!(v, ["mecha", "Jaeger", "droid", "robot"]);
|
|
|
|
assert_eq!(v, ["mecha", "Jaeger", "droid", "robot"]);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Iterate by shared reference.
|
|
|
|
let mut v = Vec::new();
|
|
|
|
let mut v = Vec::new();
|
|
|
|
for kind in &tree {
|
|
|
|
for kind in &tree {
|
|
|
|
v.push(*kind);
|
|
|
|
v.push(*kind);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
assert_eq!(v, ["mecha", "Jaeger", "droid", "robot"]);
|
|
|
|
assert_eq!(v, ["mecha", "Jaeger", "droid", "robot"]);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Iterate, taking ownership.
|
|
|
|
let mut v = Vec::new();
|
|
|
|
let mut v = Vec::new();
|
|
|
|
let mut state = tree.into_iter();
|
|
|
|
let mut state = tree.into_iter();
|
|
|
|
while let Some(kind) = state.next() {
|
|
|
|
while let Some(kind) = state.next() {
|
|
|
|
v.push(*kind);
|
|
|
|
v.push(*kind);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
assert_eq!(v, ["mecha", "Jaeger", "droid", "robot"]);
|
|
|
|
assert_eq!(v, ["mecha", "Jaeger", "droid", "robot"]);
|
|
|
|
|
|
|
|
|
|
|
|
assert_eq!(tree.iter()
|
|
|
|
|
|
|
|
.map(|name| format!("mega-{}", name))
|
|
|
|
|
|
|
|
.collect::<Vec<_>>(),
|
|
|
|
|
|
|
|
vec!["mega-mecha", "mega-Jaeger",
|
|
|
|
|
|
|
|
"mega-droid", "mega-robot"]);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let mut iterator = tree.into_iter();
|
|
|
|
|
|
|
|
assert_eq!(iterator.next(), Some(&"mecha"));
|
|
|
|
|
|
|
|
assert_eq!(iterator.next(), Some(&"Jaeger"));
|
|
|
|
|
|
|
|
assert_eq!(iterator.next(), Some(&"droid"));
|
|
|
|
|
|
|
|
assert_eq!(iterator.next(), Some(&"robot"));
|
|
|
|
|
|
|
|
assert_eq!(iterator.next(), None);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
#[test]
|
|
|
|
fn other_cloned() {
|
|
|
|
fn other_cloned() {
|
|
|
|
use std::collections::BTreeSet;
|
|
|
|
use std::collections::BTreeSet;
|
|
|
@ -257,13 +271,12 @@ fn other_cloned() {
|
|
|
|
#[test]
|
|
|
|
#[test]
|
|
|
|
fn fuzz() {
|
|
|
|
fn fuzz() {
|
|
|
|
fn make_random_tree(p: f32) -> BinaryTree<i32> {
|
|
|
|
fn make_random_tree(p: f32) -> BinaryTree<i32> {
|
|
|
|
use rand::{ThreadRng, thread_rng};
|
|
|
|
use rand::prelude::*;
|
|
|
|
use rand::distributions::range::Range;
|
|
|
|
use rand::thread_rng;
|
|
|
|
use rand::distributions::Sample;
|
|
|
|
use rand::rngs::ThreadRng;
|
|
|
|
|
|
|
|
|
|
|
|
fn make(p: f32, next: &mut i32, rng: &mut ThreadRng) -> BinaryTree<i32> {
|
|
|
|
fn make(p: f32, next: &mut i32, rng: &mut ThreadRng) -> BinaryTree<i32> {
|
|
|
|
let mut range = Range::new(0.0, 1.0);
|
|
|
|
if rng.gen_range(0.0 .. 1.0) > p {
|
|
|
|
if range.sample(rng) > p {
|
|
|
|
|
|
|
|
Empty
|
|
|
|
Empty
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
let left = make(p * p, next, rng);
|
|
|
|
let left = make(p * p, next, rng);
|
|
|
|