Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members

GLIBNode.h

Go to the documentation of this file.
00001 #ifndef MMANN_GLIBNODE_H
00002 #define MMANN_GLIBNODE_H
00003 
00011 
00016 template <class Data, class ConfigData>
00017 class GLIBTreeNode
00018 {
00019 public:
00020 
00022     GLIBTreeNode(Data* data);
00023 
00025     virtual ~GLIBTreeNode();
00026 
00030     static void DeleteAllGLIBTreeNodes(GLIBTreeNode<Data, ConfigData>* Node, DeleteTreeDataEnum DeleteTreeData);
00031 
00039     static GLIBTreeNode<Data, ConfigData>* Insert(GLIBTreeNode<Data, ConfigData>* Node, ACompareNodesAlgorithm<Data, ConfigData>* Compare,
00040                                      Data* NodeData, bool* Inserted);
00041 
00048     static GLIBTreeNode<Data, ConfigData>* Remove(GLIBTreeNode<Data, ConfigData>* Node, ACompareNodesAlgorithm<Data, ConfigData>* Compare,
00049                                      Data* NodeData);
00050 
00057     static Data* Lookup(GLIBTreeNode<Data, ConfigData>* Node, ACompareNodesAlgorithm<Data, ConfigData>* Compare,
00058                                      Data* NodeData);
00059 
00066     static Data* Search(GLIBTreeNode<Data, ConfigData>* Node, ACompareNodesAlgorithm<Data, ConfigData>* Compare, Data* NodeData);
00067 
00072     static int GetHeight(GLIBTreeNode<Data, ConfigData>* Node);
00073 
00078     static int GetNodeCount(GLIBTreeNode<Data, ConfigData>* Node);
00079 
00080 protected:
00081 
00086     static GLIBTreeNode<Data, ConfigData>* Balance(GLIBTreeNode<Data, ConfigData>* Node);
00087 
00093     static GLIBTreeNode<Data, ConfigData>* RemoveLeftmost(GLIBTreeNode<Data, ConfigData>* Node, GLIBTreeNode<Data, ConfigData>** Leftmost);
00094 
00100     static GLIBTreeNode<Data, ConfigData>* RestoreLeftBalance(GLIBTreeNode<Data, ConfigData>* Node, int OldBalance);
00101 
00107     static GLIBTreeNode<Data, ConfigData>* RestoreRightBalance(GLIBTreeNode<Data, ConfigData>* Node, int OldBalance);
00108 
00113     static GLIBTreeNode<Data, ConfigData>* RotateLeft(GLIBTreeNode<Data, ConfigData>* Node);
00114 
00119     static GLIBTreeNode<Data, ConfigData>* RotateRight(GLIBTreeNode<Data, ConfigData>* Node);
00120 
00122     GLIBTreeNode<Data, ConfigData>* m_Left;
00123 
00125     GLIBTreeNode<Data, ConfigData>* m_Right;
00126 
00128     Data* m_Data;
00129 
00131     signed char m_Balance;
00132 
00133 };
00134 
00135 template <class Data, class ConfigData>
00136 GLIBTreeNode<Data, ConfigData>::GLIBTreeNode(Data* data)
00137 {
00138     m_Left = m_Right = NULL;
00139     m_Balance = 0;
00140     m_Data = data;
00141 }
00142     
00143 template <class Data, class ConfigData>
00144 GLIBTreeNode<Data, ConfigData>::~GLIBTreeNode()
00145 {
00146 }
00147 
00148 template <class Data, class ConfigData>
00149 GLIBTreeNode<Data, ConfigData>* GLIBTreeNode<Data, ConfigData>::Insert(GLIBTreeNode<Data, ConfigData>* Node, 
00150                                                     ACompareNodesAlgorithm<Data, ConfigData>* Compare,
00151                                                     Data* NodeData, bool* Inserted)
00152 {
00153     int OldBalance;
00154     int CompareValue;
00155 
00156     if (Node == NULL)
00157     {
00158         *Inserted = true;
00159         return new GLIBTreeNode<Data, ConfigData>(NodeData);
00160     }
00161 
00162     CompareValue = (*Compare).Compare(Node->m_Data, NodeData, NULL);
00163     if (CompareValue == 0)
00164     {
00165         *Inserted = false;
00166         Node->m_Data = NodeData;
00167         return Node;
00168     }
00169 
00170     if (CompareValue < 0)
00171     {
00172         if (Node->m_Left != NULL)
00173         {
00174             OldBalance = Node->m_Left->m_Balance;
00175             Node->m_Left = Insert(Node->m_Left, Compare, NodeData, Inserted);
00176             if ((OldBalance != Node->m_Left->m_Balance) && Node->m_Left->m_Balance)
00177                 Node->m_Balance -= 1;
00178         }
00179         else
00180         {
00181             *Inserted = true;
00182             Node->m_Left = new GLIBTreeNode<Data, ConfigData>(NodeData);
00183             Node->m_Balance -= 1;
00184         }
00185     }
00186     else if (CompareValue > 0)
00187     {
00188         if (Node->m_Right != NULL)
00189         {
00190             OldBalance = Node->m_Right->m_Balance;
00191             Node->m_Right = Insert(Node->m_Right, Compare, NodeData, Inserted);
00192             if ((OldBalance != Node->m_Right->m_Balance) && Node->m_Right->m_Balance)
00193                 Node->m_Balance += 1;
00194         }
00195         else
00196         {
00197             *Inserted = true;
00198             Node->m_Right = new GLIBTreeNode<Data, ConfigData>(NodeData);
00199             Node->m_Balance += 1;
00200         }
00201     }
00202 
00203     if ((*Inserted) && ((Node->m_Balance < -1) || (Node->m_Balance > 1)))
00204     {
00205         Node = Balance(Node);
00206     }
00207 
00208     return Node;
00209 }
00210 
00211 template <class Data, class ConfigData>
00212 GLIBTreeNode<Data, ConfigData>* GLIBTreeNode<Data, ConfigData>::Remove(GLIBTreeNode<Data, ConfigData>* Node, 
00213                                              ACompareNodesAlgorithm<Data, ConfigData>* Compare,
00214                                              Data* NodeData)
00215 {
00216     if (Node == NULL)
00217         return NULL;
00218 
00219     GLIBTreeNode<Data, ConfigData>* NewRoot;
00220     int OldBalance;
00221     int CompareValue;
00222 
00223     CompareValue = (*Compare).Compare(Node->m_Data, NodeData, NULL);
00224     if (CompareValue == 0)
00225     {
00226         if (Node->m_Right == NULL)
00227         {
00228             NewRoot = Node->m_Left;
00229         }
00230         else
00231         {
00232             OldBalance = Node->m_Right->m_Balance;
00233             Node->m_Right = RemoveLeftmost(Node->m_Right, &NewRoot);
00234             NewRoot->m_Left = Node->m_Left;
00235             NewRoot->m_Right = Node->m_Right;
00236             NewRoot->m_Balance = Node->m_Balance;
00237             NewRoot = RestoreRightBalance(NewRoot, OldBalance);
00238         }
00239 
00240         delete Node;
00241         return NewRoot;
00242     }
00243     else if (CompareValue < 0)
00244     {
00245         if (Node->m_Left != NULL)
00246         {
00247             OldBalance = Node->m_Left->m_Balance;
00248             Node->m_Left = Remove(Node->m_Left, Compare, NodeData);
00249             Node = RestoreLeftBalance(Node, OldBalance);
00250         }
00251     }
00252     else if (CompareValue > 0)
00253     {
00254         if (Node->m_Right != NULL)
00255         {
00256             OldBalance = Node->m_Right->m_Balance;
00257             Node->m_Right = Remove(Node->m_Right, Compare, NodeData);
00258             Node = RestoreRightBalance(Node, OldBalance);
00259         }
00260     }
00261 
00262     return Node;
00263 }
00264 
00265 template <class Data, class ConfigData>
00266 Data* GLIBTreeNode<Data, ConfigData>::Lookup(GLIBTreeNode<Data, ConfigData>* Node, 
00267                                                     ACompareNodesAlgorithm<Data, ConfigData>* Compare,
00268                                                     Data* NodeData)
00269 {
00270     if (Node == NULL)
00271         return NULL;
00272 
00273     int CompareValue = (*Compare).Compare(Node->m_Data, NodeData, NULL);
00274     if (CompareValue == 0)
00275         return Node->m_Data;
00276 
00277     if (CompareValue < 0)
00278     {
00279         if (Node->m_Left != NULL)
00280             return Lookup((GLIBTreeNode<Data, ConfigData>*)Node->m_Left, Compare, NodeData);
00281     }
00282     else if (CompareValue > 0)
00283     {
00284         if (Node->m_Right != NULL)
00285             return Lookup((GLIBTreeNode<Data, ConfigData>*)Node->m_Right, Compare, NodeData);
00286     }
00287 
00288     return NULL;
00289 }
00290 
00291 template <class Data, class ConfigData>
00292 Data* GLIBTreeNode<Data, ConfigData>::Search(GLIBTreeNode<Data, ConfigData>* Node, ACompareNodesAlgorithm<Data, ConfigData>* Compare, Data* NodeData)
00293 {
00294     if (Node == NULL)
00295         return NULL;
00296 
00297     int Direction;
00298     
00299     do
00300     {
00301         Direction = (*Compare).Compare(Node->m_Data, NodeData, NULL);
00302         if (Direction == 0)
00303             return Node->m_Data;
00304 
00305         if (Direction < 0)
00306             Node = Node->m_Left;
00307         else if (Direction > 0)
00308             Node = Node->m_Right;
00309     }
00310     while ((Node != NULL) && (Direction != 0));
00311 
00312     return NULL;
00313 }
00314 
00315 template <class Data, class ConfigData>
00316 int GLIBTreeNode<Data, ConfigData>::GetHeight(GLIBTreeNode<Data, ConfigData>* Node)
00317 {
00318     if (Node != NULL)
00319     {
00320         int LeftHeight = 0, 
00321             RightHeight = 0;
00322         
00323         if (Node->m_Left != NULL)
00324             LeftHeight = GetHeight(Node->m_Left);
00325 
00326         if (Node->m_Right != NULL)
00327             RightHeight = GetHeight(Node->m_Right);
00328 
00329         return ((LeftHeight > RightHeight) ? LeftHeight : RightHeight) + 1;
00330     }
00331 
00332     return 0;
00333 }
00334 
00335 template <class Data, class ConfigData>
00336 int GLIBTreeNode<Data, ConfigData>::GetNodeCount(GLIBTreeNode<Data, ConfigData>* Node)
00337 {
00338     int Count = 1;
00339 
00340     if (Node->m_Left)
00341         Count += GetNodeCount(Node->m_Left);
00342     if (Node->m_Right)
00343         Count += GetNodeCount(Node->m_Right);
00344 
00345     return Count;
00346 }
00347 
00348 template <class Data, class ConfigData>
00349 GLIBTreeNode<Data, ConfigData>* GLIBTreeNode<Data, ConfigData>::Balance(GLIBTreeNode<Data, ConfigData>* Node)
00350 {
00351     if (Node->m_Balance < -1)
00352     {
00353         if (Node->m_Left->m_Balance > 0)
00354             Node->m_Left = RotateLeft(Node->m_Left);
00355         Node = RotateRight(Node);
00356     }
00357     else if (Node->m_Balance > 1)
00358     {
00359         if (Node->m_Right->m_Balance < 0)
00360             Node->m_Right = RotateRight(Node->m_Right);
00361         Node = RotateLeft(Node);
00362     }
00363 
00364     return Node;
00365 }
00366 
00367 template <class Data, class ConfigData>
00368 GLIBTreeNode<Data, ConfigData>* GLIBTreeNode<Data, ConfigData>::RemoveLeftmost(GLIBTreeNode<Data, ConfigData>* Node, GLIBTreeNode<Data, ConfigData>** Leftmost)
00369 {
00370     if (Node->m_Left == NULL)
00371     {
00372         *Leftmost = Node;
00373         return Node->m_Right;
00374     }
00375 
00376     int OldBalance = Node->m_Left->m_Balance;
00377     Node->m_Left = RemoveLeftmost(Node->m_Left, Leftmost);
00378     return RestoreLeftBalance(Node, OldBalance);
00379 }
00380 
00381 template <class Data, class ConfigData>
00382 GLIBTreeNode<Data, ConfigData>* GLIBTreeNode<Data, ConfigData>::RestoreLeftBalance(GLIBTreeNode<Data, ConfigData>* Node, int OldBalance)
00383 {
00384     if (Node->m_Left == NULL)
00385         Node->m_Balance += 1;
00386     else if ((Node->m_Left->m_Balance != OldBalance) && (Node->m_Left->m_Balance == 0))
00387         Node->m_Balance += 1;
00388 
00389     if (Node->m_Balance > 1)
00390         return Balance(Node);
00391 
00392     return Node;
00393 }
00394 
00395 template <class Data, class ConfigData>
00396 GLIBTreeNode<Data, ConfigData>* GLIBTreeNode<Data, ConfigData>::RestoreRightBalance(GLIBTreeNode<Data, ConfigData>* Node, int OldBalance)
00397 {
00398     if (Node->m_Right == NULL)
00399         Node->m_Balance -= 1;
00400     else if ((Node->m_Right->m_Balance != OldBalance) && (Node->m_Right->m_Balance == 0))
00401         Node->m_Balance -= 1;
00402 
00403     if (Node->m_Balance < -1)
00404         return Balance(Node);
00405 
00406     return Node;
00407 }
00408 
00409 template <class Data, class ConfigData>
00410 GLIBTreeNode<Data, ConfigData>* GLIBTreeNode<Data, ConfigData>::RotateLeft(GLIBTreeNode<Data, ConfigData>* Node)
00411 {
00412     GLIBTreeNode<Data, ConfigData> *Left = (GLIBTreeNode<Data, ConfigData>*)Node->m_Left,
00413                                    *Right = (GLIBTreeNode<Data, ConfigData>*)Node->m_Right;
00414 
00415     Node->m_Right = Right->m_Left;
00416     Right->m_Left = Node;
00417 
00418     int aBalance = Node->m_Balance,
00419         bBalance = Right->m_Balance;
00420 
00421     if (bBalance <= 0)
00422     {
00423         if (aBalance >= 1)
00424             Right->m_Balance = bBalance - 1;
00425         else
00426             Right->m_Balance = aBalance + bBalance - 2;
00427         Node->m_Balance = aBalance - 1;
00428     }
00429     else
00430     {
00431         if (aBalance <= bBalance)
00432             Right->m_Balance = aBalance - 2;
00433         else
00434             Right->m_Balance = bBalance - 1;
00435         Node->m_Balance = aBalance - bBalance - 1;
00436     }
00437 
00438     return Right;
00439 }
00440 
00441 template <class Data, class ConfigData>
00442 GLIBTreeNode<Data, ConfigData>* GLIBTreeNode<Data, ConfigData>::RotateRight(GLIBTreeNode<Data, ConfigData>* Node)
00443 {
00444     GLIBTreeNode<Data, ConfigData> *Left = (GLIBTreeNode<Data, ConfigData>*)Node->m_Left;
00445     Node->m_Left = Left->m_Right;
00446     Left->m_Right = Node;
00447 
00448     int aBalance = Node->m_Balance,
00449         bBalance = Left->m_Balance;
00450 
00451     if (bBalance <= 0)
00452     {
00453         if (bBalance > aBalance)
00454             Left->m_Balance = bBalance + 1;
00455         else
00456             Left->m_Balance = aBalance + 2;
00457         Node->m_Balance = aBalance - bBalance + 1;
00458     }
00459     else
00460     {
00461         if (aBalance <= -1)
00462             Left->m_Balance = bBalance + 1;
00463         else
00464             Left->m_Balance = aBalance + bBalance + 2;
00465         Node->m_Balance = aBalance + 1;
00466     }
00467 
00468     return Left;
00469 }
00470 
00471 template <class Data, class ConfigData>
00472 void GLIBTreeNode<Data, ConfigData>::DeleteAllGLIBTreeNodes(GLIBTreeNode<Data, ConfigData>* Node, DeleteTreeDataEnum DeleteTreeData)
00473 {
00474     if (Node->m_Left != NULL)
00475         DeleteAllGLIBTreeNodes(Node->m_Left, DeleteTreeData);
00476     if (Node->m_Right != NULL)
00477         DeleteAllGLIBTreeNodes(Node->m_Right, DeleteTreeData);
00478 
00479     switch(DeleteTreeData)
00480     {
00481     case NO_DELETE_TREE_ITEM:
00482         break;
00483     case DELETE_TREE_ITEM:
00484         delete Node->m_Data;
00485         break;
00486     case DELETE_TREE_ITEM_ARRAY:
00487         delete [] Node->m_Data;
00488         break;
00489     default:
00490         //This shouldn't happen
00491         assert(false);
00492     }
00493 
00494     delete Node;
00495 }
00496 
00497 #endif

Generated on Sat Nov 5 11:20:16 2005 for Cpp Freecell Solver by  doxygen 1.4.4