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
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
00152
00153
00154
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
00163 while (CurrentNode != NULL)
00164 {
00165
00166 StackABits &= ~(1ul << StackAHeight);
00167 StackANodes[StackAHeight++] = CurrentNode;
00168 CurrentNode = CurrentNode->m_Left;
00169 }
00170
00171
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
00199
00200
00201
00202 AVLRedBlackTree<Data, ConfigData>* NewTree;
00203
00204
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
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
00219 if (p->m_Left != NULL)
00220 {
00221 AVLRedBlackNode<Data> *r = new AVLRedBlackNode<Data>(m_DeleteTreeData);
00222 q->m_Left = r;
00223 }
00224
00225
00226 goto start;
00227 while(true)
00228 {
00229
00230 while (p != NULL)
00231 {
00232 goto escape;
00233 start:
00234
00235 *StackPAStackPointer++ = p;
00236 *StackQAStackPointer++ = q;
00237 p = p->m_Left;
00238 q = q->m_Left;
00239 }
00240
00241
00242 if (StackPAStackPointer == StackPANode)
00243 {
00244 assert(StackQAStackPointer == StackQANode);
00245 return NewTree;
00246 }
00247
00248 p = *--StackPAStackPointer;
00249 q = *--StackQAStackPointer;
00250
00251
00252 p = p->m_Right;
00253 q = q->m_Right;
00254 }
00255
00256 escape:
00257
00258 if (p->m_Right)
00259 {
00260 AVLRedBlackNode<Data> *r = new AVLRedBlackNode<Data>(m_DeleteTreeData);
00261 q->m_Right = r;
00262 }
00263
00264
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
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
00296 TravNode->m_Node = m_Root.m_Right;
00297 }
00298
00299 while(true)
00300 {
00301
00302 while (TravNode->m_Node != NULL)
00303 {
00304
00305 TravNode->m_Stack[TravNode->m_TopOfStack++] = TravNode->m_Node;
00306 TravNode->m_Node = TravNode->m_Node->m_Left;
00307 }
00308
00309
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
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
00327
00328
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
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
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
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
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
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
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
00530
00531
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
00571 if (z->m_Left == NULL || z->m_Right == NULL)
00572 {
00573
00574 y = z;
00575
00576
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
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
00601 x = y->m_Right;
00602
00603
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
00611 if (y->m_Color == RED)
00612 {
00613 delete y;
00614 return (Data*)NodeData;
00615 }
00616
00617 delete y;
00618
00619
00620 while (StackPPointer > 1 && (x == NULL || x->m_Color == BLACK))
00621
00622 {
00623 if (StackPDirections[StackPPointer - 1] == SDLEFT)
00624
00625 {
00626 w = StackPNodes[StackPPointer - 1]->m_Right;
00627
00628 if (w->m_Color == RED)
00629
00630 {
00631
00632 w->m_Color = BLACK;
00633
00634 StackPNodes[StackPPointer - 1]->m_Color = RED;
00635
00636 StackPNodes[StackPPointer - 1]->m_Right = w->m_Left;
00637
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
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
00654 {
00655
00656 w->m_Color = RED;
00657
00658 x = StackPNodes[StackPPointer - 1];
00659
00660 StackPPointer--;
00661 }
00662 else
00663 {
00664 if (w->m_Right == NULL || w->m_Right->m_Color == BLACK)
00665
00666 {
00667
00668 w->m_Left->m_Color = BLACK;
00669
00670 w->m_Color = RED;
00671
00672 y = w->m_Left;
00673
00674 w->m_Left = y->m_Right;
00675 y->m_Right = w;
00676 w = StackPNodes[StackPPointer - 1]->m_Right = y;
00677
00678 }
00679
00680
00681 w->m_Color = StackPNodes[StackPPointer - 1]->m_Color;
00682
00683 StackPNodes[StackPPointer - 1]->m_Color = BLACK;
00684
00685 w->m_Right->m_Color = BLACK;
00686
00687 StackPNodes[StackPPointer - 1]->m_Right = w->m_Left;
00688
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
00695 break;
00696 }
00697 }
00698 else
00699 {
00700 w = StackPNodes[StackPPointer - 1]->m_Left;
00701 if (w->m_Color == RED)
00702 {
00703
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
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
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
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
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
00822
00823
00824
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