Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(182)

Side by Side Diff: corelib/src/implementation/splay_tree.dart

Issue 9455051: Add getMinimum, getMaximum, getPreceding and getSucceeding to SplayTree. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | tests/corelib/src/SplayTreeTest.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 k, V v) { 10 SplayTreeNode(K this.key, V this.value);
11 key = k;
12 value = v;
13 }
14 11
15 K key; 12 K key;
16 V value; 13 V value;
17 SplayTreeNode<K, V> left; 14 SplayTreeNode<K, V> left;
18 SplayTreeNode<K, V> right; 15 SplayTreeNode<K, V> right;
19 } 16 }
20 17
21 /** 18 /**
22 * A splay tree is a self-balancing binary 19 * A splay tree is a self-balancing binary
23 * search tree with the additional property that recently accessed 20 * search tree with the additional property that recently accessed
24 * elements are quick to access again. It performs basic operations 21 * elements are quick to access again. It performs basic operations
25 * such as insertion, look-up and removal in O(log(n)) amortized time. 22 * such as insertion, look-up and removal in O(log(n)) amortized time.
26 * 23 *
27 * This implementation is a Dart version of the JavaScript 24 * This implementation is a Dart version of the JavaScript
28 * implementation in the V8 project. 25 * implementation in the V8 project.
29 */ 26 */
30 class SplayTree<K extends Comparable, V> implements Map<K, V> { 27 class SplayTreeMap<K extends Comparable, V> implements Map<K, V> {
31 28
32 // The root node of the splay tree. It will contain either the last 29 // The root node of the splay tree. It will contain either the last
33 // element inserted, or the last element looked up. 30 // element inserted, or the last element looked up.
34 SplayTreeNode<K, V> _root; 31 SplayTreeNode<K, V> _root;
35 32
36 // The dummy node used when performing a splay on the tree. It is a 33 // The dummy node used when performing a splay on the tree. It is a
37 // local field of the class to avoid allocating a node each time a 34 // local field of the class to avoid allocating a node each time a
38 // splay is performed. 35 // splay is performed.
39 SplayTreeNode<K, V> _dummy; 36 SplayTreeNode<K, V> _dummy;
40 37
41 // Number of elements in the splay tree. 38 // Number of elements in the splay tree.
42 int _count; 39 int _count;
43 40
44 SplayTree() { 41 SplayTreeMap() {
45 _dummy = new SplayTreeNode<K, V>(null, null); 42 _dummy = new SplayTreeNode<K, V>(null, null);
46 _count = 0; 43 _count = 0;
47 } 44 }
48 45
49 /** 46 /**
50 * Perform the splay operation for the given key. Moves the node with 47 * Perform the splay operation for the given key. Moves the node with
51 * the given key to the top of the tree. If no node has the given 48 * the given key to the top of the tree. If no node has the given
52 * key, the last node on the search path is moved to the top of the 49 * key, the last node on the search path is moved to the top of the
53 * tree. This is the simplified top-down splaying algorithm from: 50 * tree. This is the simplified top-down splaying algorithm from:
54 * "Self-adjusting Binary Search Trees" by Sleator and Tarjan. 51 * "Self-adjusting Binary Search Trees" by Sleator and Tarjan.
(...skipping 16 matching lines...) Expand all
71 SplayTreeNode<K, V> tmp = current.left; 68 SplayTreeNode<K, V> tmp = current.left;
72 current.left = tmp.right; 69 current.left = tmp.right;
73 tmp.right = current; 70 tmp.right = current;
74 current = tmp; 71 current = tmp;
75 if (current.left === null) break; 72 if (current.left === null) break;
76 } 73 }
77 // Link right. 74 // Link right.
78 right.left = current; 75 right.left = current;
79 right = current; 76 right = current;
80 current = current.left; 77 current = current.left;
81 } else if (key.compareTo(current.key) > 0) { 78 } else if (key.compareTo(current.key) > 0) {
sra1 2012/02/27 23:46:04 You could improve this by caching the value return
Anders Johnsen 2012/02/28 12:25:18 I don't expect this to be a huge improvement, but
82 if (current.right === null) break; 79 if (current.right === null) break;
83 if (key.compareTo(current.right.key) > 0) { 80 if (key.compareTo(current.right.key) > 0) {
84 // Rotate left. 81 // Rotate left.
85 SplayTreeNode<K, V> tmp = current.right; 82 SplayTreeNode<K, V> tmp = current.right;
86 current.right = tmp.left; 83 current.right = tmp.left;
87 tmp.left = current; 84 tmp.left = current;
88 current = tmp; 85 current = tmp;
89 if (current.right === null) break; 86 if (current.right === null) break;
90 } 87 }
91 // Link left. 88 // Link left.
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
209 bool containsKey(K key) { 206 bool containsKey(K key) {
210 if (!isEmpty()) { 207 if (!isEmpty()) {
211 splay_(key); 208 splay_(key);
212 if (_root.key.compareTo(key) == 0) return true; 209 if (_root.key.compareTo(key) == 0) return true;
213 } 210 }
214 return false; 211 return false;
215 } 212 }
216 213
217 bool containsValue(V value) { 214 bool containsValue(V value) {
218 bool found = false; 215 bool found = false;
219 // Note: Worst performance you can get because we don't have 216 bool visit(SplayTreeNode node) {
220 // non-local return. 217 if (node === null) return false;
221 // TODO: optimize this method with a similar code than forEach. 218 if (node.value == value) return true;
222 forEach((Object k, Object v) { if (value == v) found = true; }); 219 return visit(node.left) || visit(node.right);
223 return found; 220 }
221 return visit(_root);
224 } 222 }
225 223
226 Collection<K> getKeys() { 224 Collection<K> getKeys() {
227 List<K> list = new List<K>(); 225 List<K> list = new List<K>();
228 forEach((K k, V v) { list.add(k); }); 226 forEach((K k, V v) { list.add(k); });
229 return list; 227 return list;
230 } 228 }
231 229
232 Collection<V> getValues() { 230 Collection<V> getValues() {
233 List<V> list = new List<V>(); 231 List<V> list = new List<V>();
234 forEach((K k, V v) { list.add(v); }); 232 forEach((K k, V v) { list.add(v); });
235 return list; 233 return list;
236 } 234 }
237 235
238 String toString() { 236 String toString() {
239 return Maps.mapToString(this); 237 return Maps.mapToString(this);
240 } 238 }
239
240 /**
241 * Get the first key in the map. Returns [ifEmpty] if the map is empty.
sra1 2012/02/27 23:46:04 There is no ifEmpty parameter. Since it is a key
Anders Johnsen 2012/02/28 12:25:18 Ah yes, ty!
242 */
243 K firstKey() {
244 if (_root === null) return null;
245 SplayTreeNode<K, V> node = _root;
246 while (node.left !== null) {
247 node = node.left;
248 }
249 splay_(node.key);
sra1 2012/02/27 23:46:04 One does wonder if there is a concise specializati
250 return node.key;
251 }
252
253 /**
254 * Get the last key in the map. Returns [ifEmpty] if the map is empty.
sra1 2012/02/27 23:46:04 Ditto.
Anders Johnsen 2012/02/28 12:25:18 Done.
255 */
256 V lastKey() {
257 if (_root === null) return null;
258 SplayTreeNode<K, V> node = _root;
259 while (node.right !== null) {
260 node = node.right;
261 }
262 splay_(node.key);
263 return node.key;
264 }
265
266 /**
267 * Get the last key in the map that is strictly smaller than [key]. Returns
268 * [null] if no key was not found.
269 */
270 K lastKeyBefore(K key) {
271 splay_(key);
272 K visit(SplayTreeNode node, [K ifEmpty]) {
273 if (node === null) return ifEmpty;
274 if (node.key.compareTo(key) >= 0) {
275 return visit(node.left, ifEmpty);
276 }
277 if (node.key.compareTo(key) < 0) {
278 return visit(node.right, node.key);
279 }
280 }
281 return visit(_root);
282 }
283
284 /**
285 * Get the first key in the map that is strictly larger than [key]. Returns
286 * [null] if no key was not found.
287 */
288 K firstKeyAfter(K key) {
289 splay_(key);
290 K visit(SplayTreeNode node, [K ifEmpty]) {
291 if (node === null) return ifEmpty;
292 if (node.key.compareTo(key) > 0) {
293 return visit(node.left, node.key);
294 }
295 if (node.key.compareTo(key) <= 0) {
296 return visit(node.right, ifEmpty);
297 }
298 }
299 return visit(_root);
300 }
241 } 301 }
OLDNEW
« no previous file with comments | « no previous file | tests/corelib/src/SplayTreeTest.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698