1
1
#![ allow( dead_code) ]
2
2
3
- extern crate rand;
4
-
5
3
// An ordered collection of `T`s.
6
4
enum BinaryTree < T > {
7
5
Empty ,
8
- NonEmpty ( Box < TreeNode < T > > )
6
+ NonEmpty ( Box < TreeNode < T > > ) ,
9
7
}
10
8
11
9
// A part of a BinaryTree.
12
10
struct TreeNode < T > {
13
11
element : T ,
14
12
left : BinaryTree < T > ,
15
- right : BinaryTree < T >
13
+ right : BinaryTree < T > ,
16
14
}
17
15
18
16
#[ test]
@@ -26,37 +24,42 @@ fn binary_tree_size() {
26
24
}
27
25
28
26
#[ test]
29
- fn test_hand_building_tree_of_planets ( ) {
27
+ fn build_binary_tree ( ) {
30
28
use self :: BinaryTree :: * ;
31
29
let jupiter_tree = NonEmpty ( Box :: new ( TreeNode {
32
30
element : "Jupiter" ,
33
31
left : Empty ,
34
- right : Empty
32
+ right : Empty ,
35
33
} ) ) ;
34
+
36
35
let mercury_tree = NonEmpty ( Box :: new ( TreeNode {
37
36
element : "Mercury" ,
38
37
left : Empty ,
39
- right : Empty
38
+ right : Empty ,
40
39
} ) ) ;
40
+
41
41
let mars_tree = NonEmpty ( Box :: new ( TreeNode {
42
42
element : "Mars" ,
43
43
left : jupiter_tree,
44
- right : mercury_tree
44
+ right : mercury_tree,
45
45
} ) ) ;
46
+
46
47
let venus_tree = NonEmpty ( Box :: new ( TreeNode {
47
48
element : "Venus" ,
48
49
left : Empty ,
49
- right : Empty
50
+ right : Empty ,
50
51
} ) ) ;
52
+
51
53
let uranus_tree = NonEmpty ( Box :: new ( TreeNode {
52
54
element : "Uranus" ,
53
55
left : Empty ,
54
- right : venus_tree
56
+ right : venus_tree,
55
57
} ) ) ;
58
+
56
59
let tree = NonEmpty ( Box :: new ( TreeNode {
57
60
element : "Saturn" ,
58
61
left : mars_tree,
59
- right : uranus_tree
62
+ right : uranus_tree,
60
63
} ) ) ;
61
64
62
65
assert_eq ! ( tree. walk( ) ,
@@ -80,18 +83,20 @@ impl<T: Clone> BinaryTree<T> {
80
83
impl < T : Ord > BinaryTree < T > {
81
84
fn add ( & mut self , value : T ) {
82
85
match * self {
83
- BinaryTree :: Empty =>
86
+ BinaryTree :: Empty => {
84
87
* self = BinaryTree :: NonEmpty ( Box :: new ( TreeNode {
85
88
element : value,
86
89
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) => {
90
94
if value <= node. element {
91
95
node. left . add ( value) ;
92
96
} else {
93
97
node. right . add ( value) ;
94
98
}
99
+ }
95
100
}
96
101
}
97
102
}
@@ -113,18 +118,22 @@ fn test_add_method_2() {
113
118
let mut tree = BinaryTree :: Empty ;
114
119
tree. add ( "Mercury" ) ;
115
120
tree. add ( "Venus" ) ;
116
- for planet in vec ! [ "Mars" , "Jupiter" , "Saturn" , "Uranus" ] {
121
+ for planet in vec ! [ "Mars" , "Jupiter" , "Saturn" , "Uranus" ] {
117
122
tree. add ( planet) ;
118
123
}
119
124
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
+ ) ;
122
129
}
123
130
131
+ // From chapter 15: Iterators
132
+
124
133
use self :: BinaryTree :: * ;
125
134
126
135
// The state of an in-order traversal of a `BinaryTree`.
127
- struct TreeIter < ' a , T : ' a > {
136
+ struct TreeIter < ' a , T > {
128
137
// A stack of references to tree nodes. Since we use `Vec`'s
129
138
// `push` and `pop` methods, the top of the stack is the end of the
130
139
// vector.
@@ -164,14 +173,13 @@ impl<'a, T> Iterator for TreeIter<'a, T> {
164
173
type Item = & ' a T ;
165
174
fn next ( & mut self ) -> Option < & ' a T > {
166
175
// 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.
175
183
self . push_left_edge ( & node. right ) ;
176
184
177
185
// Produce a reference to this node's value.
@@ -188,24 +196,40 @@ fn external_iterator() {
188
196
}
189
197
190
198
// 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" ) ;
195
204
196
205
// Iterate over it.
197
206
let mut v = Vec :: new ( ) ;
198
207
for kind in & tree {
199
208
v. push ( * kind) ;
200
209
}
201
- assert_eq ! ( v, [ "mecha " , "Jaeger " , "droid " , "robot" ] ) ;
210
+ assert_eq ! ( v, [ "droid " , "jaeger " , "mecha " , "robot" ] ) ;
202
211
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.
203
226
let left_subtree = make_node ( Empty , "mecha" , Empty ) ;
204
227
let right_subtree = make_node ( make_node ( Empty , "droid" , Empty ) ,
205
228
"robot" ,
206
229
Empty ) ;
207
230
let tree = make_node ( left_subtree, "Jaeger" , right_subtree) ;
208
231
232
+ // Try initializing the iterator ourselves and see if it runs.
209
233
let mut v = Vec :: new ( ) ;
210
234
let mut iter = TreeIter { unvisited : vec ! [ ] } ;
211
235
iter. push_left_edge ( & tree) ;
@@ -214,33 +238,23 @@ fn external_iterator() {
214
238
}
215
239
assert_eq ! ( v, [ "mecha" , "Jaeger" , "droid" , "robot" ] ) ;
216
240
241
+ // Iterate by shared reference.
217
242
let mut v = Vec :: new ( ) ;
218
243
for kind in & tree {
219
244
v. push ( * kind) ;
220
245
}
221
246
assert_eq ! ( v, [ "mecha" , "Jaeger" , "droid" , "robot" ] ) ;
222
247
248
+ // Iterate, taking ownership.
223
249
let mut v = Vec :: new ( ) ;
224
250
let mut state = tree. into_iter ( ) ;
225
251
while let Some ( kind) = state. next ( ) {
226
252
v. push ( * kind) ;
227
253
}
228
254
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 ) ;
242
255
}
243
256
257
+
244
258
#[ test]
245
259
fn other_cloned ( ) {
246
260
use std:: collections:: BTreeSet ;
@@ -257,13 +271,12 @@ fn other_cloned() {
257
271
#[ test]
258
272
fn fuzz ( ) {
259
273
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 ;
263
277
264
278
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 {
267
280
Empty
268
281
} else {
269
282
let left = make ( p * p, next, rng) ;
0 commit comments