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

AVLTree.h

Go to the documentation of this file.
00001 #ifndef MMANN_AVLTREE_H
00002 #define MMANN_AVLTREE_H
00003 
00011 
00012 #include <assert.h>
00013 #include "AVLNode.h"
00014 
00019 template <class Data, class ConfigData>
00020 class AVLTree : public AGenericTree<Data, ConfigData>
00021 {
00022 public:
00024     AVLTree(ACompareNodesAlgorithm<Data, ConfigData>* Compare, DeleteTreeDataEnum DeleteTreeData = NO_DELETE_TREE_ITEM,
00025                     ConfigData* pConfigData = NULL);
00026 
00028     virtual ~AVLTree();
00029 
00035     virtual Data* Search(Data* NodeData, bool* NodeInserted);
00036 
00041     virtual Data* Find(Data* NodeData);
00042 
00045     virtual void DeleteTree();
00046 
00051     Data* Delete(Data* NodeData);
00052 
00056     Data* DeleteRoot();
00057     
00058 protected:
00059 
00066     Data* Insert(AVLTree<Data, ConfigData>* Tree, Data* NodeData, bool &HasTreeGrown);
00067 
00074     Data* Find(AVLTree<Data, ConfigData>* Tree, Data* NodeData);
00075 
00082     AVLNode<Data>* Remove(AVLTree<Data, ConfigData>* Tree, Data* NodeData, bool &HasTreeShrunk);
00083 
00089     AVLNode<Data>* RemoveRoot(AVLTree<Data, ConfigData>* Tree, bool &HasTreeShrunk);
00090 
00094     void SwingLeft(AVLNode<Data>** Root);
00095 
00099     void SwingRight(AVLNode<Data>** Root);
00100 
00104     void BalanceAfterNastySwing(AVLNode<Data>* Root);
00105 
00107     AVLNode<Data>* m_Root;
00108 };
00109 
00110 template <class Data, class ConfigData>
00111 AVLTree<Data, ConfigData>::AVLTree(ACompareNodesAlgorithm<Data, ConfigData>* Compare, DeleteTreeDataEnum DeleteTreeData,
00112                     ConfigData* pConfigData) : AGenericTree<Data, ConfigData>(Compare, DeleteTreeData, pConfigData)
00113 {
00114     m_Root = NULL;
00115 }
00116 
00117 template <class Data, class ConfigData>
00118 AVLTree<Data, ConfigData>::~AVLTree()
00119 {
00120 }
00121 
00122 template <class Data, class ConfigData>
00123 void AVLTree<Data, ConfigData>::DeleteTree()
00124 {
00125     if (m_Root != NULL)
00126         DeleteAllAVLNodes(m_Root, m_DeleteTreeData);
00127 }
00128 
00129 template <class Data, class ConfigData>
00130 Data* AVLTree<Data, ConfigData>::Delete(Data* NodeData)
00131 {
00132 bool LocalHasTreeShrunk;
00133 AVLNode<Data>* TempNode;
00134 Data* TempData;
00135 
00136     TempNode = Remove(this, NodeData, LocalHasTreeShrunk);
00137     TempData = TempNode->m_Data;
00138     delete TempNode;
00139     return TempData;
00140 }
00141 
00142 template <class Data, class ConfigData>
00143 AVLNode<Data>* AVLTree<Data, ConfigData>::Remove(AVLTree<Data, ConfigData>* Tree, Data* NodeData, bool &HasTreeShrunk)
00144 {
00145     AVLNode<Data>* TempNode;
00146 
00147     int CompareValue = Tree->m_CompareNodes->Compare(Tree->m_Root->m_Data, NodeData, Tree->m_ConfigData);
00148     if (CompareValue > 0)
00149     {
00150         //remove from left subtree
00151         AVLTree<Data, ConfigData> LeftSubtree(Tree->m_CompareNodes, Tree->m_DeleteTreeData, Tree->m_ConfigData);
00152         if (LeftSubtree.m_Root = Tree->m_Root->m_Left)
00153         {
00154             TempNode = Remove(&LeftSubtree, NodeData, HasTreeShrunk);
00155             Tree->m_Root->m_Left = LeftSubtree.m_Root;
00156             if (HasTreeShrunk)
00157             {
00158                 switch(Tree->m_Root->m_Balance++)
00159                 {
00160                 case -1:
00161                     HasTreeShrunk = true;
00162                     return TempNode;
00163                 case 0:
00164                     HasTreeShrunk = false;
00165                     return TempNode;
00166                 }
00167                 switch(Tree->m_Root->m_Right->m_Balance)
00168                 {
00169                 case 0:
00170                     SwingLeft(&(Tree->m_Root));
00171                     Tree->m_Root->m_Balance = -1;
00172                     Tree->m_Root->m_Left->m_Balance = 1;
00173                     HasTreeShrunk = false;
00174                     return TempNode;
00175                 case 1:
00176                     SwingLeft(&(Tree->m_Root));
00177                     Tree->m_Root->m_Balance = 0;
00178                     Tree->m_Root->m_Left->m_Balance = 0;
00179                     HasTreeShrunk = true;
00180                     return TempNode;
00181                 }
00182                 
00183                 SwingRight(&(Tree->m_Root->m_Right));
00184                 SwingLeft(&(Tree->m_Root));
00185                 BalanceAfterNastySwing(Tree->m_Root);
00186                 HasTreeShrunk = true;
00187                 return TempNode;
00188             }
00189         }
00190     }
00191     else if (CompareValue == 0)
00192     {
00193         return RemoveRoot(Tree, HasTreeShrunk);
00194     }
00195     else if (CompareValue < 0)
00196     {
00197         //remove the right subtree
00198         AVLTree<Data, ConfigData> RightSubtree(Tree->m_CompareNodes, Tree->m_DeleteTreeData, Tree->m_ConfigData);
00199         if (RightSubtree.m_Root = Tree->m_Root->m_Right)
00200         {
00201             TempNode = Remove(&RightSubtree, NodeData, HasTreeShrunk);
00202             Tree->m_Root->m_Right = RightSubtree.m_Root;
00203             if (HasTreeShrunk)
00204             {
00205                 switch(Tree->m_Root->m_Balance--)
00206                 {
00207                 case 1:
00208                     HasTreeShrunk = true;
00209                     return TempNode;
00210                 case 0:
00211                     HasTreeShrunk = false;
00212                     return TempNode;
00213                 }
00214                 switch(Tree->m_Root->m_Left->m_Balance)
00215                 {
00216                 case 0:
00217                     SwingRight(&(Tree->m_Root));
00218                     Tree->m_Root->m_Balance = 1;
00219                     Tree->m_Root->m_Right->m_Balance = -1;
00220                     HasTreeShrunk = false;
00221                     return TempNode;
00222                 case -1:
00223                     SwingRight(&(Tree->m_Root));
00224                     Tree->m_Root->m_Balance = 0;
00225                     Tree->m_Root->m_Right->m_Balance = 0;
00226                     HasTreeShrunk = true;
00227                     return TempNode;
00228                 }
00229 
00230                 SwingLeft(&(Tree->m_Root->m_Left));
00231                 SwingRight(&(Tree->m_Root));
00232                 BalanceAfterNastySwing(Tree->m_Root);
00233                 HasTreeShrunk = true;
00234                 return TempNode;
00235             }
00236         }
00237     }
00238 
00239     HasTreeShrunk = false;
00240     return TempNode;
00241 }
00242 
00243 template <class Data, class ConfigData>
00244 Data* AVLTree<Data, ConfigData>::DeleteRoot()
00245 {
00246 bool LocalHasTreeShrunk;
00247 AVLNode<Data>* TempNode;
00248 Data* TempData;
00249 
00250     TempNode = RemoveRoot(this, LocalHasTreeShrunk);
00251     TempData = TempNode->m_Data;
00252     delete TempNode;
00253     return TempData;
00254 }
00255 
00256 template <class Data, class ConfigData>
00257 AVLNode<Data>* AVLTree<Data, ConfigData>::RemoveRoot(AVLTree<Data, ConfigData>* Tree, bool &HasTreeShrunk)
00258 {
00259     if (Tree->m_Root == NULL)
00260         return NULL;
00261 
00262     AVLNode<Data>* Node = Tree->m_Root;
00263     AVLNode<Data>* TempNode;
00264 
00265     if (Tree->m_Root->m_Left == NULL)
00266     {
00267         if (Tree->m_Root->m_Right == NULL)
00268         {
00269             Tree->m_Root = NULL;
00270             HasTreeShrunk = true;
00271             return Node;
00272         }
00273         Tree->m_Root = Tree->m_Root->m_Right;
00274         HasTreeShrunk = true;
00275         return Node;
00276     }
00277     if (Tree->m_Root->m_Right == NULL)
00278     {
00279         Tree->m_Root = Tree->m_Root->m_Left;
00280         HasTreeShrunk = true;
00281         return Node;
00282     }
00283 
00284     TempNode = Node;
00285     if (Tree->m_Root->m_Balance < 0)
00286     {
00287         //remove from the left subtree
00288         Node = Tree->m_Root->m_Left;
00289         while (Node->m_Right)
00290             Node = Node->m_Right;
00291     }
00292     else
00293     {
00294         //remove from the right subtree
00295         Node = Tree->m_Root->m_Right;
00296         while (Node->m_Left)
00297             Node = Node->m_Left;
00298     }
00299 
00300     Remove(Tree, Node->m_Data, HasTreeShrunk);
00301     Node->m_Left = Tree->m_Root->m_Left;
00302     Node->m_Right = Tree->m_Root->m_Right;
00303     Node->m_Balance = Tree->m_Root->m_Balance;
00304     Tree->m_Root = Node;
00305     if (Node->m_Balance == 0)
00306     {
00307         return TempNode;
00308     }
00309 
00310     HasTreeShrunk = false;
00311     return TempNode;
00312 }
00313 
00314 template <class Data, class ConfigData>
00315 void AVLTree<Data, ConfigData>::SwingLeft(AVLNode<Data>** Root)
00316 {
00317     AVLNode<Data>* a = *Root;
00318     AVLNode<Data>* b = a->m_Right;
00319     *Root = b;
00320     a->m_Right = b->m_Left;
00321     b->m_Left = a;
00322 }
00323 
00324 template <class Data, class ConfigData>
00325 void AVLTree<Data, ConfigData>::SwingRight(AVLNode<Data>** Root)
00326 {
00327     AVLNode<Data>* a = *Root;
00328     AVLNode<Data>* b = a->m_Left;
00329     *Root = b;
00330     a->m_Left = b->m_Right;
00331     b->m_Right = a;
00332 }
00333 
00334 template <class Data, class ConfigData>
00335 void AVLTree<Data, ConfigData>::BalanceAfterNastySwing(AVLNode<Data>* Root)
00336 {
00337     switch(Root->m_Balance)
00338     {
00339     case -1:
00340         Root->m_Left->m_Balance = 0;
00341         Root->m_Right->m_Balance = 1;
00342         break;
00343     case 1:
00344         Root->m_Left->m_Balance = -1;
00345         Root->m_Right->m_Balance = 0;
00346         break;
00347     case 0:
00348         Root->m_Left->m_Balance = 0;
00349         Root->m_Right->m_Balance = 0;
00350         break;
00351     }
00352 
00353     Root->m_Balance = 0;
00354 }
00355 
00356 template <class Data, class ConfigData>
00357 Data* AVLTree<Data, ConfigData>::Find(Data* NodeData)
00358 {
00359     return Find(this, NodeData);
00360 }
00361 
00362 template <class Data, class ConfigData>
00363 Data* AVLTree<Data, ConfigData>::Find(AVLTree<Data, ConfigData>* Tree, Data* NodeData)
00364 {
00365     if (Tree->m_Root == NULL)
00366         return NULL;
00367 
00368     int CompareValue = Tree->m_CompareNodes->Compare(Tree->m_Root->m_Data, NodeData, Tree->m_ConfigData);
00369     if (CompareValue > 0)
00370     {
00371         AVLTree<Data, ConfigData> LeftSubtree(Tree->m_CompareNodes, Tree->m_DeleteTreeData, Tree->m_ConfigData);
00372         LeftSubtree.m_Root = Tree->m_Root->m_Left;
00373         return Find(&LeftSubtree, NodeData);
00374     }
00375     else if (CompareValue == 0)
00376     {
00377         return Tree->m_Root->m_Data;
00378     }
00379     else if (CompareValue < 0)
00380     {
00381         AVLTree<Data, ConfigData> RightSubtree(Tree->m_CompareNodes, Tree->m_DeleteTreeData, Tree->m_ConfigData);
00382         RightSubtree.m_Root = Tree->m_Root->m_Right;
00383         return Find(&RightSubtree, NodeData);
00384     }
00385 
00386     //this shouldn't happen!!!!
00387     assert(false);
00388     return NULL;
00389 }
00390 
00391 template <class Data, class ConfigData>
00392 Data* AVLTree<Data, ConfigData>::Search(Data* NodeData, bool* NodeInserted)
00393 {
00394 bool LocalHasTreeGrown;
00395 
00396     *NodeInserted = false;
00397     Data* FindNode = Find(NodeData);
00398     if (FindNode == NULL)
00399     {
00400         *NodeInserted = true;
00401         Insert(this, NodeData, LocalHasTreeGrown);
00402     }
00403 
00404     return FindNode;
00405 }
00406 
00407 template <class Data, class ConfigData>
00408 Data* AVLTree<Data, ConfigData>::Insert(AVLTree<Data, ConfigData>* Tree, Data* NodeData, bool &HasTreeGrown)
00409 {
00410     //insert into an empty tree
00411     if (Tree->m_Root == NULL)
00412     {
00413         Tree->m_Root = new AVLNode<Data>(NodeData);
00414         HasTreeGrown = true;
00415         return NodeData;
00416     }
00417 
00418     if (Tree->m_CompareNodes->Compare(Tree->m_Root->m_Data, NodeData, NULL) > 0)
00419     {
00420         //insert into the left subtree
00421         if (Tree->m_Root->m_Left != NULL)
00422         {
00423             AVLTree<Data, ConfigData> LeftSubtree(m_CompareNodes);
00424             LeftSubtree.m_Root = Tree->m_Root->m_Left;
00425             Insert(&LeftSubtree, NodeData, HasTreeGrown);
00426             if (HasTreeGrown)
00427             {
00428                 switch(Tree->m_Root->m_Balance--)
00429                 {
00430                 case 1:
00431                     HasTreeGrown = false;
00432                     return NodeData;
00433                 case 0:
00434                     HasTreeGrown = true;
00435                     return NodeData;
00436                 }
00437 
00438                 if (Tree->m_Root->m_Left->m_Balance < 0)
00439                 {
00440                     SwingRight(&(Tree->m_Root));
00441                     Tree->m_Root->m_Balance = 0;
00442                     Tree->m_Root->m_Right->m_Balance = 0;
00443                 }
00444                 else
00445                 {
00446                     SwingLeft(&(Tree->m_Root->m_Left));
00447                     SwingRight(&(Tree->m_Root));
00448                     BalanceAfterNastySwing(Tree->m_Root);
00449                 }
00450             }
00451             else
00452             {
00453                 Tree->m_Root->m_Left = LeftSubtree.m_Root;
00454             }
00455 
00456             HasTreeGrown = false;
00457             return NodeData;
00458         }
00459         else
00460         {
00461             Tree->m_Root->m_Left = new AVLNode<Data>(NodeData);
00462             if (Tree->m_Root->m_Balance--)
00463             {
00464                 HasTreeGrown = false;
00465                 return NodeData;
00466             }
00467 
00468             HasTreeGrown = true;
00469             return NodeData;
00470         }
00471     }
00472     else
00473     {
00474         //insert into the right subtree
00475         if (Tree->m_Root->m_Right != NULL)
00476         {
00477             AVLTree<Data, ConfigData> RightSubtree(m_CompareNodes);
00478             RightSubtree.m_Root = Tree->m_Root->m_Right;
00479             Insert(&RightSubtree, NodeData, HasTreeGrown);
00480             if (HasTreeGrown)
00481             {
00482                 switch(Tree->m_Root->m_Balance++)
00483                 {
00484                 case -1:
00485                     HasTreeGrown = false;
00486                     return NodeData;
00487                 case 0:
00488                     HasTreeGrown = true;
00489                     return NodeData;
00490                 }
00491 
00492                 if (Tree->m_Root->m_Right->m_Balance > 0)
00493                 {
00494                     SwingLeft(&(Tree->m_Root));
00495                     Tree->m_Root->m_Balance = 0;
00496                     Tree->m_Root->m_Left->m_Balance = 0;
00497                 }
00498                 else
00499                 {
00500                     SwingRight(&(Tree->m_Root->m_Right));
00501                     SwingLeft(&(Tree->m_Root));
00502                     BalanceAfterNastySwing(Tree->m_Root);
00503                 }
00504             }
00505             else
00506             {
00507                 Tree->m_Root->m_Right = RightSubtree.m_Root;
00508             }
00509 
00510             HasTreeGrown = false;
00511             return NodeData;
00512         }
00513         else
00514         {
00515             Tree->m_Root->m_Right = new AVLNode<Data>(NodeData);
00516             if (Tree->m_Root->m_Balance++)
00517             {
00518                 HasTreeGrown = false;
00519                 return NodeData;
00520             }
00521 
00522             HasTreeGrown = true;
00523             return NodeData;
00524         }
00525     }
00526 }
00527 
00528 #endif

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