Skip to content

Commit 88dbb7c

Browse files
committed
binary-tree: Update.
1 parent fd7632b commit 88dbb7c

File tree

3 files changed

+103
-95
lines changed

3 files changed

+103
-95
lines changed

binary-tree/Cargo.lock

Lines changed: 38 additions & 44 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

binary-tree/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
name = "binary-tree"
33
version = "0.1.0"
44
authors = ["You <[email protected]>"]
5+
edition = "2018"
56

67
[dependencies]
7-
rand = "0.3.14"
8+
rand = "0.8"

binary-tree/src/lib.rs

Lines changed: 63 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,16 @@
11
#![allow(dead_code)]
22

3-
extern crate rand;
4-
53
// An ordered collection of `T`s.
64
enum BinaryTree<T> {
75
Empty,
8-
NonEmpty(Box<TreeNode<T>>)
6+
NonEmpty(Box<TreeNode<T>>),
97
}
108

119
// A part of a BinaryTree.
1210
struct TreeNode<T> {
1311
element: T,
1412
left: BinaryTree<T>,
15-
right: BinaryTree<T>
13+
right: BinaryTree<T>,
1614
}
1715

1816
#[test]
@@ -26,37 +24,42 @@ fn binary_tree_size() {
2624
}
2725

2826
#[test]
29-
fn test_hand_building_tree_of_planets() {
27+
fn build_binary_tree() {
3028
use self::BinaryTree::*;
3129
let jupiter_tree = NonEmpty(Box::new(TreeNode {
3230
element: "Jupiter",
3331
left: Empty,
34-
right: Empty
32+
right: Empty,
3533
}));
34+
3635
let mercury_tree = NonEmpty(Box::new(TreeNode {
3736
element: "Mercury",
3837
left: Empty,
39-
right: Empty
38+
right: Empty,
4039
}));
40+
4141
let mars_tree = NonEmpty(Box::new(TreeNode {
4242
element: "Mars",
4343
left: jupiter_tree,
44-
right: mercury_tree
44+
right: mercury_tree,
4545
}));
46+
4647
let venus_tree = NonEmpty(Box::new(TreeNode {
4748
element: "Venus",
4849
left: Empty,
49-
right: Empty
50+
right: Empty,
5051
}));
52+
5153
let uranus_tree = NonEmpty(Box::new(TreeNode {
5254
element: "Uranus",
5355
left: Empty,
54-
right: venus_tree
56+
right: venus_tree,
5557
}));
58+
5659
let tree = NonEmpty(Box::new(TreeNode {
5760
element: "Saturn",
5861
left: mars_tree,
59-
right: uranus_tree
62+
right: uranus_tree,
6063
}));
6164

6265
assert_eq!(tree.walk(),
@@ -80,18 +83,20 @@ impl<T: Clone> BinaryTree<T> {
8083
impl<T: Ord> BinaryTree<T> {
8184
fn add(&mut self, value: T) {
8285
match *self {
83-
BinaryTree::Empty =>
86+
BinaryTree::Empty => {
8487
*self = BinaryTree::NonEmpty(Box::new(TreeNode {
8588
element: value,
8689
left: BinaryTree::Empty,
87-
right: BinaryTree::Empty
88-
})),
89-
BinaryTree::NonEmpty(ref mut node) =>
90+
right: BinaryTree::Empty,
91+
}))
92+
}
93+
BinaryTree::NonEmpty(ref mut node) => {
9094
if value <= node.element {
9195
node.left.add(value);
9296
} else {
9397
node.right.add(value);
9498
}
99+
}
95100
}
96101
}
97102
}
@@ -113,18 +118,22 @@ fn test_add_method_2() {
113118
let mut tree = BinaryTree::Empty;
114119
tree.add("Mercury");
115120
tree.add("Venus");
116-
for planet in vec!["Mars", "Jupiter", "Saturn", "Uranus"] {
121+
for planet in vec!["Mars", "Jupiter", "Saturn", "Uranus"] {
117122
tree.add(planet);
118123
}
119124

120-
assert_eq!(tree.walk(),
121-
vec!["Jupiter", "Mars", "Mercury", "Saturn", "Uranus", "Venus"]);
125+
assert_eq!(
126+
tree.walk(),
127+
vec!["Jupiter", "Mars", "Mercury", "Saturn", "Uranus", "Venus"]
128+
);
122129
}
123130

131+
// From chapter 15: Iterators
132+
124133
use self::BinaryTree::*;
125134

126135
// The state of an in-order traversal of a `BinaryTree`.
127-
struct TreeIter<'a, T: 'a> {
136+
struct TreeIter<'a, T> {
128137
// A stack of references to tree nodes. Since we use `Vec`'s
129138
// `push` and `pop` methods, the top of the stack is the end of the
130139
// vector.
@@ -164,14 +173,13 @@ impl<'a, T> Iterator for TreeIter<'a, T> {
164173
type Item = &'a T;
165174
fn next(&mut self) -> Option<&'a T> {
166175
// Find the node this iteration must produce,
167-
// or finish the iteration.
168-
let node = match self.unvisited.pop() {
169-
None => return None,
170-
Some(n) => n
171-
};
172-
173-
// The next node after this one is the leftmost child of
174-
// this node's right child, so push the path from here down.
176+
// or finish the iteration. (Use the `?` operator
177+
// to return immediately if it's `None`.)
178+
let node = self.unvisited.pop()?;
179+
180+
// After `node`, the next thing we produce must be the leftmost
181+
// child in `node`'s right subtree, so push the path from here
182+
// down. Our helper method turns out to be just what we need.
175183
self.push_left_edge(&node.right);
176184

177185
// Produce a reference to this node's value.
@@ -188,24 +196,40 @@ fn external_iterator() {
188196
}
189197

190198
// Build a small tree.
191-
let subtree_l = make_node(Empty, "mecha", Empty);
192-
let subtree_rl = make_node(Empty, "droid", Empty);
193-
let subtree_r = make_node(subtree_rl, "robot", Empty);
194-
let tree = make_node(subtree_l, "Jaeger", subtree_r);
199+
let mut tree = BinaryTree::Empty;
200+
tree.add("jaeger");
201+
tree.add("robot");
202+
tree.add("droid");
203+
tree.add("mecha");
195204

196205
// Iterate over it.
197206
let mut v = Vec::new();
198207
for kind in &tree {
199208
v.push(*kind);
200209
}
201-
assert_eq!(v, ["mecha", "Jaeger", "droid", "robot"]);
210+
assert_eq!(v, ["droid", "jaeger", "mecha", "robot"]);
202211

212+
assert_eq!(tree.iter()
213+
.map(|name| format!("mega-{}", name))
214+
.collect::<Vec<_>>(),
215+
vec!["mega-droid", "mega-jaeger",
216+
"mega-mecha", "mega-robot"]);
217+
218+
let mut iterator = (&tree).into_iter();
219+
assert_eq!(iterator.next(), Some(&"droid"));
220+
assert_eq!(iterator.next(), Some(&"jaeger"));
221+
assert_eq!(iterator.next(), Some(&"mecha"));
222+
assert_eq!(iterator.next(), Some(&"robot"));
223+
assert_eq!(iterator.next(), None);
224+
225+
// Construct a tree by hand.
203226
let left_subtree = make_node(Empty, "mecha", Empty);
204227
let right_subtree = make_node(make_node(Empty, "droid", Empty),
205228
"robot",
206229
Empty);
207230
let tree = make_node(left_subtree, "Jaeger", right_subtree);
208231

232+
// Try initializing the iterator ourselves and see if it runs.
209233
let mut v = Vec::new();
210234
let mut iter = TreeIter { unvisited: vec![] };
211235
iter.push_left_edge(&tree);
@@ -214,33 +238,23 @@ fn external_iterator() {
214238
}
215239
assert_eq!(v, ["mecha", "Jaeger", "droid", "robot"]);
216240

241+
// Iterate by shared reference.
217242
let mut v = Vec::new();
218243
for kind in &tree {
219244
v.push(*kind);
220245
}
221246
assert_eq!(v, ["mecha", "Jaeger", "droid", "robot"]);
222247

248+
// Iterate, taking ownership.
223249
let mut v = Vec::new();
224250
let mut state = tree.into_iter();
225251
while let Some(kind) = state.next() {
226252
v.push(*kind);
227253
}
228254
assert_eq!(v, ["mecha", "Jaeger", "droid", "robot"]);
229-
230-
assert_eq!(tree.iter()
231-
.map(|name| format!("mega-{}", name))
232-
.collect::<Vec<_>>(),
233-
vec!["mega-mecha", "mega-Jaeger",
234-
"mega-droid", "mega-robot"]);
235-
236-
let mut iterator = tree.into_iter();
237-
assert_eq!(iterator.next(), Some(&"mecha"));
238-
assert_eq!(iterator.next(), Some(&"Jaeger"));
239-
assert_eq!(iterator.next(), Some(&"droid"));
240-
assert_eq!(iterator.next(), Some(&"robot"));
241-
assert_eq!(iterator.next(), None);
242255
}
243256

257+
244258
#[test]
245259
fn other_cloned() {
246260
use std::collections::BTreeSet;
@@ -257,13 +271,12 @@ fn other_cloned() {
257271
#[test]
258272
fn fuzz() {
259273
fn make_random_tree(p: f32) -> BinaryTree<i32> {
260-
use rand::{ThreadRng, thread_rng};
261-
use rand::distributions::range::Range;
262-
use rand::distributions::Sample;
274+
use rand::prelude::*;
275+
use rand::thread_rng;
276+
use rand::rngs::ThreadRng;
263277

264278
fn make(p: f32, next: &mut i32, rng: &mut ThreadRng) -> BinaryTree<i32> {
265-
let mut range = Range::new(0.0, 1.0);
266-
if range.sample(rng) > p {
279+
if rng.gen_range(0.0 .. 1.0) > p {
267280
Empty
268281
} else {
269282
let left = make(p * p, next, rng);

0 commit comments

Comments
 (0)