00001
00024 #ifndef _SPLAYTREE
00025 #define _SPLAYTREE
00026
00027 template <class comparable>
00028 class splaytree_iterator;
00029
00033 template <class comparable>
00034 struct node {
00036
00037 node<comparable> *left;
00038 node<comparable> *right;
00039 node<comparable> *parent;
00040 comparable element;
00042 };
00043
00047 template <class comparable>
00048 class splaytree {
00049 public:
00051
00052 typedef splaytree_iterator<comparable> iterator;
00053 typedef splaytree_iterator<comparable> const_iterator;
00054 typedef size_t size_type;
00055
00056 explicit splaytree(const comparable ¬Found);
00057 splaytree(const splaytree &rhs);
00058 virtual ~splaytree() { clear(); delete Null; }
00059
00060 const comparable &findMin();
00061 const comparable &findMax();
00062 const comparable &find(const comparable &x);
00063
00064 bool empty() const { return root == Null; }
00065 size_type size() const { return count; }
00066
00067 void print() const { plog("\ndump tree %x:\n", this); print(root); }
00068
00069 void clear() { clear(root); root = Null; }
00070 void insert(const comparable &x);
00071 void remove(const comparable &x);
00072 void erase(iterator iter) { for (;iter != enditer; iter++) { remove(*iter); } }
00073 void sort();
00074
00075 void push_back(const comparable &x) { insert(x); }
00076
00077 iterator begin() { return iterator(root, Null); }
00078 iterator end() { return enditer; }
00079
00080 const_iterator begin() const { return iterator(root, Null); }
00081 const_iterator end() const { return enditer; }
00082
00083
00085
00086 private:
00088
00089 const comparable ITEM_NOT_FOUND;
00090 iterator enditer;
00091 size_type count;
00092
00093 node<comparable> *root;
00094 node<comparable> *Null;
00095
00096 void rotateLeft(node<comparable> *&k2) const;
00097 void rotateRight(node<comparable> *&k1) const;
00098 void splay(const comparable &x, node<comparable> *&t) const;
00099
00100 void clear(node<comparable> *n)
00101 {
00102 if (n != Null) {
00103 clear(n->left);
00104 clear(n->right);
00105 delete n;
00106 }
00107 }
00108
00109 void print(node<comparable> *n) const
00110 {
00111 if (n == Null) return;
00112 print(n->left);
00113 plog("%x: {", n);
00114 if (n->parent == Null) { plog("Null"); } else { plog("%x", n->parent); }
00115 plog(", ");
00116 if (n->left == Null) { plog("Null"); } else { plog("%x", n->left); }
00117 plog(", ");
00118 if (n->right == Null) { plog("Null"); } else { plog("%x", n->right); }
00119 plog("}\n");
00120 print(n->right);
00121 }
00123 };
00124
00128 template <class comparable>
00129 class splaytree_iterator {
00130 public:
00132
00133 splaytree_iterator() {}
00134 splaytree_iterator(const node<comparable> *root, const node<comparable> *n)
00135 {
00136 iterations = 0;
00137 current = (node<comparable> *) root;
00138 Null = (node<comparable> *) n;
00139
00140 while (current->left != Null) {
00141 current = current->left;
00142 }
00143 }
00144
00145 bool operator !=(const splaytree_iterator<comparable> iter) { return current != iter.current; }
00146 comparable operator *() { return current->element; }
00147 splaytree_iterator<comparable> *operator ++(int) { return ++*this; }
00148 splaytree_iterator<comparable> *operator ++()
00149 {
00150 if (current->right == Null) {
00151 node<comparable> *old;
00152 do {
00153 old = current;
00154 current = current->parent;
00155 } while ((current != Null) && (current->right == old));
00156 } else {
00157 current = current->right;
00158 while (current->left != Null) {
00159 current = current->left;
00160 }
00161 }
00162
00163 iterations++;
00164 return this;
00165 }
00166
00167
00169
00170 private:
00172
00173 long iterations;
00174 node<comparable> *current;
00175 node<comparable> *Null;
00177 };
00178
00179 template<class comparable>
00180 splaytree<comparable>::splaytree(const comparable ¬Found) : ITEM_NOT_FOUND(notFound)
00181 {
00182 Null = new node<comparable>;
00183 Null->left = Null->right = Null->parent = Null;
00184 Null->element = notFound;
00185 root = Null;
00186
00187 enditer = iterator(Null, Null);
00188 count = 0;
00189 }
00190
00191 template<class comparable>
00192 void splaytree<comparable>::splay(const comparable &x, node<comparable> *&t) const
00193 {
00194 static node<comparable> header;
00195 node<comparable> *leftTreeMax, *rightTreeMin;
00196
00197 header.left = header.right = header.parent = Null;
00198 leftTreeMax = rightTreeMin = &header;
00199
00200 Null->element = x;
00201
00202 while (true) {
00203 if (x < t->element) {
00204 if (x < t->left->element) {
00205 rotateLeft(t);
00206 }
00207 if (t->left == Null) {
00208 break;
00209 }
00210
00211 rightTreeMin->left = t;
00212 rightTreeMin = t;
00213 t = t->left;
00214 } else {
00215 if (t->right->element < x) {
00216 rotateRight(t);
00217 }
00218 if (t->right == Null) {
00219 break;
00220 }
00221
00222 leftTreeMax->right = t;
00223 leftTreeMax = t;
00224 t = t->right;
00225 }
00226 }
00227
00228 leftTreeMax->right = t->left;
00229 rightTreeMin->left = t->right;
00230
00231 t->parent = header.parent;
00232
00233 t->left = header.right;
00234 t->left->parent = t;
00235
00236 t->right = header.left;
00237 t->right->parent = t;
00238 }
00239
00240 template <class comparable>
00241 void splaytree<comparable>::insert(const comparable &x)
00242 {
00243 node<comparable> *newNode = new node<comparable>;
00244 newNode->element = x;
00245
00246 if (root == Null) {
00247 newNode->left = newNode->right = newNode->parent = Null;
00248 root = newNode;
00249 } else {
00250 splay(x, root);
00251
00252 newNode->parent = root->parent;
00253 if (x < root->element) {
00254 newNode->left = root->left;
00255 root->left->parent = newNode;
00256
00257 newNode->right = root;
00258 newNode->right->parent = newNode;
00259
00260 root->left = Null;
00261 root = newNode;
00262 } else {
00263 newNode->right = root->right;
00264 newNode->right->parent = newNode;
00265
00266 newNode->left = root;
00267 newNode->left->parent = newNode;
00268
00269 root->right = Null;
00270 root = newNode;
00271 }
00272 }
00273
00274 count++;
00275 }
00276
00277 template <class comparable>
00278 void splaytree<comparable>::remove(const comparable &x)
00279 {
00280 node<comparable> *newTree;
00281
00282 splay(x, root);
00283 if (root->element != x) {
00284 return;
00285 }
00286
00287 if (root->left == Null) {
00288 newTree = root->right;
00289 } else {
00290 newTree = root->left;
00291 splay(x, newTree);
00292 newTree->right = root->right;
00293 newTree->right->parent = newTree;
00294 }
00295
00296 delete root;
00297
00298 root = newTree;
00299 root->parent = Null;
00300
00301 count--;
00302 }
00303
00304 template <class comparable>
00305 void splaytree<comparable>::sort()
00306 {
00308 #if 0
00309 node<comparable> *old = root;
00310 iterator iter = begin();
00311
00312 root = Null;
00313 count = 0;
00314
00315 while (iter != end()) {
00316 insert(*iter);
00317 iter++;
00318 }
00319
00320 splay(old->element, root);
00321 clear(old);
00322 #endif
00323 }
00324
00325 template <class comparable>
00326 const comparable &splaytree<comparable>::find(const comparable &x)
00327 {
00328 splay(x, root);
00329 if ((x < root->element) || (root->element < x)) {
00330 return ITEM_NOT_FOUND;
00331 } else {
00332 return root->element;
00333 }
00334 }
00335
00336 template <class comparable>
00337 const comparable &splaytree<comparable>::findMax()
00338 {
00339 node<comparable> *max = root;
00340
00341 while (max->right != Null) {
00342 max = max->right;
00343 }
00344
00345 return find(max->element);
00346 }
00347
00348 template <class comparable>
00349 const comparable &splaytree<comparable>::findMin()
00350 {
00351 node<comparable> *min = root;
00352
00353 while (min->left != Null) {
00354 min = min->left;
00355 }
00356
00357 return find(min->element);
00358 }
00359
00360 template <class comparable>
00361 void splaytree<comparable>::rotateLeft(node<comparable> *&k2) const
00362 {
00363 node<comparable> *k1 = k2->left;
00364 k1->parent = k2->parent;
00365
00366 k2->left = k1->right;
00367 k2->left->parent = k2;
00368
00369 k1->right = k2;
00370 k1->right->parent = k1;
00371
00372 k2 = k1;
00373 }
00374
00375 template <class comparable>
00376 void splaytree<comparable>::rotateRight(node<comparable> *&k1) const
00377 {
00378 node<comparable> *k2 = k1->right;
00379 k2->parent = k1->parent;
00380
00381 k1->right = k2->left;
00382 k1->right->parent = k1;
00383
00384 k2->left = k1;
00385 k2->left->parent = k2;
00386
00387 k1 = k2;
00388 }
00389
00390 #endif