|
1 | 1 | use std::cmp::Ordering; |
2 | | -use std::ops::Deref; |
3 | 2 |
|
4 | 3 | /// This struct implements as Binary Search Tree (BST), which is a |
5 | 4 | /// simple data structure for storing sorted data |
@@ -38,29 +37,29 @@ where |
38 | 37 | /// tree, and false otherwise |
39 | 38 | pub fn search(&self, value: &T) -> bool { |
40 | 39 | match &self.value { |
41 | | - Some(key) => { |
42 | | - match key.cmp(value) { |
43 | | - Ordering::Equal => { |
44 | | - // key == value |
45 | | - true |
46 | | - } |
47 | | - Ordering::Greater => { |
48 | | - // key > value |
49 | | - match &self.left { |
50 | | - Some(node) => node.search(value), |
51 | | - None => false, |
52 | | - } |
| 40 | + // empty tree |
| 41 | + None => false, |
| 42 | + // non-empty tree |
| 43 | + Some(key) => match value.cmp(key) { |
| 44 | + // target == root's key |
| 45 | + Ordering::Equal => true, |
| 46 | + // target < root's key |
| 47 | + Ordering::Less => { |
| 48 | + if let Some(node) = &self.left { |
| 49 | + node.search(value) |
| 50 | + } else { |
| 51 | + false |
53 | 52 | } |
54 | | - Ordering::Less => { |
55 | | - // key < value |
56 | | - match &self.right { |
57 | | - Some(node) => node.search(value), |
58 | | - None => false, |
59 | | - } |
| 53 | + } |
| 54 | + // target > root's key |
| 55 | + Ordering::Greater => { |
| 56 | + if let Some(node) = &self.right { |
| 57 | + node.search(value) |
| 58 | + } else { |
| 59 | + false |
60 | 60 | } |
61 | 61 | } |
62 | | - } |
63 | | - None => false, |
| 62 | + }, |
64 | 63 | } |
65 | 64 | } |
66 | 65 |
|
@@ -112,67 +111,68 @@ where |
112 | 111 | /// Returns the largest value in this tree smaller than value |
113 | 112 | pub fn floor(&self, value: &T) -> Option<&T> { |
114 | 113 | match &self.value { |
115 | | - Some(key) => { |
116 | | - match key.cmp(value) { |
117 | | - Ordering::Greater => { |
118 | | - // key > value |
119 | | - match &self.left { |
120 | | - Some(node) => node.floor(value), |
121 | | - None => None, |
122 | | - } |
| 114 | + // empty tree |
| 115 | + None => None, |
| 116 | + // non-empty tree |
| 117 | + Some(key) => match value.cmp(key) { |
| 118 | + // value == root's key |
| 119 | + Ordering::Equal => Some(key), |
| 120 | + // value < root's key |
| 121 | + Ordering::Less => { |
| 122 | + if let Some(node) = &self.left { |
| 123 | + node.floor(value) |
| 124 | + } else { |
| 125 | + None |
123 | 126 | } |
124 | | - Ordering::Less => { |
125 | | - // key < value |
126 | | - match &self.right { |
127 | | - Some(node) => { |
128 | | - let val = node.floor(value); |
129 | | - match val { |
130 | | - Some(_) => val, |
131 | | - None => Some(key), |
132 | | - } |
133 | | - } |
| 127 | + } |
| 128 | + // value > root's key |
| 129 | + Ordering::Greater => match &self.right { |
| 130 | + // right child is None |
| 131 | + None => Some(key), |
| 132 | + // right child is not None |
| 133 | + Some(node) => { |
| 134 | + let val = node.floor(value); |
| 135 | + match val { |
134 | 136 | None => Some(key), |
| 137 | + Some(_) => val, |
135 | 138 | } |
136 | 139 | } |
137 | | - Ordering::Equal => Some(key), |
138 | | - } |
139 | | - } |
140 | | - None => None, |
| 140 | + }, |
| 141 | + }, |
141 | 142 | } |
142 | 143 | } |
143 | 144 |
|
144 | 145 | /// Returns the smallest value in this tree larger than value |
145 | 146 | pub fn ceil(&self, value: &T) -> Option<&T> { |
146 | 147 | match &self.value { |
147 | | - Some(key) => { |
148 | | - match key.cmp(value) { |
149 | | - Ordering::Less => { |
150 | | - // key < value |
151 | | - match &self.right { |
152 | | - Some(node) => node.ceil(value), |
153 | | - None => None, |
154 | | - } |
| 148 | + // empty tree |
| 149 | + None => None, |
| 150 | + // non-empty tree |
| 151 | + Some(key) => match value.cmp(key) { |
| 152 | + // value == root's key |
| 153 | + Ordering::Equal => Some(key), |
| 154 | + // value > root's key |
| 155 | + Ordering::Greater => { |
| 156 | + if let Some(node) = &self.right { |
| 157 | + node.ceil(value) |
| 158 | + } else { |
| 159 | + None |
155 | 160 | } |
156 | | - Ordering::Greater => { |
157 | | - // key > value |
158 | | - match &self.left { |
159 | | - Some(node) => { |
160 | | - let val = node.ceil(value); |
161 | | - match val { |
162 | | - Some(_) => val, |
163 | | - None => Some(key), |
164 | | - } |
165 | | - } |
| 161 | + } |
| 162 | + // value < root's key |
| 163 | + Ordering::Less => match &self.left { |
| 164 | + // left child is None |
| 165 | + None => Some(key), |
| 166 | + // left child is not None |
| 167 | + Some(node) => { |
| 168 | + let val = node.ceil(value); |
| 169 | + match val { |
166 | 170 | None => Some(key), |
| 171 | + Some(_) => val, |
167 | 172 | } |
168 | 173 | } |
169 | | - Ordering::Equal => { |
170 | | - // key == value |
171 | | - Some(key) |
172 | | - } |
173 | | - } |
174 | | - } |
175 | | - None => None, |
| 174 | + }, |
| 175 | + }, |
176 | 176 | } |
177 | 177 | } |
178 | 178 | } |
@@ -208,15 +208,15 @@ where |
208 | 208 | type Item = &'a T; |
209 | 209 |
|
210 | 210 | fn next(&mut self) -> Option<&'a T> { |
211 | | - if self.stack.is_empty() { |
212 | | - None |
213 | | - } else { |
214 | | - let node = self.stack.pop().unwrap(); |
215 | | - if let Some(right_node) = &node.right { |
216 | | - self.stack.push(right_node.deref()); |
217 | | - self.stack_push_left(); |
| 211 | + match self.stack.pop() { |
| 212 | + None => None, |
| 213 | + Some(node) => { |
| 214 | + if let Some(right_node) = &node.right { |
| 215 | + self.stack.push(right_node); |
| 216 | + self.stack_push_left(); |
| 217 | + } |
| 218 | + node.value.as_ref() |
218 | 219 | } |
219 | | - node.value.as_ref() |
220 | 220 | } |
221 | 221 | } |
222 | 222 | } |
@@ -250,6 +250,13 @@ mod test { |
250 | 250 | ); |
251 | 251 | assert!(!tree.search(&"only a sith deals in absolutes")); |
252 | 252 | assert!(!tree.search(&"you underestimate my power")); |
| 253 | + assert!(!tree.search(&"apple pie")); |
| 254 | + |
| 255 | + let empty_tree = BinarySearchTree::<i32>::new(); |
| 256 | + assert!(!empty_tree.search(&12)); |
| 257 | + assert!(!empty_tree.search(&-5)); |
| 258 | + assert!(!empty_tree.search(&0)); |
| 259 | + assert!(!empty_tree.search(&5)); |
253 | 260 | } |
254 | 261 |
|
255 | 262 | #[test] |
@@ -316,6 +323,10 @@ mod test { |
316 | 323 | "your move" |
317 | 324 | ); |
318 | 325 | assert!(tree.ceil(&"your new empire").is_none()); |
| 326 | + |
| 327 | + let empty_tree = BinarySearchTree::<i32>::new(); |
| 328 | + assert!(empty_tree.floor(&12).is_none()); |
| 329 | + assert!(empty_tree.ceil(&12).is_none()); |
319 | 330 | } |
320 | 331 |
|
321 | 332 | #[test] |
|
0 commit comments