00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 # ifndef TPL_SPLAY_TREE_H
00045 # define TPL_SPLAY_TREE_H
00046
00047 # include <tpl_binNode.H>
00048 # include <tpl_binNodeUtils.H>
00049 # include <tpl_arrayStack.H>
00050
00051 using namespace Aleph;
00052
00053 namespace Aleph {
00054
00075 template <template <typename> class NodeType, typename Key, class Compare>
00076 class Gen_Splay_Tree
00077 {
00078
00079 public:
00080
00081 typedef NodeType<Key> Node;
00082
00083 private:
00084
00085 Gen_Splay_Tree(const Gen_Splay_Tree&);
00086
00087 Gen_Splay_Tree& operator = (const Gen_Splay_Tree&);
00088
00089 static Node * zig_zig_right(Node* p)
00090 {
00091 Node * q = LLINK(p);
00092 Node * r = LLINK(q);
00093 LLINK(p) = RLINK(q);
00094 LLINK(q) = RLINK(r);
00095 RLINK(q) = p;
00096 RLINK(r) = q;
00097
00098 return r;
00099 }
00100
00101 static Node * zig_zig_left(Node* p)
00102 {
00103 Node * q = RLINK(p);
00104 Node * r = RLINK(q);
00105 RLINK(p) = LLINK(q);
00106 RLINK(q) = LLINK(r);
00107 LLINK(q) = p;
00108 LLINK(r) = q;
00109
00110 return r;
00111 }
00112
00113 static Node * zig_zag_right(Node* p)
00114 {
00115 LLINK(p) = rotate_to_left(LLINK(p));
00116 return rotate_to_right(p);
00117 }
00118
00119 static Node * zig_zag_left(Node* p)
00120 {
00121 RLINK(p) = rotate_to_right(RLINK(p));
00122 return rotate_to_left(p);
00123 }
00124
00125
00126 struct Node_Desc
00127 {
00128 Node * node;
00129 Node ** node_parent;
00130
00131 Node_Desc() { }
00132
00133 Node_Desc(Node * p, Node ** pp) : node(p), node_parent(pp) { }
00134
00135 };
00136 ArrayStack<Node_Desc, Node::MaxHeight> splay_stack;
00137 void push_in_splay_stack(Node * p, Node ** pp)
00138 {
00139 try
00140 {
00141 splay_stack.push(Node_Desc(p, pp));
00142 }
00143 catch (std::overflow_error)
00144 {
00145 splay_stack.empty();
00146 throw;
00147 }
00148 }
00149 void search_and_push_in_splay_stack(const Key & key)
00150 {
00151 splay_stack.empty();
00152
00153 Node ** pp = &RLINK(head);
00154 Node * p = root;
00155
00156 while (p != NULL)
00157 {
00158 push_in_splay_stack(p, pp);
00159
00160 if (Compare()(key, KEY(p)))
00161 {
00162 pp = &LLINK(p);
00163 p = LLINK(p);
00164 }
00165 else if (Compare()(KEY(p), key))
00166 {
00167 pp = &RLINK(p);
00168 p = RLINK(p);
00169 }
00170 else
00171 return;
00172 }
00173 }
00174 Node head_node;
00175 Node *head;
00176 Node *&root;
00177 enum Zig_Type { ZIG_LEFT, ZIG_RIGHT, ZIG_ZAG_LEFT, ZIG_ZAG_RIGHT,
00178 ZIG_ZIG_LEFT, ZIG_ZIG_RIGHT };
00179
00180 Zig_Type zig_type(Node *& p, Node **& pp)
00181 {
00182
00183 I(splay_stack.size() >= 2);
00184
00185 Node_Desc first = splay_stack.pop();
00186 Node_Desc second = splay_stack.pop();
00187
00188 Zig_Type ret_val =
00189 Compare()(KEY(second.node), KEY(first.node)) ? ZIG_LEFT : ZIG_RIGHT;
00190
00191 if (splay_stack.is_empty())
00192 {
00193 p = second.node;
00194 pp = second.node_parent;
00195
00196 return ret_val;
00197 }
00198
00199 Node_Desc third = splay_stack.pop();
00200
00201 pp = third.node_parent;
00202 p = third.node;
00203
00204 if (ret_val == ZIG_LEFT)
00205 return Compare()(KEY(third.node), KEY(second.node))
00206 ? ZIG_ZIG_LEFT : ZIG_ZAG_RIGHT;
00207
00208 return Compare()(KEY(second.node), KEY(third.node))
00209 ? ZIG_ZIG_RIGHT : ZIG_ZAG_LEFT;
00210 }
00211 void splay()
00212 {
00213 if (splay_stack.is_empty() or splay_stack.top().node == root)
00214 return;
00215
00216 Node **pp, *p;
00217 while (true)
00218 {
00219 switch (zig_type(p, pp))
00220 {
00221 case ZIG_LEFT: *pp = rotate_to_left(p); break;
00222 case ZIG_RIGHT: *pp = rotate_to_right(p); break;
00223 case ZIG_ZIG_LEFT: *pp = zig_zig_left(p); break;
00224 case ZIG_ZIG_RIGHT: *pp = zig_zig_right(p); break;
00225 case ZIG_ZAG_LEFT: *pp = zig_zag_left(p); break;
00226 case ZIG_ZAG_RIGHT: *pp = zig_zag_right(p); break;
00227
00228 default: ERROR("Invalid rotation type");
00229
00230 }
00231
00232 if (splay_stack.is_empty())
00233 break;
00234
00235 push_in_splay_stack(p, pp);
00236 }
00237 }
00238
00239 public:
00240
00241 virtual ~Gen_Splay_Tree() { }
00242
00244 Node*& getRoot() const { return root; }
00245
00246 Gen_Splay_Tree() : head(&head_node), root(RLINK(head)) { }
00250 Node * search(const Key & key)
00251 {
00252 if (root == NULL)
00253 return NULL;
00254
00255 search_and_push_in_splay_stack(key);
00256
00257 splay();
00258
00259 if (are_equals<Key, Compare>(key, KEY(root)))
00260 return root;
00261
00262 return NULL;
00263 }
00268 Node * insert(Node * p)
00269 {
00270 if (root == NULL)
00271 {
00272 root = p;
00273 return root;
00274 }
00275
00276 search_and_push_in_splay_stack(KEY(p));
00277
00278 Node * pp = splay_stack.top().node;
00279
00280
00281 if (Compare()(KEY(p), KEY(pp)))
00282 {
00283 LLINK(pp) = p;
00284 push_in_splay_stack(p, &LLINK(pp));
00285 }
00286 else if (Compare()(KEY(pp), KEY(p)))
00287 {
00288 RLINK(pp) = p;
00289 push_in_splay_stack(p, &RLINK(pp));
00290 }
00291 else
00292 {
00293 splay();
00294
00295 return NULL;
00296 }
00297
00298 splay();
00299
00300 return root;
00301 }
00305 Node * remove(const Key & key)
00306 {
00307 search_and_push_in_splay_stack(key);
00308
00309 splay();
00310
00311 if (no_equals<Key, Compare>(KEY(root), key))
00312 return NULL;
00313
00314 Node * p = root;
00315 root = join_exclusive(LLINK(root), RLINK(root));
00316 p->reset();
00317
00318 return p;
00319 }
00320 };
00321
00335 template <typename Key, class Compare = Aleph::less<Key> >
00336 struct Splay_Tree : public Gen_Splay_Tree<BinNode, Key, Compare>
00337 { };
00338
00352 template <typename Key, class Compare = Aleph::less<Key> >
00353 struct Splay_Tree_Vtl : public Gen_Splay_Tree<BinNodeVtl, Key, Compare>
00354 { };
00355
00356
00357 }
00358 # endif
00359