splaytree.h

Go to the documentation of this file.
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 &notFound);
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 //              const splaytree &operator=(const splaytree &rhs);
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 //              void operator --();
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 &notFound) : 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

Generated on Mon Jun 5 10:20:48 2006 for Intelligence.kdevelop by  doxygen 1.4.6