2 * Copyright 2008-2009, Ingo Weinhold <ingo_weinhold@gmx.de>.
3 * Distributed under the terms of the MIT License.
5 * Original Java implementation:
6 * Available at http://www.link.cs.cmu.edu/splay/
7 * Author: Danny Sleator <sleator@cs.cmu.edu>
8 * This code is in the public domain.
10 #ifndef KERNEL_UTIL_SPLAY_TREE_H
11 #define KERNEL_UTIL_SPLAY_TREE_H
13 /*! Implements two classes:
15 SplayTree: A top-down splay tree.
17 IteratableSplayTree: Extends SplayTree by a singly-linked list to make it
18 cheaply iteratable (requires another pointer per node).
20 Both classes are templatized over a definition parameter with the following
21 (or a compatible) interface:
23 struct SplayTreeDefinition {
27 static const KeyType& GetKey(const NodeType* node);
28 static SplayTreeLink<NodeType>* GetLink(NodeType* node);
30 static int Compare(const KeyType& key, const NodeType* node);
32 // for IteratableSplayTree only
33 static NodeType** GetListLink(NodeType* node);
38 template<typename Node
>
39 struct SplayTreeLink
{
45 template<typename Definition
>
48 typedef typename
Definition::KeyType Key
;
49 typedef typename
Definition::NodeType Node
;
50 typedef SplayTreeLink
<Node
> Link
;
61 \param node the item to insert.
63 bool Insert(Node
* node
)
65 Link
* nodeLink
= Definition::GetLink(node
);
69 nodeLink
->left
= NULL
;
70 nodeLink
->right
= NULL
;
74 Key key
= Definition::GetKey(node
);
77 int c
= Definition::Compare(key
, fRoot
);
81 Link
* rootLink
= Definition::GetLink(fRoot
);
84 nodeLink
->left
= rootLink
->left
;
85 nodeLink
->right
= fRoot
;
86 rootLink
->left
= NULL
;
88 nodeLink
->right
= rootLink
->right
;
89 nodeLink
->left
= fRoot
;
90 rootLink
->right
= NULL
;
97 Node
* Remove(const Key
& key
)
104 if (Definition::Compare(key
, fRoot
) != 0)
107 // Now delete the root
109 Link
* rootLink
= Definition::GetLink(fRoot
);
110 if (rootLink
->left
== NULL
) {
111 fRoot
= rootLink
->right
;
113 Node
* temp
= rootLink
->right
;
114 fRoot
= rootLink
->left
;
116 Definition::GetLink(fRoot
)->right
= temp
;
123 Remove from the tree.
124 \param node the item to remove.
126 bool Remove(Node
* node
)
128 Key key
= Definition::GetKey(node
);
134 // Now delete the root
135 Link
* rootLink
= Definition::GetLink(fRoot
);
136 if (rootLink
->left
== NULL
) {
137 fRoot
= rootLink
->right
;
139 Node
* temp
= rootLink
->right
;
140 fRoot
= rootLink
->left
;
142 Definition::GetLink(fRoot
)->right
= temp
;
149 Find the smallest item in the tree.
158 while (Node
* left
= Definition::GetLink(node
)->left
)
161 _Splay(Definition::GetKey(node
));
167 Find the largest item in the tree.
176 while (Node
* right
= Definition::GetLink(node
)->right
)
179 _Splay(Definition::GetKey(node
));
185 Find an item in the tree.
187 Node
* Lookup(const Key
& key
)
194 return Definition::Compare(key
, fRoot
) == 0 ? fRoot
: NULL
;
203 Test if the tree is logically empty.
204 \return true if empty, false otherwise.
208 return fRoot
== NULL
;
211 Node
* PreviousDontSplay(const Key
& key
) const
213 Node
* closestNode
= NULL
;
215 while (node
!= NULL
) {
216 if (Definition::Compare(key
, node
) > 0) {
218 node
= Definition::GetLink(node
)->right
;
220 node
= Definition::GetLink(node
)->left
;
226 Node
* FindClosest(const Key
& key
, bool greater
, bool orEqual
)
233 Node
* closestNode
= NULL
;
235 while (node
!= NULL
) {
236 int compare
= Definition::Compare(key
, node
);
237 if (compare
== 0 && orEqual
)
243 node
= Definition::GetLink(node
)->left
;
245 node
= Definition::GetLink(node
)->right
;
249 node
= Definition::GetLink(node
)->right
;
251 node
= Definition::GetLink(node
)->left
;
258 SplayTree
& operator=(const SplayTree
& other
)
266 Internal method to perform a top-down splay.
268 _Splay(key) does the splay operation on the given key.
269 If key is in the tree, then the node containing
270 that key becomes the root. If key is not in the tree,
271 then after the splay, key.root is either the greatest key
272 < key in the tree, or the least key > key in the tree.
274 This means, among other things, that if you splay with
275 a key that's larger than any in the tree, the rightmost
276 node of the tree becomes the root. This property is used
277 in the Remove() method.
279 void _Splay(const Key
& key
) {
281 headerLink
.left
= headerLink
.right
= NULL
;
283 Link
* lLink
= &headerLink
;
284 Link
* rLink
= &headerLink
;
291 int c
= Definition::Compare(key
, t
);
293 Node
*& left
= Definition::GetLink(t
)->left
;
297 if (Definition::Compare(key
, left
) < 0) {
300 Link
* yLink
= Definition::GetLink(y
);
304 if (yLink
->left
== NULL
)
311 rLink
= Definition::GetLink(r
);
314 Node
*& right
= Definition::GetLink(t
)->right
;
318 if (Definition::Compare(key
, right
) > 0) {
321 Link
* yLink
= Definition::GetLink(y
);
325 if (yLink
->right
== NULL
)
332 lLink
= Definition::GetLink(l
);
339 Link
* tLink
= Definition::GetLink(t
);
340 lLink
->right
= tLink
->left
;
341 rLink
->left
= tLink
->right
;
342 tLink
->left
= headerLink
.right
;
343 tLink
->right
= headerLink
.left
;
352 template<typename Definition
>
353 class IteratableSplayTree
{
355 typedef typename
Definition::KeyType Key
;
356 typedef typename
Definition::NodeType Node
;
357 typedef SplayTreeLink
<Node
> Link
;
358 typedef IteratableSplayTree
<Definition
> Tree
;
367 Iterator(const Iterator
& other
)
379 Iterator(Tree
* tree
, Node
* next
)
389 return fNext
!= NULL
;
396 fNext
= *Definition::GetListLink(fNext
);
407 Node
* element
= fCurrent
;
409 fTree
->Remove(fCurrent
);
415 Iterator
&operator=(const Iterator
&other
)
418 fCurrent
= other
.fCurrent
;
426 fNext
= fTree
->fFirst
;
435 class ConstIterator
{
441 ConstIterator(const ConstIterator
& other
)
446 ConstIterator(const Tree
* tree
)
453 ConstIterator(const Tree
* tree
, Node
* next
)
462 return fNext
!= NULL
;
469 fNext
= *Definition::GetListLink(fNext
);
473 ConstIterator
&operator=(const ConstIterator
&other
)
482 fNext
= fTree
->fFirst
;
490 IteratableSplayTree()
497 bool Insert(Node
* node
)
499 if (!fTree
.Insert(node
))
503 if (Node
* previous
= fTree
.PreviousDontSplay(Definition::GetKey(node
)))
504 previousNext
= Definition::GetListLink(previous
);
506 previousNext
= &fFirst
;
508 *Definition::GetListLink(node
) = *previousNext
;
509 *previousNext
= node
;
514 Node
* Remove(const Key
& key
)
516 Node
* node
= fTree
.Remove(key
);
521 if (Node
* previous
= fTree
.PreviousDontSplay(key
))
522 previousNext
= Definition::GetListLink(previous
);
524 previousNext
= &fFirst
;
526 *previousNext
= *Definition::GetListLink(node
);
531 bool Remove(Node
* node
)
533 if (!fTree
.Remove(node
))
537 if (Node
* previous
= fTree
.PreviousDontSplay(Definition::GetKey(node
)))
538 previousNext
= Definition::GetListLink(previous
);
540 previousNext
= &fFirst
;
542 *previousNext
= *Definition::GetListLink(node
);
547 Node
* Lookup(const Key
& key
)
549 return fTree
.Lookup(key
);
558 Test if the tree is logically empty.
559 \return true if empty, false otherwise.
563 return fTree
.IsEmpty();
566 Node
* FindClosest(const Key
& key
, bool greater
, bool orEqual
)
568 return fTree
.FindClosest(key
, greater
, orEqual
);
573 return fTree
.FindMin();
578 return fTree
.FindMax();
581 Iterator
GetIterator()
583 return Iterator(this);
586 ConstIterator
GetIterator() const
588 return ConstIterator(this);
591 Iterator
GetIterator(const Key
& key
, bool greater
, bool orEqual
)
593 return Iterator(this, fTree
.FindClosest(key
, greater
, orEqual
));
596 ConstIterator
GetIterator(const Key
& key
, bool greater
, bool orEqual
) const
598 return ConstIterator(this, FindClosest(key
, greater
, orEqual
));
601 IteratableSplayTree
& operator=(const IteratableSplayTree
& other
)
604 fFirst
= other
.fFirst
;
609 friend class Iterator
;
610 friend class ConstIterator
;
611 // needed for gcc 2.95.3 only
613 SplayTree
<Definition
> fTree
;
618 #endif // KERNEL_UTIL_SPLAY_TREE_H