1 // Copyright (C) 2006-2012 by Kat'Oun
\r
2 // This file is part of the "Irrlicht Engine".
\r
3 // For conditions of distribution and use, see copyright notice in irrlicht.h
\r
5 #ifndef __IRR_MAP_H_INCLUDED__
\r
6 #define __IRR_MAP_H_INCLUDED__
\r
8 #include "irrTypes.h"
\r
16 //! map template for associative arrays using a red-black tree
\r
17 template <class KeyType, class ValueType>
\r
20 //! red/black tree for map
\r
21 template <class KeyTypeRB, class ValueTypeRB>
\r
26 RBTree(const KeyTypeRB& k, const ValueTypeRB& v)
\r
27 : LeftChild(0), RightChild(0), Parent(0), Key(k),
\r
28 Value(v), IsRed(true) {}
\r
30 void setLeftChild(RBTree* p)
\r
37 void setRightChild(RBTree* p)
\r
44 void setParent(RBTree* p) { Parent=p; }
\r
46 void setValue(const ValueTypeRB& v) { Value = v; }
\r
48 void setRed() { IsRed = true; }
\r
49 void setBlack() { IsRed = false; }
\r
51 RBTree* getLeftChild() const { return LeftChild; }
\r
52 RBTree* getRightChild() const { return RightChild; }
\r
53 RBTree* getParent() const { return Parent; }
\r
55 const ValueTypeRB& getValue() const
\r
60 ValueTypeRB& getValue()
\r
65 const KeyTypeRB& getKey() const
\r
75 bool isLeftChild() const
\r
77 return (Parent != 0) && (Parent->getLeftChild()==this);
\r
80 bool isRightChild() const
\r
82 return (Parent!=0) && (Parent->getRightChild()==this);
\r
87 return (LeftChild==0) && (RightChild==0);
\r
90 unsigned int getLevel() const
\r
95 return getParent()->getLevel() + 1;
\r
104 bool isBlack() const
\r
113 RBTree* RightChild;
\r
125 typedef RBTree<KeyType,ValueType> Node;
\r
126 // We need the forward declaration for the friend declaration
\r
127 class ConstIterator;
\r
129 //! Normal Iterator
\r
132 friend class ConstIterator;
\r
135 Iterator() : Root(0), Cur(0) {}
\r
137 // Constructor(Node*)
\r
138 Iterator(Node* root) : Root(root)
\r
143 void reset(bool atLowest=true)
\r
146 Cur = getMin(Root);
\r
148 Cur = getMax(Root);
\r
156 Node* getNode() const
\r
161 void operator++(int)
\r
166 void operator--(int)
\r
178 _IRR_DEBUG_BREAK_IF(atEnd()) // access violation
\r
185 Node* getMin(Node* n) const
\r
187 while(n && n->getLeftChild())
\r
188 n = n->getLeftChild();
\r
192 Node* getMax(Node* n) const
\r
194 while(n && n->getRightChild())
\r
195 n = n->getRightChild();
\r
205 if (Cur->getRightChild())
\r
207 // If current node has a right child, the next higher node is the
\r
208 // node with lowest key beneath the right child.
\r
209 Cur = getMin(Cur->getRightChild());
\r
211 else if (Cur->isLeftChild())
\r
213 // No right child? Well if current node is a left child then
\r
214 // the next higher node is the parent
\r
215 Cur = Cur->getParent();
\r
219 // Current node neither is left child nor has a right child.
\r
220 // I.e. it is either right child or root
\r
221 // The next higher node is the parent of the first non-right
\r
222 // child (i.e. either a left child or the root) up in the
\r
223 // hierarchy. Root's parent is 0.
\r
224 while(Cur->isRightChild())
\r
225 Cur = Cur->getParent();
\r
226 Cur = Cur->getParent();
\r
236 if (Cur->getLeftChild())
\r
238 // If current node has a left child, the next lower node is the
\r
239 // node with highest key beneath the left child.
\r
240 Cur = getMax(Cur->getLeftChild());
\r
242 else if (Cur->isRightChild())
\r
244 // No left child? Well if current node is a right child then
\r
245 // the next lower node is the parent
\r
246 Cur = Cur->getParent();
\r
250 // Current node neither is right child nor has a left child.
\r
251 // It is either left child or root
\r
252 // The next higher node is the parent of the first non-left
\r
253 // child (i.e. either a right child or the root) up in the
\r
254 // hierarchy. Root's parent is 0.
\r
256 while(Cur->isLeftChild())
\r
257 Cur = Cur->getParent();
\r
258 Cur = Cur->getParent();
\r
267 class ConstIterator
\r
269 friend class Iterator;
\r
272 ConstIterator() : Root(0), Cur(0) {}
\r
274 // Constructor(Node*)
\r
275 ConstIterator(const Node* root) : Root(root)
\r
280 // Constructor(Iterator)
\r
281 ConstIterator(const Iterator& src) : Root(src.Root), Cur(src.Cur) {}
\r
283 void reset(bool atLowest=true)
\r
286 Cur = getMin(Root);
\r
288 Cur = getMax(Root);
\r
296 const Node* getNode() const
\r
301 void operator++(int)
\r
306 void operator--(int)
\r
311 const Node* operator->()
\r
316 const Node& operator*()
\r
318 _IRR_DEBUG_BREAK_IF(atEnd()) // access violation
\r
325 const Node* getMin(const Node* n) const
\r
327 while(n && n->getLeftChild())
\r
328 n = n->getLeftChild();
\r
332 const Node* getMax(const Node* n) const
\r
334 while(n && n->getRightChild())
\r
335 n = n->getRightChild();
\r
345 if (Cur->getRightChild())
\r
347 // If current node has a right child, the next higher node is the
\r
348 // node with lowest key beneath the right child.
\r
349 Cur = getMin(Cur->getRightChild());
\r
351 else if (Cur->isLeftChild())
\r
353 // No right child? Well if current node is a left child then
\r
354 // the next higher node is the parent
\r
355 Cur = Cur->getParent();
\r
359 // Current node neither is left child nor has a right child.
\r
360 // It is either right child or root
\r
361 // The next higher node is the parent of the first non-right
\r
362 // child (i.e. either a left child or the root) up in the
\r
363 // hierarchy. Root's parent is 0.
\r
364 while(Cur->isRightChild())
\r
365 Cur = Cur->getParent();
\r
366 Cur = Cur->getParent();
\r
376 if (Cur->getLeftChild())
\r
378 // If current node has a left child, the next lower node is the
\r
379 // node with highest key beneath the left child.
\r
380 Cur = getMax(Cur->getLeftChild());
\r
382 else if (Cur->isRightChild())
\r
384 // No left child? Well if current node is a right child then
\r
385 // the next lower node is the parent
\r
386 Cur = Cur->getParent();
\r
390 // Current node neither is right child nor has a left child.
\r
391 // It is either left child or root
\r
392 // The next higher node is the parent of the first non-left
\r
393 // child (i.e. either a right child or the root) up in the
\r
394 // hierarchy. Root's parent is 0.
\r
396 while(Cur->isLeftChild())
\r
397 Cur = Cur->getParent();
\r
398 Cur = Cur->getParent();
\r
404 }; // ConstIterator
\r
407 //! Parent First Iterator.
\r
408 /** Traverses the tree from top to bottom. Typical usage is
\r
409 when storing the tree structure, because when reading it
\r
410 later (and inserting elements) the tree structure will
\r
412 class ParentFirstIterator
\r
416 ParentFirstIterator() : Root(0), Cur(0) {}
\r
418 explicit ParentFirstIterator(Node* root) : Root(root), Cur(0)
\r
438 void operator++(int)
\r
443 Node* operator -> ()
\r
450 _IRR_DEBUG_BREAK_IF(atEnd()) // access violation
\r
463 // First we try down to the left
\r
464 if (Cur->getLeftChild())
\r
466 Cur = Cur->getLeftChild();
\r
468 else if (Cur->getRightChild())
\r
470 // No left child? The we go down to the right.
\r
471 Cur = Cur->getRightChild();
\r
475 // No children? Move up in the hierarchy until
\r
476 // we either reach 0 (and are finished) or
\r
477 // find a right uncle.
\r
480 // But if parent is left child and has a right "uncle" the parent
\r
481 // has already been processed but the uncle hasn't. Move to
\r
483 if (Cur->isLeftChild() && Cur->getParent()->getRightChild())
\r
485 Cur = Cur->getParent()->getRightChild();
\r
488 Cur = Cur->getParent();
\r
496 }; // ParentFirstIterator
\r
499 //! Parent Last Iterator
\r
500 /** Traverse the tree from bottom to top.
\r
501 Typical usage is when deleting all elements in the tree
\r
502 because you must delete the children before you delete
\r
504 class ParentLastIterator
\r
508 ParentLastIterator() : Root(0), Cur(0) {}
\r
510 explicit ParentLastIterator(Node* root) : Root(root), Cur(0)
\r
517 Cur = getMin(Root);
\r
530 void operator++(int)
\r
535 Node* operator -> ()
\r
542 _IRR_DEBUG_BREAK_IF(atEnd()) // access violation
\r
548 Node* getMin(Node* n)
\r
550 while(n!=0 && (n->getLeftChild()!=0 || n->getRightChild()!=0))
\r
552 if (n->getLeftChild())
\r
553 n = n->getLeftChild();
\r
555 n = n->getRightChild();
\r
566 // Note: Starting point is the node as far down to the left as possible.
\r
568 // If current node has an uncle to the right, go to the
\r
569 // node as far down to the left from the uncle as possible
\r
570 // else just go up a level to the parent.
\r
571 if (Cur->isLeftChild() && Cur->getParent()->getRightChild())
\r
573 Cur = getMin(Cur->getParent()->getRightChild());
\r
576 Cur = Cur->getParent();
\r
581 }; // ParentLastIterator
\r
584 // AccessClass is a temporary class used with the [] operator.
\r
585 // It makes it possible to have different behavior in situations like:
\r
586 // myTree["Foo"] = 32;
\r
587 // If "Foo" already exists update its value else insert a new element.
\r
588 // int i = myTree["Foo"]
\r
589 // If "Foo" exists return its value.
\r
592 // Let map be the only one who can instantiate this class.
\r
593 friend class map<KeyType, ValueType>;
\r
597 // Assignment operator. Handles the myTree["Foo"] = 32; situation
\r
598 void operator=(const ValueType& value)
\r
600 // Just use the Set method, it handles already exist/not exist situation
\r
601 Tree.set(Key,value);
\r
604 // ValueType operator
\r
605 operator ValueType()
\r
607 Node* node = Tree.find(Key);
\r
610 _IRR_DEBUG_BREAK_IF(node==0) // access violation
\r
612 return node->getValue();
\r
617 AccessClass(map& tree, const KeyType& key) : Tree(tree), Key(key) {}
\r
622 const KeyType& Key;
\r
627 map() : Root(0), Size(0) {}
\r
636 typedef KeyType key_type;
\r
637 typedef ValueType value_type;
\r
638 typedef u32 size_type;
\r
640 //------------------------------
\r
642 //------------------------------
\r
644 //! Inserts a new node into the tree
\r
645 /** \param keyNew: the index for this value
\r
646 \param v: the value to insert
\r
647 \return True if successful, false if it fails (already exists) */
\r
648 bool insert(const KeyType& keyNew, const ValueType& v)
\r
650 // First insert node the "usual" way (no fancy balance logic yet)
\r
651 Node* newNode = new Node(keyNew,v);
\r
652 if (!insert(newNode))
\r
658 // Then attend a balancing party
\r
659 while (!newNode->isRoot() && (newNode->getParent()->isRed()))
\r
661 if (newNode->getParent()->isLeftChild())
\r
663 // If newNode is a left child, get its right 'uncle'
\r
664 Node* newNodesUncle = newNode->getParent()->getParent()->getRightChild();
\r
665 if ( newNodesUncle!=0 && newNodesUncle->isRed())
\r
667 // case 1 - change the colors
\r
668 newNode->getParent()->setBlack();
\r
669 newNodesUncle->setBlack();
\r
670 newNode->getParent()->getParent()->setRed();
\r
671 // Move newNode up the tree
\r
672 newNode = newNode->getParent()->getParent();
\r
676 // newNodesUncle is a black node
\r
677 if ( newNode->isRightChild())
\r
679 // and newNode is to the right
\r
680 // case 2 - move newNode up and rotate
\r
681 newNode = newNode->getParent();
\r
682 rotateLeft(newNode);
\r
685 newNode->getParent()->setBlack();
\r
686 newNode->getParent()->getParent()->setRed();
\r
687 rotateRight(newNode->getParent()->getParent());
\r
692 // If newNode is a right child, get its left 'uncle'
\r
693 Node* newNodesUncle = newNode->getParent()->getParent()->getLeftChild();
\r
694 if ( newNodesUncle!=0 && newNodesUncle->isRed())
\r
696 // case 1 - change the colors
\r
697 newNode->getParent()->setBlack();
\r
698 newNodesUncle->setBlack();
\r
699 newNode->getParent()->getParent()->setRed();
\r
700 // Move newNode up the tree
\r
701 newNode = newNode->getParent()->getParent();
\r
705 // newNodesUncle is a black node
\r
706 if (newNode->isLeftChild())
\r
708 // and newNode is to the left
\r
709 // case 2 - move newNode up and rotate
\r
710 newNode = newNode->getParent();
\r
711 rotateRight(newNode);
\r
714 newNode->getParent()->setBlack();
\r
715 newNode->getParent()->getParent()->setRed();
\r
716 rotateLeft(newNode->getParent()->getParent());
\r
721 // Color the root black
\r
726 //! Replaces the value if the key already exists, otherwise inserts a new element.
\r
727 /** \param k The index for this value
\r
728 \param v The new value of */
\r
729 void set(const KeyType& k, const ValueType& v)
\r
738 //! Removes a node from the tree and returns it.
\r
739 /** The returned node must be deleted by the user
\r
740 \param k the key to remove
\r
741 \return A pointer to the node, or 0 if not found */
\r
742 Node* delink(const KeyType& k)
\r
748 // Rotate p down to the left until it has no right child, will get there
\r
749 // sooner or later.
\r
750 while(p->getRightChild())
\r
752 // "Pull up my right child and let it knock me down to the left"
\r
755 // p now has no right child but might have a left child
\r
756 Node* left = p->getLeftChild();
\r
758 // Let p's parent point to p's child instead of point to p
\r
759 if (p->isLeftChild())
\r
760 p->getParent()->setLeftChild(left);
\r
762 else if (p->isRightChild())
\r
763 p->getParent()->setRightChild(left);
\r
767 // p has no parent => p is the root.
\r
768 // Let the left child be the new root.
\r
772 // p is now gone from the tree in the sense that
\r
773 // no one is pointing at it, so return it.
\r
779 //! Removes a node from the tree and deletes it.
\r
780 /** \return True if the node was found and deleted */
\r
781 bool remove(const KeyType& k)
\r
787 //! Removes a node from the tree and deletes it.
\r
788 /** \return True if the node was found and deleted */
\r
789 bool remove(Node* p)
\r
796 // Rotate p down to the left until it has no right child, will get there
\r
797 // sooner or later.
\r
798 while(p->getRightChild())
\r
800 // "Pull up my right child and let it knock me down to the left"
\r
803 // p now has no right child but might have a left child
\r
804 Node* left = p->getLeftChild();
\r
806 // Let p's parent point to p's child instead of point to p
\r
807 if (p->isLeftChild())
\r
808 p->getParent()->setLeftChild(left);
\r
810 else if (p->isRightChild())
\r
811 p->getParent()->setRightChild(left);
\r
815 // p has no parent => p is the root.
\r
816 // Let the left child be the new root.
\r
820 // p is now gone from the tree in the sense that
\r
821 // no one is pointing at it. Let's get rid of it.
\r
828 //! Clear the entire tree
\r
831 ParentLastIterator i(getParentLastIterator());
\r
835 Node* p = i.getNode();
\r
836 i++; // Increment it before it is deleted
\r
837 // else iterator will get quite confused.
\r
844 //! Is the tree empty?
\r
845 //! \return Returns true if empty, false if not
\r
851 //! \deprecated Use empty() instead. This method may be removed by Irrlicht 1.9
\r
852 _IRR_DEPRECATED_ bool isEmpty() const
\r
857 //! Search for a node with the specified key.
\r
858 //! \param keyToFind: The key to find
\r
859 //! \return Returns 0 if node couldn't be found.
\r
860 Node* find(const KeyType& keyToFind) const
\r
862 Node* pNode = Root;
\r
866 const KeyType& key=pNode->getKey();
\r
868 if (keyToFind == key)
\r
870 else if (keyToFind < key)
\r
871 pNode = pNode->getLeftChild();
\r
872 else //keyToFind > key
\r
873 pNode = pNode->getRightChild();
\r
879 //! Gets the root element.
\r
880 //! \return Returns a pointer to the root node, or
\r
881 //! 0 if the tree is empty.
\r
882 Node* getRoot() const
\r
887 //! Returns the number of nodes in the tree.
\r
893 //! Swap the content of this map container with the content of another map
\r
894 /** Afterwards this object will contain the content of the other object and the other
\r
895 object will contain the content of this object. Iterators will afterwards be valid for
\r
896 the swapped object.
\r
897 \param other Swap content with this object */
\r
898 void swap(map<KeyType, ValueType>& other)
\r
900 core::swap(Root, other.Root);
\r
901 core::swap(Size, other.Size);
\r
904 //------------------------------
\r
905 // Public Iterators
\r
906 //------------------------------
\r
908 //! Returns an iterator
\r
909 Iterator getIterator() const
\r
911 Iterator it(getRoot());
\r
915 //! Returns a Constiterator
\r
916 ConstIterator getConstIterator() const
\r
918 Iterator it(getRoot());
\r
922 //! Returns a ParentFirstIterator.
\r
923 //! Traverses the tree from top to bottom. Typical usage is
\r
924 //! when storing the tree structure, because when reading it
\r
925 //! later (and inserting elements) the tree structure will
\r
927 ParentFirstIterator getParentFirstIterator() const
\r
929 ParentFirstIterator it(getRoot());
\r
933 //! Returns a ParentLastIterator to traverse the tree from
\r
935 //! Typical usage is when deleting all elements in the tree
\r
936 //! because you must delete the children before you delete
\r
938 ParentLastIterator getParentLastIterator() const
\r
940 ParentLastIterator it(getRoot());
\r
944 //------------------------------
\r
945 // Public Operators
\r
946 //------------------------------
\r
948 //! operator [] for access to elements
\r
949 /** for example myMap["key"] */
\r
950 AccessClass operator[](const KeyType& k)
\r
952 return AccessClass(*this, k);
\r
956 //------------------------------
\r
957 // Disabled methods
\r
958 //------------------------------
\r
959 // Copy constructor and assignment operator deliberately
\r
960 // defined but not implemented. The tree should never be
\r
961 // copied, pass along references to it instead.
\r
962 explicit map(const map& src);
\r
963 map& operator = (const map& src);
\r
965 //! Set node as new root.
\r
966 /** The node will be set to black, otherwise core dumps may arise
\r
967 (patch provided by rogerborg).
\r
968 \param newRoot Node which will be the new root
\r
970 void setRoot(Node* newRoot)
\r
975 Root->setParent(0);
\r
980 //! Insert a node into the tree without using any fancy balancing logic.
\r
981 /** \return false if that key already exist in the tree. */
\r
982 bool insert(Node* newNode)
\r
984 bool result=true; // Assume success
\r
993 Node* pNode = Root;
\r
994 const KeyType& keyNew = newNode->getKey();
\r
997 const KeyType& key=pNode->getKey();
\r
1004 else if (keyNew < key)
\r
1006 if (pNode->getLeftChild() == 0)
\r
1008 pNode->setLeftChild(newNode);
\r
1012 pNode = pNode->getLeftChild();
\r
1014 else // keyNew > key
\r
1016 if (pNode->getRightChild()==0)
\r
1018 pNode->setRightChild(newNode);
\r
1023 pNode = pNode->getRightChild();
\r
1036 //! Pull up node's right child and let it knock node down to the left
\r
1037 void rotateLeft(Node* p)
\r
1039 Node* right = p->getRightChild();
\r
1041 p->setRightChild(right->getLeftChild());
\r
1043 if (p->isLeftChild())
\r
1044 p->getParent()->setLeftChild(right);
\r
1045 else if (p->isRightChild())
\r
1046 p->getParent()->setRightChild(right);
\r
1050 right->setLeftChild(p);
\r
1054 //! Pull up node's left child and let it knock node down to the right
\r
1055 void rotateRight(Node* p)
\r
1057 Node* left = p->getLeftChild();
\r
1059 p->setLeftChild(left->getRightChild());
\r
1061 if (p->isLeftChild())
\r
1062 p->getParent()->setLeftChild(left);
\r
1063 else if (p->isRightChild())
\r
1064 p->getParent()->setRightChild(left);
\r
1068 left->setRightChild(p);
\r
1071 //------------------------------
\r
1072 // Private Members
\r
1073 //------------------------------
\r
1074 Node* Root; // The top node. 0 if empty.
\r
1075 u32 Size; // Number of nodes in the tree
\r
1078 } // end namespace core
\r
1079 } // end namespace irr
\r
1081 #endif // __IRR_MAP_H_INCLUDED__
\r