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

AVLRedBlackTree.h

Go to the documentation of this file.
00001 #ifndef MMANN_AVLREDBLACKTREE_H
00002 #define MMANN_AVLREDBLACKTREE_H
00003 
00011 
00012 #include "AVLRedBlackNode.h"
00013 #include "CompareAlgorithms.h"
00014 #include "TestAVLRedBlackTree.h"
00015 #include "AGenericTree.h"
00016 #include <limits.h>
00017 
00019 #define RB_MAX_HEIGHT 32
00020 
00022 enum StackDirection{SDLEFT = 0, SDRIGHT};
00023 
00025 template <class Data>
00026 class TraverseNode
00027 {
00028 public:
00030     TraverseNode();
00031     
00033     bool m_Initialize;
00034 
00036     int m_TopOfStack;
00037 
00039     const AVLRedBlackNode<Data> *m_Node;
00040 
00042     const AVLRedBlackNode<Data> *m_Stack[RB_MAX_HEIGHT];
00043 };
00044 
00059 template <class Data, class ConfigData>
00060 class AVLRedBlackTree : public AGenericTree<Data, ConfigData>
00061 {
00062 public:
00064     AVLRedBlackTree(ACompareNodesAlgorithm<Data, ConfigData>* Compare, DeleteTreeDataEnum DeleteTreeData = NO_DELETE_TREE_ITEM,
00065                     ConfigData* pConfigData = NULL);
00066 
00068     virtual ~AVLRedBlackTree();
00069 
00073     AVLRedBlackTree<Data, ConfigData>* Copy();
00074 
00080     virtual Data* Search(Data* NodeData, bool* NodeInserted);
00081 
00086     virtual Data* Find(Data* NodeData);
00087 
00092     Data* Traverse(TraverseNode<Data>* TravNode);
00093 
00100     Data* FindClose(const Data* NodeData);
00101 
00106     Data* Delete(const Data* NodeData);
00107 
00112     void Verify(bool* IsDone);
00113 
00118     bool Compare(AVLRedBlackTree<Data, ConfigData>* Tree);
00119 
00125     bool CompareNodes(AVLRedBlackNode<Data>* Node1, AVLRedBlackNode<Data>* Node2);
00126 
00127 
00128 private:
00130     AVLRedBlackNode<Data>* m_Root;
00131 
00133     int m_Count;
00134 };
00135 
00136 /**********************************************
00137 AVLRedBlackTree
00138 ***********************************************/
00139 
00140 template <class Data, class ConfigData>
00141 AVLRedBlackTree<Data, ConfigData>::AVLRedBlackTree(ACompareNodesAlgorithm<Data, ConfigData>* Compare,  DeleteTreeDataEnum DeleteTreeData,
00142                                                   ConfigData* pConfigData) : AGenericTree<Data, ConfigData>(Compare, DeleteTreeData, pConfigData)
00143 {
00144     m_Root = new AVLRedBlackNode<Data>(DeleteTreeData);
00145     m_Count = 0;
00146 }
00147 
00148 template <class Data, class ConfigData>
00149 AVLRedBlackTree<Data, ConfigData>::~AVLRedBlackTree()
00150 {
00151     //Uses Knuth's Algorithm 2.3.1T as modified in exercise 13
00152     //(postorder traversal)
00153 
00154     //T1
00155     AVLRedBlackNode<Data> *StackANodes[RB_MAX_HEIGHT];
00156     unsigned long StackABits = 0;
00157     int StackAHeight = 0;
00158     AVLRedBlackNode<Data> *CurrentNode = m_Root->m_Left;
00159 
00160     while(true)
00161     {
00162         //T2
00163         while (CurrentNode != NULL)
00164         {
00165             //T3
00166             StackABits &= ~(1ul << StackAHeight);
00167             StackANodes[StackAHeight++] = CurrentNode;
00168             CurrentNode = CurrentNode->m_Left;      //going left
00169         }
00170 
00171         //T4
00172         while(true)
00173         {
00174             if (!StackAHeight)
00175             {
00176                 delete m_Root;
00177                 return;
00178             }
00179 
00180             CurrentNode = StackANodes[--StackAHeight];
00181             if (!(StackABits & (1ul << StackAHeight)))
00182             {
00183                 StackABits |= (1ul << StackAHeight++);
00184                 CurrentNode = CurrentNode->m_Right; 
00185                 break;
00186             }
00187 
00188             delete CurrentNode;
00189         }
00190     }
00191 
00192     delete m_Root;
00193 }
00194 
00195 template <class Data, class ConfigData>
00196 AVLRedBlackTree<Data, ConfigData>* AVLRedBlackTree<Data, ConfigData>::Copy()
00197 {
00198     /* This is a combination of Knuth's Algorithm 2.3.1C (copying a
00199      binary tree) and Algorithm 2.3.1T as modified by exercise 12
00200     (preorder traversal). */
00201 
00202     AVLRedBlackTree<Data, ConfigData>* NewTree;
00203 
00204     //PT1
00205     const AVLRedBlackNode<Data> *StackPANode[RB_MAX_HEIGHT];
00206     const AVLRedBlackNode<Data> **StackPAStackPointer = StackPANode;
00207     NewTree = new AVLRedBlackTree<Data, ConfigData>(m_CompareNodes, m_DeleteTreeData, m_ConfigData);
00208     NewTree->m_Count = m_Count;
00209     const AVLRedBlackNode<Data> *p = m_Root;
00210 
00211     //QT1
00212     AVLRedBlackNode<Data> *StackQANode[RB_MAX_HEIGHT];
00213     AVLRedBlackNode<Data> **StackQAStackPointer = StackQANode;
00214     AVLRedBlackNode<Data> *q = NewTree->m_Root;
00215 
00216     while(true)
00217     {
00218         //C4
00219         if (p->m_Left != NULL)
00220         {
00221             AVLRedBlackNode<Data> *r = new AVLRedBlackNode<Data>(m_DeleteTreeData);
00222             q->m_Left = r;
00223         }
00224 
00225         //C5 Find preorder successor of P and Q
00226         goto start;
00227         while(true)
00228         {
00229             //PT2
00230             while (p != NULL)
00231             {
00232                 goto escape;
00233                 start:
00234                 //PT3
00235                 *StackPAStackPointer++ = p;
00236                 *StackQAStackPointer++ = q;
00237                 p = p->m_Left;
00238                 q = q->m_Left;
00239             }
00240 
00241             //PT4
00242             if (StackPAStackPointer == StackPANode)
00243             {
00244                 assert(StackQAStackPointer == StackQANode);
00245                 return NewTree;
00246             }
00247 
00248             p = *--StackPAStackPointer;
00249             q = *--StackQAStackPointer;
00250 
00251             //PT5
00252             p = p->m_Right;
00253             q = q->m_Right;
00254         }
00255 
00256         escape:
00257         //C2
00258         if (p->m_Right)
00259         {
00260             AVLRedBlackNode<Data> *r = new AVLRedBlackNode<Data>(m_DeleteTreeData);
00261             q->m_Right = r;
00262         }
00263 
00264         //C3
00265         q->m_Color = p->m_Color;
00266         q->m_Data = p->m_Data;
00267     }
00268 }
00269 
00270 template <class Data, class ConfigData>
00271 bool AVLRedBlackTree<Data, ConfigData>::Compare(AVLRedBlackTree<Data, ConfigData>* Tree)
00272 {
00273     if (Tree == NULL)
00274         return false;
00275 
00276     if ((Tree->m_CompareNodes != m_CompareNodes) || 
00277         (Tree->m_ConfigData != m_ConfigData))
00278         return false;
00279 
00280     return CompareNodes(m_Root, Tree->m_Root);
00281 }
00282 
00283 template <class Data, class ConfigData>
00284 Data* AVLRedBlackTree<Data, ConfigData>::Traverse(TraverseNode<Data>* TravNode)
00285 {
00286     //Uses Knuth's algorithm 2.3.1T (inorder traversal)
00287     if (!TravNode->m_Initialize)
00288     {
00289         TravNode->m_Initialize = true;
00290         TravNode->m_TopOfStack = 0;
00291         TravNode->m_Node = m_Root.m_Left;
00292     }
00293     else
00294     {
00295         //T5
00296         TravNode->m_Node = m_Root.m_Right;
00297     }
00298 
00299     while(true)
00300     {
00301         //T2
00302         while (TravNode->m_Node != NULL)
00303         {
00304             //T3
00305             TravNode->m_Stack[TravNode->m_TopOfStack++] = TravNode->m_Node;
00306             TravNode->m_Node = TravNode->m_Node->m_Left;
00307         }
00308 
00309         //T4
00310         if (TravNode->m_TopOfStack == 0)
00311         {
00312             TravNode->m_Initialize = false;
00313             return NULL;
00314         }
00315 
00316         TravNode->m_Node = TravNode->m_Stack[--TravNode->m_TopOfStack];
00317 
00318         //T5
00319         return TravNode->m_Node->m_Data;
00320     }
00321 }
00322 
00323 template <class Data, class ConfigData>
00324 Data* AVLRedBlackTree<Data, ConfigData>::Search(Data* NodeData, bool* NodeInserted)
00325 {
00326     /* Algorithm based on RB-Insert from section 14.3 of _Introduction
00327      to Algorithms_, Cormen et al., MIT Press 1990, ISBN
00328      0-262-03141-8. */
00329 
00330     *NodeInserted = false;
00331     AVLRedBlackNode<Data> *StackANodes[RB_MAX_HEIGHT];
00332     StackDirection StackADirections[RB_MAX_HEIGHT];
00333     int StackAPointer = 1;
00334 
00335     AVLRedBlackNode<Data> *t, *x, *y, *n;
00336 
00337     t = m_Root;
00338     x = t->m_Left;
00339 
00340     if (x == NULL)
00341     {
00342         m_Count++;
00343         assert(m_Count == 1);
00344         x = t->m_Left = new AVLRedBlackNode<Data>(m_DeleteTreeData);
00345         *NodeInserted = true;
00346         x->m_Data = NodeData;
00347         x->m_Color = BLACK;
00348         return NULL;
00349     }
00350 
00351     StackADirections[0] = SDLEFT;
00352     StackANodes[0] = m_Root;
00353 
00354     while(true)
00355     {
00356         int CompareValue = m_CompareNodes->Compare(NodeData, x->m_Data, m_ConfigData);
00357         if (CompareValue < 0)
00358         {
00359             StackANodes[StackAPointer] = x;
00360             StackADirections[StackAPointer++] = SDLEFT;
00361             y = x->m_Left;
00362             if (y == NULL)
00363             {
00364                 n = x = x->m_Left = new AVLRedBlackNode<Data>(m_DeleteTreeData);
00365                 *NodeInserted = true;
00366                 break;
00367             }   
00368         }
00369         else if (CompareValue > 0)
00370         {
00371             StackANodes[StackAPointer] = x;
00372             StackADirections[StackAPointer++] = SDRIGHT;
00373             y = x->m_Right;
00374             if (y == NULL)
00375             {
00376                 n = x = x->m_Right = new AVLRedBlackNode<Data>(m_DeleteTreeData);
00377                 *NodeInserted = true;
00378                 break;
00379             }
00380         }
00381         else
00382             return x->m_Data;
00383 
00384         x = y;
00385     }
00386 
00387     m_Count++;
00388     x->m_Data = NodeData;
00389     x->m_Left = x->m_Right = NULL;
00390     x->m_Color = RED;
00391 
00392     while(true)
00393     {
00394         if ((StackAPointer < 3) || (StackANodes[StackAPointer - 1]->m_Color != RED))
00395             break;
00396 
00397         if (StackADirections[StackAPointer - 2] == SDLEFT)
00398         {
00399             y = StackANodes[StackAPointer - 2]->m_Right;
00400             if (y != NULL && y->m_Color == RED)
00401             {
00402                 //case 1
00403                 StackANodes[StackAPointer - 1]->m_Color = y->m_Color = BLACK;
00404                 StackANodes[StackAPointer - 2]->m_Color = RED;
00405                 StackAPointer -= 2;
00406             }
00407             else
00408             {
00409                 if (StackADirections[StackAPointer - 1] == SDRIGHT)
00410                 {
00411                     //case 2
00412                     x = StackANodes[StackAPointer - 1];
00413                     y = x->m_Right;
00414                     x->m_Right = y->m_Left;
00415                     y->m_Left = x;
00416                     StackANodes[StackAPointer - 2]->m_Left = y;
00417                 }
00418                 else
00419                     y = StackANodes[StackAPointer - 1];
00420 
00421                 //case 3
00422                 x = StackANodes[StackAPointer - 2];
00423                 x->m_Color = RED;
00424                 y->m_Color = BLACK;
00425                 x->m_Left = y->m_Right;
00426                 y->m_Right = x;
00427                 StackADirections[StackAPointer - 3] ? 
00428                     StackANodes[StackAPointer - 3]->m_Right = y :
00429                     StackANodes[StackAPointer - 3]->m_Left = y;
00430                 break;
00431             }
00432         }
00433         else
00434         {
00435             y = StackANodes[StackAPointer - 2]->m_Left;
00436             if (y != NULL && y->m_Color == RED)
00437             {
00438                 //case 1
00439                 StackANodes[StackAPointer - 1]->m_Color = y->m_Color = BLACK;
00440                 StackANodes[StackAPointer - 2]->m_Color = RED;
00441                 StackAPointer -= 2;
00442             }
00443             else
00444             {
00445                 if (StackADirections[StackAPointer - 1] == SDLEFT)
00446                 {
00447                     //case 2
00448                     x = StackANodes[StackAPointer - 1];
00449                     y = x->m_Left;
00450                     x->m_Left = y->m_Right;
00451                     y->m_Right = x;
00452                     StackANodes[StackAPointer - 2]->m_Right = y;
00453                 }
00454                 else
00455                     y = StackANodes[StackAPointer - 1];
00456 
00457                 //case 3
00458                 x = StackANodes[StackAPointer - 2];
00459                 x->m_Color = RED;
00460                 y->m_Color = BLACK;
00461 
00462                 x->m_Right = y->m_Left;
00463                 y->m_Left = x;
00464                 StackADirections[StackAPointer - 3] ? 
00465                     StackANodes[StackAPointer - 3]->m_Right = y :
00466                     StackANodes[StackAPointer - 3]->m_Left = y;
00467                 break;
00468             }
00469         }
00470     }
00471 
00472     m_Root->m_Left->m_Color = BLACK;
00473 
00474     return NULL;
00475 }
00476 
00477 template <class Data, class ConfigData>
00478 Data* AVLRedBlackTree<Data, ConfigData>::Find(Data* NodeData)
00479 {
00480     const AVLRedBlackNode<Data> *CurrentNode;
00481 
00482     for (CurrentNode = m_Root->m_Left; CurrentNode != NULL;)
00483     {
00484         int CompareValue = m_CompareNodes->Compare(NodeData, CurrentNode->m_Data, m_ConfigData);
00485         if (CompareValue < 0)
00486             CurrentNode = CurrentNode->m_Left;
00487         else if (CompareValue > 0)
00488             CurrentNode = CurrentNode->m_Right;
00489         else
00490             return CurrentNode->m_Data;
00491     }
00492 
00493     return NULL;
00494 }
00495 
00496 template <class Data, class ConfigData>
00497 Data* AVLRedBlackTree<Data, ConfigData>::FindClose(const Data* NodeData)
00498 {
00499     const AVLRedBlackNode<Data> *CurrentNode;
00500 
00501     CurrentNode = m_Root.m_Left;
00502     if (CurrentNode == NULL)
00503         return NULL;
00504 
00505     while(true)
00506     {
00507         int CompareValue = m_CompareNodes->Compare(NodeData, CurrentNode->m_Data, m_ConfigData);
00508         StackDirection Direction;
00509 
00510         if (CompareValue < 0)
00511             Direction = SDLEFT;
00512         else if (CompareValue > 0)
00513             Direction = SDRIGHT;
00514         else
00515             return CurrentNode->m_Data;
00516 
00517         if ((Direction == SDRIGHT) && CurrentNode->m_Right)
00518             CurrentNode = CurrentNode->m_Right;
00519         else if ((Direction == SDLEFT) && CurrentNode->m_Left)
00520             CurrentNode = CurrentNode->m_Left;
00521         else
00522             return CurrentNode->m_Data;
00523     }
00524 }
00525 
00526 template <class Data, class ConfigData>
00527 Data* AVLRedBlackTree<Data, ConfigData>::Delete(const Data* NodeData)
00528 {
00529     /* Algorithm based on RB-Delete and RB-Delete-Fixup from section
00530      14.4 of _Introduction to Algorithms_, Cormen et al., MIT Press
00531      1990, ISBN 0-262-03141-8. */
00532 
00533     AVLRedBlackNode<Data> *StackPNodes[RB_MAX_HEIGHT];
00534     StackDirection StackPDirections[RB_MAX_HEIGHT];
00535     int StackPPointer = 1;
00536 
00537     AVLRedBlackNode<Data> *w, *x, *y, *z;
00538 
00539     StackPDirections[0] = SDLEFT;
00540     StackPNodes[0] = m_Root;
00541     z = m_Root->m_Left;
00542     while(true)
00543     {
00544         if (z == NULL)
00545             return NULL;
00546 
00547         int CompareValue = m_CompareNodes->Compare(NodeData, z->m_Data, m_ConfigData);
00548         if (CompareValue == 0)
00549             break;
00550 
00551         StackPNodes[StackPPointer] = z;
00552         if (CompareValue < 0)
00553         {
00554             z = z->m_Left;
00555             StackPDirections[StackPPointer] = SDLEFT;
00556         }
00557         else if (CompareValue > 0)
00558         {
00559             z = z->m_Right;
00560             StackPDirections[StackPPointer] = SDRIGHT;
00561         }
00562         
00563         StackPPointer++;
00564     }
00565 
00566     m_Count--;
00567 
00568     NodeData = z->m_Data;
00569 
00570     //RB-Delete: Line 1
00571     if (z->m_Left == NULL || z->m_Right == NULL)
00572     {
00573         //Line 2
00574         y = z;
00575 
00576         //Lines 4-6
00577         if (y->m_Left != NULL)
00578             x = y->m_Left;
00579         else
00580             x = y->m_Right;
00581 
00582         StackPDirections[StackPPointer - 1] ? 
00583             StackPNodes[StackPPointer - 1]->m_Right = x :
00584             StackPNodes[StackPPointer - 1]->m_Left = x; 
00585     }
00586     else
00587     {
00588         StackPNodes[StackPPointer] = z;
00589         StackPDirections[StackPPointer++] = SDRIGHT;
00590 
00591         //Line 3
00592         y = z->m_Right;
00593         while (y->m_Left)
00594         {
00595             StackPNodes[StackPPointer] = y;
00596             StackPDirections[StackPPointer++] = SDLEFT;
00597             y = y->m_Left;
00598         }
00599 
00600         //Lines 4-6
00601         x = y->m_Right;
00602 
00603         //Lines 13-15
00604         z->m_Data = y->m_Data;
00605         StackPDirections[StackPPointer - 1] ? 
00606             StackPNodes[StackPPointer - 1]->m_Right = x :
00607             StackPNodes[StackPPointer - 1]->m_Left = x; 
00608     }
00609 
00610     //Line 16
00611     if (y->m_Color == RED)
00612     {
00613         delete y;
00614         return (Data*)NodeData;
00615     }
00616 
00617     delete y;
00618 
00619     //Numbers below are line numbers from the RB-Delete-Fixup
00620     while (StackPPointer > 1 && (x == NULL || x->m_Color == BLACK))
00621     //1
00622     {
00623         if (StackPDirections[StackPPointer - 1] == SDLEFT)
00624         //2
00625         {
00626             w = StackPNodes[StackPPointer - 1]->m_Right;
00627             //3
00628             if (w->m_Color == RED)
00629             //4
00630             {
00631                 //Case1
00632                 w->m_Color = BLACK;
00633                 //5
00634                 StackPNodes[StackPPointer - 1]->m_Color = RED;
00635                 //6
00636                 StackPNodes[StackPPointer - 1]->m_Right = w->m_Left;
00637                 //7
00638                 w->m_Left = StackPNodes[StackPPointer - 1];
00639                 StackPDirections[StackPPointer - 2] ? 
00640                     StackPNodes[StackPPointer - 2]->m_Right = w :
00641                     StackPNodes[StackPPointer - 2]->m_Left = w;
00642 
00643                 StackPNodes[StackPPointer] = StackPNodes[StackPPointer - 1];
00644                 StackPDirections[StackPPointer] = SDLEFT;
00645                 StackPNodes[StackPPointer - 1] = w;
00646                 StackPPointer++;
00647                 w = StackPNodes[StackPPointer - 1]->m_Right;
00648                 //8
00649             }
00650 
00651             if ((w->m_Left == NULL || w->m_Left->m_Color == BLACK) &&
00652                 (w->m_Right == NULL || w->m_Right->m_Color == BLACK))
00653             //9
00654             {
00655                 //Case2
00656                 w->m_Color = RED;
00657                 //10
00658                 x = StackPNodes[StackPPointer - 1];
00659                 //11
00660                 StackPPointer--;
00661             }
00662             else
00663             {
00664                 if (w->m_Right == NULL || w->m_Right->m_Color == BLACK)
00665                 //12
00666                 {
00667                     //Case 3
00668                     w->m_Left->m_Color = BLACK;
00669                     //13
00670                     w->m_Color = RED;
00671                     //14
00672                     y = w->m_Left;
00673                     //15
00674                     w->m_Left = y->m_Right;
00675                     y->m_Right = w;
00676                     w = StackPNodes[StackPPointer - 1]->m_Right = y;
00677                     //16
00678                 }
00679 
00680                 //Case 4
00681                 w->m_Color = StackPNodes[StackPPointer - 1]->m_Color;
00682                 //17
00683                 StackPNodes[StackPPointer - 1]->m_Color = BLACK;
00684                 //18
00685                 w->m_Right->m_Color = BLACK;
00686                 //19
00687                 StackPNodes[StackPPointer - 1]->m_Right = w->m_Left;
00688                 //20
00689                 w->m_Left = StackPNodes[StackPPointer - 1];
00690                 StackPDirections[StackPPointer - 2] ? 
00691                     StackPNodes[StackPPointer - 2]->m_Right = w :
00692                     StackPNodes[StackPPointer - 2]->m_Left = w;
00693                 x = m_Root->m_Left;
00694                 //21
00695                 break;
00696             }
00697         }
00698         else
00699         {
00700             w = StackPNodes[StackPPointer - 1]->m_Left;
00701             if (w->m_Color == RED)
00702             {
00703                 //Case 1
00704                 w->m_Color = BLACK;
00705                 StackPNodes[StackPPointer - 1]->m_Color = RED;
00706                 
00707                 StackPNodes[StackPPointer - 1]->m_Left = w->m_Right;
00708                 w->m_Right = StackPNodes[StackPPointer - 1];
00709                 StackPDirections[StackPPointer - 2] ? 
00710                     StackPNodes[StackPPointer - 2]->m_Right = w :
00711                     StackPNodes[StackPPointer - 2]->m_Left = w;
00712                 
00713                 StackPNodes[StackPPointer] = StackPNodes[StackPPointer - 1];
00714                 StackPDirections[StackPPointer] = SDRIGHT;
00715                 StackPNodes[StackPPointer - 1] = w;
00716                 StackPPointer++;
00717 
00718                 w = StackPNodes[StackPPointer - 1]->m_Left;
00719             }
00720 
00721             if ((w->m_Left == NULL || w->m_Left->m_Color == BLACK) && 
00722                 (w->m_Right == NULL || w->m_Right->m_Color == BLACK))
00723             {
00724                 //Case 2
00725                 w->m_Color = RED;
00726                 x = StackPNodes[StackPPointer - 1];
00727                 StackPPointer--;
00728             }
00729             else
00730             {
00731                 if (w->m_Left == NULL || w->m_Left->m_Color == BLACK)
00732                 {
00733                     //Case 3
00734                     w->m_Right->m_Color = BLACK;
00735                     w->m_Color = RED;
00736 
00737                     y = w->m_Right;
00738                     w->m_Right = y->m_Left;
00739                     y->m_Left = w;
00740 
00741                     w = StackPNodes[StackPPointer - 1]->m_Left = y;
00742                 }
00743 
00744                 //Case 4
00745                 w->m_Color = StackPNodes[StackPPointer - 1]->m_Color;
00746                 StackPNodes[StackPPointer - 1]->m_Color = BLACK;
00747                 w->m_Left->m_Color = BLACK;
00748 
00749                 StackPNodes[StackPPointer - 1]->m_Left = w->m_Right;
00750                 w->m_Right = StackPNodes[StackPPointer - 1];
00751                 StackPDirections[StackPPointer - 2] ? 
00752                     StackPNodes[StackPPointer - 2]->m_Right = w :
00753                     StackPNodes[StackPPointer - 2]->m_Left = w;
00754 
00755                 x = m_Root->m_Left;
00756                 break;
00757             }
00758         }
00759     }
00760 
00761     if (x != NULL)
00762         x->m_Color = BLACK;
00763     //23
00764 
00765     return (Data*) NodeData;
00766 }
00767 
00768 template <class Data, class ConfigData>
00769 bool AVLRedBlackTree<Data, ConfigData>::CompareNodes(AVLRedBlackNode<Data>* Node1, AVLRedBlackNode<Data>* Node2)
00770 {
00771     if ((Node1 == NULL || Node2 == NULL))
00772     {
00773         if ((Node1 == NULL && Node2 == NULL))
00774             return true;
00775 
00776         return false;
00777     }
00778 
00779     if ((Node1->m_Data != Node2->m_Data) || (Node1->m_Color != Node2->m_Color) || 
00780         ((Node1->m_Left != NULL) ^ (Node2->m_Left != NULL)) ||
00781         ((Node1->m_Right != NULL) ^ (Node2->m_Right != NULL)))
00782     {
00783         printf("Nodes differ: %d Node2=%d Node1->m_Color=%d Node2->m_Color=%d a:",
00784             Node1->m_Data, Node2->m_Data, Node1->m_Color, Node2->m_Color);
00785         if (Node1->m_Left)
00786             printf("l");
00787         if (Node1->m_Right)
00788             printf("r");
00789         printf(" b:");
00790         if (Node2->m_Left)
00791             printf("l");
00792         if (Node2->m_Right)
00793             printf("r");
00794         printf("\n");
00795         return false;
00796     }
00797 
00798     bool Compare = true;
00799     if (Node1->m_Left != NULL)
00800         Compare = CompareNodes(Node1->m_Left, Node2->m_Left);
00801     if ((Compare) && (Node1->m_Right != NULL))
00802         Compare = CompareNodes(Node1->m_Right, Node2->m_Right);
00803 
00804     return Compare;
00805 }   
00806 
00807 template <class Data, class ConfigData>
00808 void AVLRedBlackTree<Data, ConfigData>::Verify(bool* IsDone)
00809 {
00810     int Count = 0;
00811     RecurseTree (m_Root.m_Left, &Count, INT_MIN, INT_MAX, Done);
00812     if (Count != m_Count)
00813     {
00814         cout << " Tree has " << Count << " nodes, but tree count is " 
00815              << m_Count << "." << endl;
00816         *IsDone = true;
00817     }
00818 }
00819 
00820 /**********************************************
00821 TraverseNode
00822 ***********************************************/
00823 
00824 //constructor
00825 template <class Data>
00826 TraverseNode<Data>::TraverseNode()
00827 {
00828     m_Initialize = false;
00829     m_TopOfStack = 0;
00830     m_Node = NULL;
00831 }
00832 
00833 #endif

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