00001
00002
00003
00004
00005
00006
00007
00008
00014 #ifndef _FM_TREE_H_
00015 #define _FM_TREE_H_
00016
00017 #ifndef _FM_ALLOCATOR_H_
00018 #include "FMath/FMAllocator.h"
00019 #endif // _FM_ALLOCATOR_H_
00020
00021 namespace fm
00022 {
00027 template <class _Kty, class _Ty>
00028 class pair
00029 {
00030 public:
00031 _Kty first;
00032 _Ty second;
00035 pair() : first(), second() {}
00036
00040 pair(const _Kty& f, const _Ty& s) : first(f), second(s) {}
00041
00044 pair(const pair& p) : first(p.first), second(p.second) {}
00045
00049 inline bool operator==(const pair& p) const { return p.first == first && p.second == second; }
00050
00054 inline bool operator!=(const pair& p) const { return p.first != first || p.second != second; }
00055 };
00056
00064 template <class KEY, class DATA>
00065 class tree
00066 {
00067 private:
00068 typedef fm::pair<KEY, DATA> pair;
00069
00070 class node
00071 {
00072 public:
00073 node* left;
00074 node* right;
00075 node* parent;
00076
00077 int32 weight;
00078
00079 pair data;
00080
00081 public:
00082 node() : left(NULL), right(NULL), parent(NULL), weight(0) {}
00083
00084 void rotateLeft()
00085 {
00086 node** parentLink = (parent->left == this) ? &parent->left : &parent->right;
00087
00088
00089 node* oldRight = right;
00090
00091
00092 node* right_left = right->left;
00093 right = right_left;
00094 if (right_left != NULL) right_left->parent = this;
00095
00096
00097 oldRight->left = this;
00098
00099
00100 oldRight->parent = parent;
00101 parent = oldRight;
00102 (*parentLink) = oldRight;
00103
00104
00105 weight = weight - 1 - (oldRight->weight > 0 ? oldRight->weight : 0);
00106 oldRight->weight = oldRight->weight - (0 > -weight ? 0 : -weight) - 1;
00107 }
00108
00109 void rotateRight()
00110 {
00111 node** parentLink = (parent->left == this) ? &parent->left : &parent->right;
00112
00113
00114 node* oldLeft = left;
00115
00116
00117 node* left_right = left->right;
00118 left = left_right;
00119 if (left_right != NULL) left_right->parent = this;
00120
00121
00122 oldLeft->right = this;
00123
00124
00125 oldLeft->parent = parent;
00126 parent = oldLeft;
00127 (*parentLink) = oldLeft;
00128
00129
00130 weight = weight + 1 + (0 > oldLeft->weight ? -oldLeft->weight : 0);
00131 oldLeft->weight = (oldLeft->weight + 1) + (0 > weight ? 0 : weight);
00132 }
00133
00134 #ifdef TREE_DEBUG
00135 intptr_t depth() const
00136 {
00137 intptr_t leftDepth = left != NULL ? left->depth() : 0;
00138 intptr_t rightDepth = right != NULL ? right->depth() : 0;
00139 return max(leftDepth, rightDepth) + 1;
00140 }
00141
00142 void is_correct()
00143 {
00144 if (left != NULL) left->is_correct();
00145 if (right != NULL) right->is_correct();
00146 intptr_t leftDepth = left != NULL ? left->depth() : 0;
00147 intptr_t rightDepth = right != NULL ? right->depth() : 0;
00148 FUAssert(rightDepth - leftDepth == weight,);
00149 FUAssert(abs(weight) < 2,);
00150 }
00151 #endif // TREE_DEBUG
00152 };
00153
00154 public:
00155 class const_iterator;
00156
00161 class iterator
00162 {
00163 private:
00164 friend class tree;
00165 friend class const_iterator;
00166 node* currentNode;
00167
00168 public:
00170 iterator() {}
00172 iterator(node* n) : currentNode(n) {}
00174 iterator& operator=(const iterator& copy) { currentNode = copy.currentNode; return *this; }
00175
00179 inline bool operator==(const iterator& other) const { return other.currentNode == currentNode; }
00180 inline bool operator==(const const_iterator& other) const;
00185 inline bool operator!=(const iterator& other) const { return other.currentNode != currentNode; }
00186 inline bool operator!=(const const_iterator& other) const;
00190 iterator& operator++()
00191 {
00192
00193 if (currentNode->right == NULL)
00194 {
00195 node* oldNode;
00196 do
00197 {
00198 oldNode = currentNode;
00199
00200
00201
00202
00203 currentNode = currentNode->parent;
00204 }
00205 while (currentNode->right == oldNode && currentNode->parent != NULL);
00206 }
00207 else
00208 {
00209
00210 currentNode = currentNode->right;
00211
00212
00213 while (currentNode->left != NULL) currentNode = currentNode->left;
00214 }
00215 return (*this);
00216 }
00217
00220 iterator& operator--()
00221 {
00222
00223 if (currentNode->left == NULL)
00224 {
00225 node* oldNode;
00226 do
00227 {
00228 oldNode = currentNode;
00229
00230
00231
00232
00233 currentNode = currentNode->parent;
00234 }
00235 while (currentNode->left == oldNode && currentNode->parent != NULL);
00236 }
00237 else
00238 {
00239
00240 currentNode = currentNode->left;
00241
00242
00243 while (currentNode->right != NULL) currentNode = currentNode->right;
00244 }
00245 return (*this);
00246 }
00247
00250 inline pair& operator*() { return currentNode->data; }
00251 inline pair* operator->() { return ¤tNode->data; }
00252 };
00253
00258 class const_iterator
00259 {
00260 private:
00261 friend class tree;
00262 friend class iterator;
00263 const node* currentNode;
00264
00265 public:
00267 const_iterator() {}
00270 const_iterator(const iterator& copy) : currentNode(copy.currentNode) {}
00272 const_iterator(const node* n) : currentNode(n) {}
00274 const_iterator& operator=(const iterator& copy) { currentNode = copy.currentNode; return *this; }
00275 const_iterator& operator=(const const_iterator& copy) { currentNode = copy.currentNode; return *this; }
00280 inline bool operator==(const iterator& other) const { return other.currentNode == currentNode; }
00281 inline bool operator==(const const_iterator& other) const { return other.currentNode == currentNode; }
00286 inline bool operator!=(const iterator& other) const { return other.currentNode != currentNode; }
00287 inline bool operator!=(const const_iterator& other) const { return other.currentNode != currentNode; }
00291 const_iterator& operator++()
00292 {
00293
00294 if (currentNode->right == NULL)
00295 {
00296 const node* oldNode;
00297 do
00298 {
00299 oldNode = currentNode;
00300
00301
00302
00303
00304 currentNode = currentNode->parent;
00305 }
00306 while (currentNode->right == oldNode && currentNode->parent != NULL);
00307 }
00308 else
00309 {
00310
00311 currentNode = currentNode->right;
00312
00313
00314 while (currentNode->left != NULL) currentNode = currentNode->left;
00315 }
00316 return (*this);
00317 }
00318
00321 const_iterator& operator--()
00322 {
00323
00324 if (currentNode->left == NULL)
00325 {
00326 const node* oldNode;
00327 do
00328 {
00329 oldNode = currentNode;
00330
00331
00332
00333
00334 currentNode = currentNode->parent;
00335 }
00336 while (currentNode->left == oldNode && currentNode->parent != NULL);
00337 }
00338 else
00339 {
00340
00341 currentNode = currentNode->left;
00342
00343
00344 while (currentNode->right != NULL) currentNode = currentNode->right;
00345 }
00346 return (*this);
00347 }
00348
00351 inline const pair& operator*() { return currentNode->data; }
00352 inline const pair* operator->() { return ¤tNode->data; }
00353 };
00354
00355 private:
00356 node* root;
00357 size_t sized;
00358
00359 public:
00361 tree() : root(NULL), sized(0)
00362 {
00363 root = (node*) fm::Allocate(sizeof(node));
00364 fm::Construct(root);
00365 }
00366
00368 ~tree()
00369 {
00370 clear();
00371 root->data.first.~KEY();
00372 root->data.second.~DATA();
00373 fm::Release(root);
00374 root = NULL;
00375 }
00376
00379 inline iterator begin() { iterator it(root); return (root->right == NULL) ? it : ++it; }
00380 inline const_iterator begin() const { const_iterator it(root); return (root->right == NULL) ? it : ++it; }
00385 inline iterator end() { return iterator(root); }
00386 inline const_iterator end() const { return const_iterator(root); }
00390 inline iterator last() { node* n = root; while (n->right != NULL) n = n->right; return iterator(n); }
00391 inline const_iterator last() const { const node* n = root; while (n->right != NULL) n = n->right; return const_iterator(n); }
00399 iterator find(const KEY& key)
00400 {
00401 node* out = root->right;
00402 while (out != NULL)
00403 {
00404 if (key < out->data.first) out = out->left;
00405 else if (key == out->data.first) return iterator(out);
00406 else out = out->right;
00407 }
00408 return end();
00409 }
00410 inline const_iterator find(const KEY& key) const { return const_iterator(const_cast<tree<KEY, DATA>* >(this)->find(key)); }
00418 iterator insert(const KEY& key, const DATA& data)
00419 {
00420
00421 node** insertAt = &root->right,* parent = root;
00422 while (*insertAt != NULL)
00423 {
00424 parent = *insertAt;
00425 if (key < parent->data.first) insertAt = &parent->left;
00426 else if (key == parent->data.first)
00427 {
00428 parent->data.second = data;
00429 return iterator(parent);
00430 }
00431 else insertAt = &parent->right;
00432 }
00433
00434
00435 node* n = ((*insertAt) = (node*) fm::Allocate(sizeof(node)));
00436 fm::Construct(*insertAt);
00437 n->parent = parent;
00438 n->data.first = key;
00439 n->data.second = data;
00440 ++sized;
00441
00442
00443 parent->weight += (*insertAt == parent->right) ? 1 : -1;
00444 node* it = parent;
00445 while (it != root)
00446 {
00447
00448 if (it->weight > 1)
00449 {
00450 if (it->right->weight < 0) it->right->rotateRight();
00451 it->rotateLeft();
00452 it = it->parent;
00453 break;
00454 }
00455 else if (it->weight < -1)
00456 {
00457 if (it->left->weight > 0) it->left->rotateLeft();
00458 it->rotateRight();
00459 it = it->parent;
00460 break;
00461 }
00462 else if (it->weight == 0) break;
00463
00464
00465 it->parent->weight += (it == it->parent->right) ? 1 : -1;
00466 it = it->parent;
00467 }
00468
00469 #ifdef TREE_DEBUG
00470 root->right->is_correct();
00471 #endif // TREE_DEBUG
00472
00473 return iterator(n);
00474 }
00475
00481 inline DATA& operator[](const KEY& k) { iterator it = find(k); if (it != end()) return it->second; else { DATA d; return insert(k, d)->second; } }
00482 inline const DATA& operator[](const KEY& k) const { return find(k)->second; }
00486 inline void erase(const KEY& key) { iterator it = find(key); erase(it); }
00487
00490 inline void erase(const iterator& it)
00491 {
00492 node* n = it.currentNode;
00493 if (n != root)
00494 {
00495 node* release;
00496 if (n->left == NULL && n->right == NULL) release = n;
00497 else
00498 {
00499
00500 if (n->weight <= 0 && n->left != NULL)
00501 {
00502
00503 release = n->left;
00504 while (release->right != NULL) release = release->right;
00505 n->data = release->data;
00506
00507
00508 if (release->left != NULL)
00509 {
00510 release->data = release->left->data;
00511 release = release->left;
00512 }
00513 }
00514 else
00515 {
00516
00517 release = n->right;
00518 while (release->left != NULL) release = release->left;
00519 n->data = release->data;
00520
00521
00522 if (release->right != NULL)
00523 {
00524 release->data = release->right->data;
00525 release = release->right;
00526 }
00527 }
00528 }
00529
00530
00531 node* rebalance = release->parent;
00532 if (rebalance->left == release) { rebalance->left = NULL; ++rebalance->weight; }
00533 else { rebalance->right = NULL; --rebalance->weight; }
00534 release->data.first.~KEY();
00535 release->data.second.~DATA();
00536 fm::Release(release);
00537 --sized;
00538
00539
00540 node* it = rebalance;
00541 while (it != root)
00542 {
00543
00544 if (it->weight > 1)
00545 {
00546 if (it->right->weight < 0) it->right->rotateRight();
00547 it->rotateLeft();
00548 it = it->parent;
00549 }
00550 else if (it->weight < -1)
00551 {
00552 if (it->left->weight > 0) it->left->rotateLeft();
00553 it->rotateRight();
00554 it = it->parent;
00555 }
00556 if (it->weight != 0) break;
00557
00558
00559 it->parent->weight -= (it == it->parent->right) ? 1 : -1;
00560 it = it->parent;
00561 }
00562 }
00563
00564 #ifdef TREE_DEBUG
00565 if (root->right != NULL) root->right->is_correct();
00566 #endif // TREE_DEBUG
00567 }
00568
00571 inline bool empty() const { return sized == 0; }
00572
00575 inline size_t size() const { return sized; }
00576
00579 void clear()
00580 {
00581
00582 if (root->right != NULL)
00583 {
00584 node* n = root->right;
00585 while (n != root)
00586 {
00587 if (n->left != NULL) n = n->left;
00588 else if (n->right != NULL) n = n->right;
00589 else
00590 {
00591
00592 node* release = n;
00593 n = n->parent;
00594 if (n->left == release) n->left = NULL;
00595 else if (n->right == release) n->right = NULL;
00596 release->data.first.~KEY();
00597 release->data.second.~DATA();
00598 fm::Release(release);
00599 --sized;
00600 }
00601 }
00602 root->right = NULL;
00603 }
00604 }
00605
00610 inline tree<KEY,DATA>& operator= (const tree<KEY,DATA>& copy)
00611 {
00612 clear();
00613
00614
00615
00616 node* currentNode = copy.root;
00617 node* cloneNode = root;
00618 if (currentNode->right != NULL)
00619 {
00620 do
00621 {
00622 if (currentNode->right == NULL)
00623 {
00624 const node* oldNode;
00625 do
00626 {
00627 oldNode = currentNode;
00628
00629
00630
00631
00632 currentNode = currentNode->parent;
00633 cloneNode = cloneNode->parent;
00634 }
00635 while (currentNode->right == oldNode && currentNode->parent != NULL);
00636 }
00637 else
00638 {
00639
00640 currentNode = currentNode->right;
00641
00642 cloneNode->right = (node*) fm::Allocate(sizeof(node));
00643 fm::Construct(cloneNode->right);
00644 cloneNode->right->parent = cloneNode;
00645 cloneNode->right->data = currentNode->data;
00646 cloneNode->right->weight = currentNode->weight;
00647 ++sized;
00648
00649 cloneNode = cloneNode->right;
00650
00651
00652 while (currentNode->left != NULL)
00653 {
00654 currentNode = currentNode->left;
00655
00656 cloneNode->left = (node*) fm::Allocate(sizeof(node));
00657 fm::Construct(cloneNode->left);
00658 cloneNode->left->parent = cloneNode;
00659 cloneNode->left->data = currentNode->data;
00660 cloneNode->left->weight = currentNode->weight;
00661 ++sized;
00662
00663 cloneNode = cloneNode->left;
00664 }
00665 }
00666 }
00667 while (currentNode != copy.root);
00668 }
00669
00670 return (*this);
00671 }
00672 };
00673
00674 template <class KEY, class DATA>
00675 bool tree<KEY,DATA>::iterator::operator==(const const_iterator& other) const { return other.currentNode == currentNode; }
00676 template <class KEY, class DATA>
00677 bool tree<KEY,DATA>::iterator::operator!=(const const_iterator& other) const { return other.currentNode != currentNode; }
00678
00680 template <class _Kty>
00681 class set : public fm::tree<_Kty, _Kty> {};
00682
00684 template <class _Kty, class _Ty>
00685 class map : public fm::tree<_Kty, _Ty> {};
00686 };
00687
00688 #endif // _FM_TREE_H_
00689
00690