-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathlib.rs
415 lines (381 loc) · 14.4 KB
/
lib.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
//! This crate contains Recursive & Iterative Binary Search Tree Implementations. All common operations are included along with common traversal iterators.
//!
//! All elements within the Binary Search Trees _must_ implement the [Ord] trait.
//!
//! It is also important to note that [RecursiveBST] is more likely to `blow the stack.`
//! For more information on why that is the case, please have a look at
//! [The Story of Tail Call Optimizations in Rust.](https://seanchen1991.github.io/posts/tco-story/)
//!
//! ## Author Notes
//!
//! I have made this library with the personal goals of learning and solidifying concepts such
//! as **ownership**, **borrowing**, **generics** and **lifetimes**. I cannot promise that the implementations are
//! particularly efficient, or if they are, it was not at the forefront of my mind.
//!
//! That being said, there are some areas I would love to improve upon which include:
//! - Write idiomatic code.
//! - Effectively use **macro_rules!** to reduce large portions of repetitive code.
//! - Implement a **pretty_print()** function to display the binary search trees nicely.
//! - Implement [Drop] trait for iterative node cleanup.
//! - Pre-allocate space on the heap for nodes to reduce inefficiency of inserts.
//!
//! I'm more than happy to accept (and encourage) contributions if anyone is kind enough to do so.
//!
//! # Quick Start
//!
//! ```rust
//! use bst_rs::{BinarySearchTree, IterativeBST, RecursiveBST};
//!
//! // Create new empty binary search trees
//! let mut iterative_bst = IterativeBST::new();
//! assert!(iterative_bst.is_empty());
//!
//! let mut recursive_bst = RecursiveBST::new();
//! assert!(recursive_bst.is_empty());
//!
//! // Insert elements (no duplicates are allowed)
//! iterative_bst.insert(10);
//! iterative_bst.insert(10); // Element is not inserted
//! iterative_bst.insert(5);
//! iterative_bst.insert(2);
//! iterative_bst.insert(15);
//! iterative_bst.insert(25);
//! assert_eq!(iterative_bst.size(), 5);
//!
//! recursive_bst.insert(10);
//! recursive_bst.insert(10); // Element is not inserted
//! recursive_bst.insert(5);
//! recursive_bst.insert(2);
//! recursive_bst.insert(15);
//! recursive_bst.insert(25);
//! assert_eq!(recursive_bst.size(), 5);
//!
//! // Check if element exists
//! assert!(iterative_bst.contains(&5)); // true
//! assert!(!iterative_bst.contains(&0)); // false
//!
//! assert!(recursive_bst.contains(&5)); // true
//! assert!(!recursive_bst.contains(&0)); // false
//!
//! // Remove elements
//! iterative_bst.remove(&10);
//! iterative_bst.remove(&50); // No change to tree as element does not exist
//! assert_eq!(iterative_bst.size(), 4);
//!
//! recursive_bst.remove(&10);
//! recursive_bst.remove(&50); // No change to tree as element does not exist
//! assert_eq!(recursive_bst.size(), 4);
//!
//! // View pre-order, in-order, post-order and level-order traversals
//! assert_eq!(iterative_bst.pre_order_vec(), vec![&15, &5, &2, &25]);
//! assert_eq!(iterative_bst.in_order_vec(), vec![&2, &5, &15, &25]);
//! assert_eq!(iterative_bst.post_order_vec(), vec![&2, &5, &25, &15]);
//! assert_eq!(iterative_bst.level_order_vec(), vec![&15, &5, &25, &2]);
//!
//! assert_eq!(recursive_bst.pre_order_vec(), vec![&15, &5, &2, &25]);
//! assert_eq!(recursive_bst.in_order_vec(), vec![&2, &5, &15, &25]);
//! assert_eq!(recursive_bst.post_order_vec(), vec![&2, &5, &25, &15]);
//! assert_eq!(recursive_bst.level_order_vec(), vec![&15, &5, &25, &2]);
//!
//! // Compare equality/in-equality of trees
//! assert_eq!(iterative_bst.asc_order_vec(), recursive_bst.asc_order_vec());
//! assert_ne!(iterative_bst, IterativeBST::new());
//! assert_ne!(recursive_bst, RecursiveBST::new());
//! ```
use crate::node::{HeapNode, Node};
use std::vec::IntoIter;
mod node;
mod iterative;
mod recursive;
pub use recursive::RecursiveBST;
pub use iterative::IterativeBST;
/// Creates a [`IterativeBST`] containing the arguments.
///
/// # Important
///
/// If given no arguments this will be equivalent to calling
/// `IterativeBST::new()`
///
/// # Example
/// - Create a [`IterativeBST`] containing a given list of elements:
///
/// ```rust
/// use bst_rs::{BinarySearchTree, IterativeBST, bst};
///
/// let t1 = bst![1, 2, 3];
/// // Which is functionally equivalent to
/// let t2 = IterativeBST::from_iter(vec![1,2,3]);
/// // and produces the following tree
/// // 2
/// // / \
/// // 1 3
/// assert_eq!(t1, t2);
/// ```
///
/// [`IterativeBST`]: crate::IterativeBST
#[macro_export]
macro_rules! bst {
() => (
$crate::IterativeBST::new()
);
($($x:expr),+ $(,)?) => (
$crate::IterativeBST::from_iter(vec![$($x),+].into_iter())
);
}
#[cfg(test)]
mod tests {
use super::{bst, BinarySearchTree, IterativeBST};
#[test]
fn successfully_construct_bst_from_macro() {
let mut actual_bst = IterativeBST::new();
actual_bst.insert(3);
actual_bst.insert(2);
let expected_bst = bst![3, 2];
assert_eq!(actual_bst, expected_bst);
}
#[test]
fn verify_permutations_produce_same_tree() {
let actual_bst = bst![2, 3];
let expected_bst = bst![3, 2];
assert_eq!(actual_bst, expected_bst);
}
}
/// A trait containing all the common operations of Binary Search Trees.
///
/// # Examples
/// Examples are extended from crate level "Quick Start"
///
/// ```rust
/// use bst_rs::{BinarySearchTree, IterativeBST, RecursiveBST};
///
/// // Create new empty binary search trees
/// let mut iterative_bst = IterativeBST::new();
/// assert!(iterative_bst.is_empty());///
///
/// let mut recursive_bst = RecursiveBST::new();
/// assert!(recursive_bst.is_empty());
///
/// // Insert elements (no duplicates are allowed)
/// iterative_bst.insert(10);
/// iterative_bst.insert(10); // Element is not inserted
/// iterative_bst.insert(5);
/// iterative_bst.insert(2);
/// iterative_bst.insert(15);
/// iterative_bst.insert(25);
/// assert_eq!(iterative_bst.size(), 5);
///
/// recursive_bst.insert(10);
/// recursive_bst.insert(10); // Element is not inserted
/// recursive_bst.insert(5);
/// recursive_bst.insert(2);
/// recursive_bst.insert(15);
/// recursive_bst.insert(25);
/// assert_eq!(recursive_bst.size(), 5);
///
/// // Check if element exists
/// assert!(iterative_bst.contains(&5)); // true
/// assert!(!iterative_bst.contains(&0)); // false
///
/// assert!(recursive_bst.contains(&5)); // true
/// assert!(!recursive_bst.contains(&0)); // false
///
/// // Remove elements
/// iterative_bst.remove(&10);
/// iterative_bst.remove(&50); // No change to tree as element does not exist
/// assert_eq!(iterative_bst.size(), 4);
///
/// recursive_bst.remove(&10);
/// recursive_bst.remove(&50); // No change to tree as element does not exist
/// assert_eq!(recursive_bst.size(), 4);
///
/// // Get height of tree
/// assert_eq!(iterative_bst.height(), Some(2));
/// assert_eq!(recursive_bst.height(), Some(2));
///
/// // Get minimum element of tree
/// assert_eq!(iterative_bst.min(), Some(&2));
/// assert_eq!(recursive_bst.min(), Some(&2));
///
/// // Get maximum element of tree
/// assert_eq!(iterative_bst.max(), Some(&25));
/// assert_eq!(recursive_bst.max(), Some(&25));
///
/// // Retrieve reference to element in tree
/// assert_eq!(iterative_bst.retrieve(&5), Some(&5));
/// assert_eq!(iterative_bst.retrieve(&100), None); // Element does not exist so None is returned
/// assert_eq!(recursive_bst.retrieve(&5), Some(&5));
/// assert_eq!(recursive_bst.retrieve(&100), None); // Element does not exist so None is returned
///
/// // View pre-order, in-order, post-order and level-order traversals
/// assert_eq!(iterative_bst.pre_order_vec(), vec![&15, &5, &2, &25]);
/// assert_eq!(iterative_bst.in_order_vec(), vec![&2, &5, &15, &25]);
/// assert_eq!(iterative_bst.post_order_vec(), vec![&2, &5, &25, &15]);
/// assert_eq!(iterative_bst.level_order_vec(), vec![&15, &5, &25, &2]);
///
/// assert_eq!(recursive_bst.pre_order_vec(), vec![&15, &5, &2, &25]);
/// assert_eq!(recursive_bst.in_order_vec(), vec![&2, &5, &15, &25]);
/// assert_eq!(recursive_bst.post_order_vec(), vec![&2, &5, &25, &15]);
/// assert_eq!(recursive_bst.level_order_vec(), vec![&15, &5, &25, &2]);
///
/// // Compare equality/in-equality of trees
/// assert_eq!(iterative_bst.asc_order_vec(), recursive_bst.asc_order_vec());
/// assert_ne!(iterative_bst, IterativeBST::new());
/// assert_ne!(recursive_bst, RecursiveBST::new());
/// ```
pub trait BinarySearchTree<T: Ord> {
/// Returns the total **number of nodes** within the tree.
fn size(&self) -> usize;
/// Returns `true` if the binary search tree contains no nodes.
fn is_empty(&self) -> bool;
/// Returns `true` if the binary search tree contains one or more nodes.
fn is_not_empty(&self) -> bool;
/// Inserts given value as a node.
///
/// **Duplicate values are _not allowed_**.
fn insert(&mut self, value: T);
/// Returns `true` if the binary search tree contains an element with the given value.
fn contains(&self, value: &T) -> bool;
/// Removes the given value.
///
/// Tree will not be modified if trying to remove element that does not exist.
fn remove(&mut self, value: &T);
/// Returns a reference to the element or `None` if element does not exist.
fn retrieve(&self, value: &T) -> Option<&T>;
/// Returns a mutable reference to the element (see [`retrieve`](Self::retrieve()))
/// or `None` if element does not exist.
fn retrieve_as_mut(&mut self, value: &T) -> Option<&mut T>;
/// Returns the **height** or `None` if tree is empty.
///
/// The height is the number of edges between the root and it's furthest leaf node.
///
/// # Example
///
/// Given a tree that looks like:
///
/// ```text
/// 4
/// / \
/// 2 6
/// / \ / \
/// 1 3 5 7
/// ```
///
/// The height is: **2**
fn height(&self) -> Option<isize>;
/// Returns a reference to the minimum element of the tree or `None` if tree is empty.
fn min(&self) -> Option<&T>;
/// Returns a reference to the maximum element of the tree or `None` if tree is empty.
fn max(&self) -> Option<&T>;
/// Removes and returns the minimum element from the tree or `None` if tree is empty.
fn remove_min(&mut self) -> Option<T>;
/// Removes and returns the maximum element from the tree or `None` if tree is empty.
fn remove_max(&mut self) -> Option<T>;
/// Returns references to the elements of the tree in **ascending order.**
///
/// # Important
///
/// This function is analogous to [in_order_vec](Self::in_order_vec()) as the underlying
/// behaviour is **_exactly the same_.**
fn asc_order_vec(&self) -> Vec<&T>;
/// Returns references to the elements of the tree in the order of a **pre-order traversal.**
///
/// # Example
///
/// Given a tree that looks like:
/// ```text
/// 4
/// / \
/// 2 6
/// / \ / \
/// 1 3 5 7
/// ```
/// The pre_order_vec is: **[&4, &2, &1, &3, &6, &5, &7].**
fn pre_order_vec(&self) -> Vec<&T>;
/// Returns references to the elements of the tree in the order of an **in-order traversal.**
///
/// # Important
///
/// This function is analogous to [asc_order_vec](Self::asc_order_vec()) as the underlying
/// behaviour is **_exactly the same_.**
///
/// # Example
///
/// Given a tree that looks like:
/// ```text
/// 4
/// / \
/// 2 6
/// / \ / \
/// 1 3 5 7
/// ```
/// The in_order_vec is: **[&1, &2, &3, &4, &5, &6, &7].**
fn in_order_vec(&self) -> Vec<&T>;
/// Returns references to the elements of the tree in the order of a **post-order traversal.**
///
/// # Example
///
/// Given a tree that looks like:
/// ```text
/// 4
/// / \
/// 2 6
/// / \ / \
/// 1 3 5 7
/// ```
/// The post_order_vec is: **[&1, &3, &2, &5, &7, &6, &4].**
fn post_order_vec(&self) -> Vec<&T>;
/// Returns references to the elements of the tree in the order of a **level-order traversal.**
///
/// # Example
///
/// Given a tree that looks like:
/// ```text
/// 4
/// / \
/// 2 6
/// / \ / \
/// 1 3 5 7
/// ```
/// The post_order_vec is: **[&4, &2, &6, &1, &3, &5, &7].**
fn level_order_vec(&self) -> Vec<&T>;
/// Returns an iterator over [asc_order_vec](Self::asc_order_vec()).
///
/// # Important
///
/// This function is analogous to [in_order_iter](Self::in_order_iter()) as the underlying
/// behaviour is **_exactly the same_.**
fn asc_order_iter(&self) -> IntoIter<&T>;
/// Returns an iterator over [pre_order_vec](Self::pre_order_vec()).
fn pre_order_iter(&self) -> IntoIter<&T>;
/// Returns an iterator over [in_order_vec](Self::in_order_vec()).
///
/// # Important
///
/// This function is analogous to [asc_order_iter](Self::asc_order_iter()) as the underlying
/// behaviour is **_exactly the same_.**
fn in_order_iter(&self) -> IntoIter<&T>;
/// Returns an iterator over [post_order_vec](Self::post_order_vec()).
fn post_order_iter(&self) -> IntoIter<&T>;
/// Returns an iterator over [level_order_vec](Self::level_order_vec()).
fn level_order_iter(&self) -> IntoIter<&T>;
/// Returns [asc_order_iter](Self::asc_order_iter()) **AND** consumes the tree.
///
/// # Important
///
/// This function is analogous to [into_in_order_iter](Self::into_in_order_iter()) as the
/// underlying behaviour is **_exactly the same_.**
fn into_asc_order_iter(self) -> IntoIter<T>;
/// Returns [pre_order_iter](Self::pre_order_iter()) **AND** consumes the tree.
fn into_pre_order_iter(self) -> IntoIter<T>;
/// Returns [in_order_iter](Self::in_order_iter()) **AND** consumes the tree.
///
/// # Important
///
/// This function is analogous to [into_asc_order_iter](Self::into_asc_order_iter()) as the
/// underlying behaviour is **_exactly the same_.**
fn into_in_order_iter(self) -> IntoIter<T>;
/// Returns [post_order_iter](Self::post_order_iter()) **AND** consumes the tree.
fn into_post_order_iter(self) -> IntoIter<T>;
/// Returns [level_order_iter](Self::level_order_iter()) **AND** consumes the tree.
fn into_level_order_iter(self) -> IntoIter<T>;
}