OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 /** | 5 /** |
6 * A node in a splay tree. It holds the key, the value and the left | 6 * A node in a splay tree. It holds the key, the value and the left |
7 * and right children in the tree. | 7 * and right children in the tree. |
8 */ | 8 */ |
9 class SplayTreeNode<K, V> { | 9 class SplayTreeNode<K, V> { |
10 SplayTreeNode(K this.key, V this.value); | 10 SplayTreeNode(K this.key, V this.value); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
56 // The right child of the dummy node will hold | 56 // The right child of the dummy node will hold |
57 // the L tree of the algorithm. The left child of the dummy node | 57 // the L tree of the algorithm. The left child of the dummy node |
58 // will hold the R tree of the algorithm. Using a dummy node, left | 58 // will hold the R tree of the algorithm. Using a dummy node, left |
59 // and right will always be nodes and we avoid special cases. | 59 // and right will always be nodes and we avoid special cases. |
60 SplayTreeNode<K, V> left = _dummy; | 60 SplayTreeNode<K, V> left = _dummy; |
61 SplayTreeNode<K, V> right = _dummy; | 61 SplayTreeNode<K, V> right = _dummy; |
62 SplayTreeNode<K, V> current = _root; | 62 SplayTreeNode<K, V> current = _root; |
63 while (true) { | 63 while (true) { |
64 int comp = key.compareTo(current.key); | 64 int comp = key.compareTo(current.key); |
65 if (comp < 0) { | 65 if (comp < 0) { |
66 if (current.left === null) break; | 66 if (current.left == null) break; |
67 if (key.compareTo(current.left.key) < 0) { | 67 if (key.compareTo(current.left.key) < 0) { |
68 // Rotate right. | 68 // Rotate right. |
69 SplayTreeNode<K, V> tmp = current.left; | 69 SplayTreeNode<K, V> tmp = current.left; |
70 current.left = tmp.right; | 70 current.left = tmp.right; |
71 tmp.right = current; | 71 tmp.right = current; |
72 current = tmp; | 72 current = tmp; |
73 if (current.left === null) break; | 73 if (current.left == null) break; |
74 } | 74 } |
75 // Link right. | 75 // Link right. |
76 right.left = current; | 76 right.left = current; |
77 right = current; | 77 right = current; |
78 current = current.left; | 78 current = current.left; |
79 } else if (comp > 0) { | 79 } else if (comp > 0) { |
80 if (current.right === null) break; | 80 if (current.right == null) break; |
81 if (key.compareTo(current.right.key) > 0) { | 81 if (key.compareTo(current.right.key) > 0) { |
82 // Rotate left. | 82 // Rotate left. |
83 SplayTreeNode<K, V> tmp = current.right; | 83 SplayTreeNode<K, V> tmp = current.right; |
84 current.right = tmp.left; | 84 current.right = tmp.left; |
85 tmp.left = current; | 85 tmp.left = current; |
86 current = tmp; | 86 current = tmp; |
87 if (current.right === null) break; | 87 if (current.right == null) break; |
88 } | 88 } |
89 // Link left. | 89 // Link left. |
90 left.right = current; | 90 left.right = current; |
91 left = current; | 91 left = current; |
92 current = current.right; | 92 current = current.right; |
93 } else { | 93 } else { |
94 break; | 94 break; |
95 } | 95 } |
96 } | 96 } |
97 // Assemble. | 97 // Assemble. |
(...skipping 16 matching lines...) Expand all Loading... |
114 } | 114 } |
115 | 115 |
116 V remove(K key) { | 116 V remove(K key) { |
117 if (isEmpty) return null; | 117 if (isEmpty) return null; |
118 splay_(key); | 118 splay_(key); |
119 if (_root.key.compareTo(key) != 0) return null; | 119 if (_root.key.compareTo(key) != 0) return null; |
120 V value = _root.value; | 120 V value = _root.value; |
121 | 121 |
122 _count--; | 122 _count--; |
123 // assert(_count >= 0); | 123 // assert(_count >= 0); |
124 if (_root.left === null) { | 124 if (_root.left == null) { |
125 _root = _root.right; | 125 _root = _root.right; |
126 } else { | 126 } else { |
127 SplayTreeNode<K, V> right = _root.right; | 127 SplayTreeNode<K, V> right = _root.right; |
128 _root = _root.left; | 128 _root = _root.left; |
129 // Splay to make sure that the new root has an empty right child. | 129 // Splay to make sure that the new root has an empty right child. |
130 splay_(key); | 130 splay_(key); |
131 // Insert the original right child as the right child of the new | 131 // Insert the original right child as the right child of the new |
132 // root. | 132 // root. |
133 _root.right = right; | 133 _root.right = right; |
134 } | 134 } |
(...skipping 29 matching lines...) Expand all Loading... |
164 } | 164 } |
165 | 165 |
166 V putIfAbsent(K key, V ifAbsent()) { | 166 V putIfAbsent(K key, V ifAbsent()) { |
167 if (containsKey(key)) return this[key]; | 167 if (containsKey(key)) return this[key]; |
168 V value = ifAbsent(); | 168 V value = ifAbsent(); |
169 this[key] = value; | 169 this[key] = value; |
170 return value; | 170 return value; |
171 } | 171 } |
172 | 172 |
173 bool get isEmpty { | 173 bool get isEmpty { |
174 // assert(!((_root === null) && (_count != 0))); | 174 // assert(!((_root == null) && (_count != 0))); |
175 // assert(!((_count == 0) && (_root !== null))); | 175 // assert(!((_count == 0) && (_root != null))); |
176 return (_root === null); | 176 return (_root == null); |
177 } | 177 } |
178 | 178 |
179 void forEach(void f(K key, V value)) { | 179 void forEach(void f(K key, V value)) { |
180 List<SplayTreeNode<K, V>> list = new List<SplayTreeNode<K, V>>(); | 180 List<SplayTreeNode<K, V>> list = new List<SplayTreeNode<K, V>>(); |
181 SplayTreeNode<K, V> current = _root; | 181 SplayTreeNode<K, V> current = _root; |
182 while (current !== null) { | 182 while (current != null) { |
183 if (current.left !== null) { | 183 if (current.left != null) { |
184 list.add(current); | 184 list.add(current); |
185 current = current.left; | 185 current = current.left; |
186 } else { | 186 } else { |
187 f(current.key, current.value); | 187 f(current.key, current.value); |
188 while (current.right === null) { | 188 while (current.right == null) { |
189 if (list.isEmpty) return; | 189 if (list.isEmpty) return; |
190 current = list.removeLast(); | 190 current = list.removeLast(); |
191 f(current.key, current.value); | 191 f(current.key, current.value); |
192 } | 192 } |
193 current = current.right; | 193 current = current.right; |
194 } | 194 } |
195 } | 195 } |
196 } | 196 } |
197 | 197 |
198 int get length { | 198 int get length { |
199 return _count; | 199 return _count; |
200 } | 200 } |
201 | 201 |
202 void clear() { | 202 void clear() { |
203 _root = null; | 203 _root = null; |
204 _count = 0; | 204 _count = 0; |
205 } | 205 } |
206 | 206 |
207 bool containsKey(K key) { | 207 bool containsKey(K key) { |
208 if (!isEmpty) { | 208 if (!isEmpty) { |
209 splay_(key); | 209 splay_(key); |
210 if (_root.key.compareTo(key) == 0) return true; | 210 if (_root.key.compareTo(key) == 0) return true; |
211 } | 211 } |
212 return false; | 212 return false; |
213 } | 213 } |
214 | 214 |
215 bool containsValue(V value) { | 215 bool containsValue(V value) { |
216 bool found = false; | 216 bool found = false; |
217 bool visit(SplayTreeNode node) { | 217 bool visit(SplayTreeNode node) { |
218 if (node === null) return false; | 218 if (node == null) return false; |
219 if (node.value == value) return true; | 219 if (node.value == value) return true; |
220 return visit(node.left) || visit(node.right); | 220 return visit(node.left) || visit(node.right); |
221 } | 221 } |
222 return visit(_root); | 222 return visit(_root); |
223 } | 223 } |
224 | 224 |
225 Collection<K> get keys { | 225 Collection<K> get keys { |
226 List<K> list = new List<K>(); | 226 List<K> list = new List<K>(); |
227 forEach((K k, V v) { list.add(k); }); | 227 forEach((K k, V v) { list.add(k); }); |
228 return list; | 228 return list; |
229 } | 229 } |
230 | 230 |
231 Collection<V> get values { | 231 Collection<V> get values { |
232 List<V> list = new List<V>(); | 232 List<V> list = new List<V>(); |
233 forEach((K k, V v) { list.add(v); }); | 233 forEach((K k, V v) { list.add(v); }); |
234 return list; | 234 return list; |
235 } | 235 } |
236 | 236 |
237 String toString() { | 237 String toString() { |
238 return Maps.mapToString(this); | 238 return Maps.mapToString(this); |
239 } | 239 } |
240 | 240 |
241 /** | 241 /** |
242 * Get the first key in the map. Returns [null] if the map is empty. | 242 * Get the first key in the map. Returns [null] if the map is empty. |
243 */ | 243 */ |
244 K firstKey() { | 244 K firstKey() { |
245 if (_root === null) return null; | 245 if (_root == null) return null; |
246 SplayTreeNode<K, V> node = _root; | 246 SplayTreeNode<K, V> node = _root; |
247 while (node.left !== null) { | 247 while (node.left != null) { |
248 node = node.left; | 248 node = node.left; |
249 } | 249 } |
250 // Maybe implement a splay-method that can splay the minimum without | 250 // Maybe implement a splay-method that can splay the minimum without |
251 // performing comparisons. | 251 // performing comparisons. |
252 splay_(node.key); | 252 splay_(node.key); |
253 return node.key; | 253 return node.key; |
254 } | 254 } |
255 | 255 |
256 /** | 256 /** |
257 * Get the last key in the map. Returns [null] if the map is empty. | 257 * Get the last key in the map. Returns [null] if the map is empty. |
258 */ | 258 */ |
259 K lastKey() { | 259 K lastKey() { |
260 if (_root === null) return null; | 260 if (_root == null) return null; |
261 SplayTreeNode<K, V> node = _root; | 261 SplayTreeNode<K, V> node = _root; |
262 while (node.right !== null) { | 262 while (node.right != null) { |
263 node = node.right; | 263 node = node.right; |
264 } | 264 } |
265 // Maybe implement a splay-method that can splay the maximum without | 265 // Maybe implement a splay-method that can splay the maximum without |
266 // performing comparisons. | 266 // performing comparisons. |
267 splay_(node.key); | 267 splay_(node.key); |
268 return node.key; | 268 return node.key; |
269 } | 269 } |
270 | 270 |
271 /** | 271 /** |
272 * Get the last key in the map that is strictly smaller than [key]. Returns | 272 * Get the last key in the map that is strictly smaller than [key]. Returns |
273 * [null] if no key was not found. | 273 * [null] if no key was not found. |
274 */ | 274 */ |
275 K lastKeyBefore(K key) { | 275 K lastKeyBefore(K key) { |
276 splay_(key); | 276 splay_(key); |
277 K visit(SplayTreeNode node, K ifEmpty) { | 277 K visit(SplayTreeNode node, K ifEmpty) { |
278 if (node === null) return ifEmpty; | 278 if (node == null) return ifEmpty; |
279 if (node.key.compareTo(key) >= 0) { | 279 if (node.key.compareTo(key) >= 0) { |
280 return visit(node.left, ifEmpty); | 280 return visit(node.left, ifEmpty); |
281 } | 281 } |
282 if (node.key.compareTo(key) < 0) { | 282 if (node.key.compareTo(key) < 0) { |
283 return visit(node.right, node.key); | 283 return visit(node.right, node.key); |
284 } | 284 } |
285 } | 285 } |
286 return visit(_root, null); | 286 return visit(_root, null); |
287 } | 287 } |
288 | 288 |
289 /** | 289 /** |
290 * Get the first key in the map that is strictly larger than [key]. Returns | 290 * Get the first key in the map that is strictly larger than [key]. Returns |
291 * [null] if no key was not found. | 291 * [null] if no key was not found. |
292 */ | 292 */ |
293 K firstKeyAfter(K key) { | 293 K firstKeyAfter(K key) { |
294 splay_(key); | 294 splay_(key); |
295 K visit(SplayTreeNode node, K ifEmpty) { | 295 K visit(SplayTreeNode node, K ifEmpty) { |
296 if (node === null) return ifEmpty; | 296 if (node == null) return ifEmpty; |
297 if (node.key.compareTo(key) > 0) { | 297 if (node.key.compareTo(key) > 0) { |
298 return visit(node.left, node.key); | 298 return visit(node.left, node.key); |
299 } | 299 } |
300 if (node.key.compareTo(key) <= 0) { | 300 if (node.key.compareTo(key) <= 0) { |
301 return visit(node.right, ifEmpty); | 301 return visit(node.right, ifEmpty); |
302 } | 302 } |
303 } | 303 } |
304 return visit(_root, null); | 304 return visit(_root, null); |
305 } | 305 } |
306 } | 306 } |
OLD | NEW |