00001 #ifndef MMANN_CPP_REDBLACK_H
00002 #define MMANN_CPP_REDBLACK_H
00003
00011
00012 #include <stdlib.h>
00013 #include <assert.h>
00014 #include "CompareAlgorithms.h"
00015 #include "RedBlackNode.h"
00016 #include "AGenericTree.h"
00017
00019 enum RedBlackTreeLookup {RBNONE = -1, RBEQUAL = 0, RBGTEQ, RBLTEQ, RBLESS, RBGREAT, RBNEXT, RBPREV, RBFIRST, RBLAST};
00020
00037 template <class Data, class ConfigData>
00038 class RedBlackTree : public AGenericTree<Data, ConfigData>
00039 {
00040 public:
00042 RedBlackTree(ACompareNodesAlgorithm<Data, ConfigData>* Compare, DeleteTreeDataEnum DeleteTreeData = NO_DELETE_TREE_ITEM,
00043 ConfigData* pConfigData = NULL);
00044
00046 ~RedBlackTree();
00047
00053 virtual Data* Search(Data* NodeData, bool* NodeInserted);
00054
00059 virtual Data* Find(Data* NodeData);
00060
00065 Data* Lookup(RedBlackTreeLookup Mode, Data* NodeData);
00066
00071 Data* Delete(Data* NodeData);
00072
00073 protected:
00074
00081 RedBlackNode<Data>* Traverse(bool Insert, Data* NodeData, bool* NodeInserted);
00082
00087 void DeleteNode(RedBlackNode<Data>** Root, RedBlackNode<Data>* Node);
00088
00093 void DeleteNodeFix(RedBlackNode<Data>** Root, RedBlackNode<Data>* Node);
00094
00099 void LeftRotate(RedBlackNode<Data>** Root, RedBlackNode<Data>* x);
00100
00105 void RightRotate(RedBlackNode<Data>** Root, RedBlackNode<Data>* y);
00110 RedBlackNode<Data>* GetSuccessor(const RedBlackNode<Data>* Node);
00111
00116 RedBlackNode<Data>* GetPredecessor(const RedBlackNode<Data>* Node);
00117
00119 RedBlackNode<Data>* m_Root;
00120 };
00121
00122 template <class Data, class ConfigData>
00123 RedBlackTree<Data, ConfigData>::RedBlackTree(ACompareNodesAlgorithm<Data, ConfigData>* Compare, DeleteTreeDataEnum DeleteTreeData,
00124 ConfigData* pConfigData) : AGenericTree<Data, ConfigData>(Compare, DeleteTreeData, pConfigData)
00125 {
00126 m_Root = NULL;
00127 }
00128
00129 template <class Data, class ConfigData>
00130 RedBlackTree<Data, ConfigData>::~RedBlackTree()
00131 {
00132 if (m_Root != NULL)
00133 DeleteAllRedBlackNodes(m_Root, m_DeleteTreeData);
00134 }
00135
00136 template <class Data, class ConfigData>
00137 Data* RedBlackTree<Data, ConfigData>::Search(Data* NodeData, bool* NodeInserted)
00138 {
00139 RedBlackNode<Data>* Node = Traverse(true, NodeData, NodeInserted);
00140
00141 return ((*NodeInserted) ? NULL : Node->m_Data);
00142 }
00143
00144 template <class Data, class ConfigData>
00145 Data* RedBlackTree<Data, ConfigData>::Find(Data* NodeData)
00146 {
00147 RedBlackNode<Data>* x;
00148 bool DummyIsInsert;
00149
00150
00151 if (m_Root == NULL)
00152 return NULL;
00153
00154 x = Traverse(false, NodeData, &DummyIsInsert);
00155
00156 return (x == NULL ? NULL : x->m_Data);
00157 }
00158
00159 template <class Data, class ConfigData>
00160 Data* RedBlackTree<Data, ConfigData>::Lookup(RedBlackTreeLookup Mode, Data* NodeData)
00161 {
00162 if (m_Root == NULL)
00163 return NULL;
00164
00165 RedBlackNode<Data> *x, *y;
00166 int CompareValue;
00167 bool Found = false;
00168
00169 y = NULL;
00170 x = m_Root;
00171
00172 if (Mode == RBFIRST)
00173 {
00174
00175 while (x != NULL)
00176 {
00177 y = x;
00178 x = x->m_Left;
00179 }
00180
00181 return y->m_Data;
00182 }
00183 else if (Mode == RBLAST)
00184 {
00185
00186 while (x != NULL)
00187 {
00188 y = x;
00189 x = x->m_Right;
00190 }
00191
00192 return y->m_Data;
00193 }
00194
00195
00196 while ((x != NULL) && (!Found))
00197 {
00198 y=x;
00199 CompareValue = m_CompareNodes->Compare(NodeData, x->m_Data, m_ConfigData);
00200 if (CompareValue < 0)
00201 x = x->m_Left;
00202 else if (CompareValue > 0)
00203 x = x->m_Right;
00204 else
00205 Found = true;
00206 }
00207
00208 if (Found && (Mode == RBEQUAL || Mode == RBGTEQ || Mode == RBLTEQ))
00209 return x->m_Data;
00210
00211 if (!Found && (Mode == RBEQUAL || Mode == RBNEXT || Mode == RBPREV))
00212 return NULL;
00213
00214 if ((Mode == RBGTEQ) || (!Found && Mode == RBGREAT))
00215 {
00216 if (CompareValue > 0)
00217 return GetSuccessor(y)->m_Data;
00218 else
00219 return y->m_Data;
00220 }
00221
00222 if ((Mode == RBLTEQ) || (!Found && Mode == RBLESS))
00223 {
00224 if (CompareValue < 0)
00225 return GetPredecessor(y)->m_Data;
00226 else
00227 return y->m_Data;
00228 }
00229
00230 if ((Mode == RBNEXT) || (Found && Mode == RBGREAT))
00231 {
00232 RedBlackNode<Data>* Dummy = GetSuccessor(x);
00233 if (Dummy != NULL)
00234 return Dummy->m_Data;
00235 return NULL;
00236 }
00237 if ((Mode == RBPREV) || (Found && Mode == RBLESS))
00238 {
00239 RedBlackNode<Data>* Dummy = GetPredecessor(x);
00240 if (Dummy != NULL)
00241 return Dummy->m_Data;
00242 return NULL;
00243 }
00244
00245
00246 assert(false);
00247 return NULL;
00248 }
00249
00250 template <class Data, class ConfigData>
00251 RedBlackNode<Data>* RedBlackTree<Data, ConfigData>::Traverse(bool Insert, Data* NodeData, bool* NodeInserted)
00252 {
00253 *NodeInserted = false;
00254 RedBlackNode<Data> *x, *y, *z;
00255 int CompareValue;
00256 bool Found = false;
00257
00258 y = NULL;
00259 x = m_Root;
00260
00261
00262 while ((x != NULL) && (!Found))
00263 {
00264 y = x;
00265
00266 CompareValue = m_CompareNodes->Compare(NodeData, x->m_Data, m_ConfigData);
00267
00268 if (CompareValue < 0)
00269 x = x->m_Left;
00270 else if (CompareValue > 0)
00271 x = x->m_Right;
00272 else
00273 Found = true;
00274 }
00275
00276 if (Found || !Insert)
00277 return x;
00278
00279 z = new RedBlackNode<Data>(NodeData);
00280 *NodeInserted = true;
00281 z->m_Up = y;
00282
00283 if (y == NULL)
00284 m_Root = z;
00285 else
00286 {
00287 CompareValue = m_CompareNodes->Compare(z->m_Data, y->m_Data, m_ConfigData);
00288 if (CompareValue < 0)
00289 y->m_Left = z;
00290 else
00291 y->m_Right = z;
00292 }
00293
00294 z->m_Left = NULL;
00295 z->m_Right = NULL;
00296
00297
00298 z->m_Color = RED;
00299
00300
00301
00302 x=z;
00303
00304
00305
00306
00307
00308 while ((x != m_Root) && (x->m_Up->m_Color == RED))
00309 {
00310
00311 if (x->m_Up == x->m_Up->m_Up->m_Left)
00312 {
00313
00314 y = x->m_Up->m_Up->m_Right;
00315 if ((y != NULL) && (y->m_Color == RED))
00316 {
00317
00318 x->m_Up->m_Color = BLACK;
00319
00320 y->m_Color = BLACK;
00321
00322 x->m_Up->m_Up->m_Color = RED;
00323
00324 x = x->m_Up->m_Up;
00325 }
00326 else
00327 {
00328
00329 if (x == x->m_Up->m_Right)
00330 {
00331
00332 x = x->m_Up;
00333 LeftRotate(&m_Root, x);
00334 }
00335
00336
00337 x->m_Up->m_Color = BLACK;
00338
00339 x->m_Up->m_Up->m_Color = RED;
00340
00341 RightRotate(&m_Root, x->m_Up->m_Up);
00342 }
00343 }
00344 else
00345 {
00346
00347 y = x->m_Up->m_Up->m_Left;
00348 if ((y != NULL) && (y->m_Color == RED))
00349 {
00350
00351 x->m_Up->m_Color = BLACK;
00352
00353 y->m_Color = BLACK;
00354
00355 x->m_Up->m_Up->m_Color = RED;
00356
00357 x = x->m_Up->m_Up;
00358 }
00359 else
00360 {
00361
00362 if (x == x->m_Up->m_Left)
00363 {
00364
00365 x = x->m_Up;
00366 RightRotate(&m_Root, x);
00367 }
00368
00369
00370 x->m_Up->m_Color = BLACK;
00371
00372 x->m_Up->m_Up->m_Color = RED;
00373
00374 LeftRotate(&m_Root, x->m_Up->m_Up);
00375 }
00376 }
00377 }
00378
00379
00380 m_Root->m_Color = BLACK;
00381
00382 return z;
00383 }
00384
00385 template <class Data, class ConfigData>
00386 Data* RedBlackTree<Data, ConfigData>::Delete(Data* NodeData)
00387 {
00388 RedBlackNode<Data> *x;
00389 Data* y;
00390 bool DummyIsInsert;
00391
00392 x = Traverse(false, NodeData, &DummyIsInsert);
00393
00394 if (x == NULL)
00395 return NULL;
00396
00397 y = x->m_Data;
00398
00399 DeleteNode(&m_Root, x);
00400
00401 return y;
00402 }
00403
00404 template <class Data, class ConfigData>
00405 void RedBlackTree<Data, ConfigData>::DeleteNode(RedBlackNode<Data>** Root, RedBlackNode<Data>* Node)
00406 {
00407 RedBlackNode<Data> *x,
00408 *y;
00409
00410 if ((Node->m_Left == NULL) || (Node->m_Right == NULL))
00411 y = Node;
00412 else
00413 y = GetSuccessor(Node);
00414
00415 if (y->m_Left != NULL)
00416 x = y->m_Left;
00417 else
00418 x = y->m_Right;
00419
00420 if (x != NULL)
00421 x->m_Up = y->m_Up;
00422
00423 if (y->m_Up == NULL)
00424 {
00425 *Root = x;
00426 }
00427 else
00428 {
00429 if (y == y->m_Up->m_Left)
00430 y->m_Up->m_Left = x;
00431 else
00432 y->m_Up->m_Right = x;
00433 }
00434
00435 if (y != Node)
00436 Node->m_Data = y->m_Data;
00437
00438 if (y->m_Color == BLACK)
00439 DeleteNodeFix(Root, x);
00440
00441 delete y;
00442 }
00443
00444 template <class Data, class ConfigData>
00445 void RedBlackTree<Data, ConfigData>::DeleteNodeFix(RedBlackNode<Data>** Root, RedBlackNode<Data>* Node)
00446 {
00447 RedBlackNode<Data> *w;
00448
00449 while ((Node != *Root) && (Node != NULL) && (Node->m_Color == BLACK))
00450 {
00451 if (Node == Node->m_Up->m_Left)
00452 {
00453 w = Node->m_Up->m_Right;
00454 if (w->m_Color == RED)
00455 {
00456 w->m_Color = BLACK;
00457 Node->m_Up->m_Color = RED;
00458 LeftRotate(Root, Node->m_Up);
00459 w = Node->m_Up->m_Right;
00460 }
00461
00462 if ((w->m_Left->m_Color == BLACK) &&
00463 (w->m_Right->m_Color == BLACK))
00464 {
00465 w->m_Color = RED;
00466 Node = Node->m_Up;
00467 }
00468 else
00469 {
00470 if (w->m_Right->m_Color == BLACK)
00471 {
00472 w->m_Left->m_Color = BLACK;
00473 w->m_Color = RED;
00474 RightRotate(Root, w);
00475 w = Node->m_Up->m_Right;
00476 }
00477
00478 w->m_Color = Node->m_Up->m_Color;
00479 Node->m_Up->m_Color = BLACK;
00480 w->m_Right->m_Color = BLACK;
00481 LeftRotate(Root, Node->m_Up);
00482 Node = *Root;
00483 }
00484
00485 }
00486 else
00487 {
00488 w = Node->m_Up->m_Left;
00489 if (w->m_Color == RED)
00490 {
00491 w->m_Color = BLACK;
00492 Node->m_Up->m_Color = RED;
00493 RightRotate(Root, Node->m_Up);
00494 w = Node->m_Up->m_Left;
00495 }
00496
00497 if ((w->m_Right->m_Color == BLACK) &&
00498 (w->m_Left->m_Color == BLACK))
00499 {
00500 w->m_Color = RED;
00501 Node = Node->m_Up;
00502 }
00503 else
00504 {
00505 if (w->m_Left->m_Color == BLACK)
00506 {
00507 w->m_Right->m_Color = BLACK;
00508 w->m_Color = RED;
00509 LeftRotate(Root, w);
00510 w = Node->m_Up->m_Left;
00511 }
00512
00513 w->m_Color = Node->m_Up->m_Color;
00514 Node->m_Up->m_Color = BLACK;
00515 w->m_Left->m_Color = BLACK;
00516 RightRotate(Root, Node->m_Up);
00517 Node = *Root;
00518 }
00519 }
00520 }
00521
00522 if (Node != NULL)
00523 Node->m_Color = BLACK;
00524 }
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539 template <class Data, class ConfigData>
00540 void RedBlackTree<Data, ConfigData>::LeftRotate(RedBlackNode<Data>** Root, RedBlackNode<Data>* x)
00541 {
00542 RedBlackNode<Data> *y;
00543
00544 assert(x != NULL);
00545 assert(x->m_Right != NULL);
00546
00547 y = x->m_Right;
00548
00549
00550 x->m_Right = y->m_Left;
00551
00552
00553 if (y->m_Left != NULL)
00554 y->m_Left->m_Up = x;
00555
00556
00557 y->m_Up = x->m_Up;
00558
00559
00560 if (x->m_Up == NULL)
00561 {
00562 *Root = y;
00563 }
00564 else
00565 {
00566
00567 if (x == x->m_Up->m_Left)
00568 x->m_Up->m_Left = y;
00569 else
00570 x->m_Up->m_Right = y;
00571 }
00572
00573
00574 y->m_Left = x;
00575
00576
00577 x->m_Up = y;
00578
00579 }
00580
00581 template <class Data, class ConfigData>
00582 void RedBlackTree<Data, ConfigData>::RightRotate(RedBlackNode<Data>** Root, RedBlackNode<Data>* y)
00583 {
00584 RedBlackNode<Data> *x;
00585
00586 assert(y != NULL);
00587 assert(y->m_Left != NULL);
00588
00589 x = y->m_Left;
00590
00591
00592 y->m_Left = x->m_Right;
00593
00594
00595 if (x->m_Right != NULL)
00596 x->m_Right->m_Up = y;
00597
00598
00599 x->m_Up = y->m_Up;
00600
00601
00602 if (y->m_Up == NULL)
00603 {
00604 *Root = x;
00605 }
00606 else
00607 {
00608
00609 if (y == y->m_Up->m_Left)
00610 {
00611 y->m_Up->m_Left = x;
00612 }
00613 else
00614 {
00615 y->m_Up->m_Right = x;
00616 }
00617 }
00618
00619
00620 x->m_Right = y;
00621
00622
00623 y->m_Up = x;
00624 }
00625
00626 template <class Data, class ConfigData>
00627 RedBlackNode<Data>* RedBlackTree<Data, ConfigData>::GetSuccessor(const RedBlackNode<Data>* Node)
00628 {
00629 RedBlackNode<Data> *y;
00630
00631 if (Node->m_Right != NULL)
00632 {
00633
00634
00635 for (y = Node->m_Right; y->m_Left != NULL; y = y->m_Left);
00636 }
00637 else
00638 {
00639
00640
00641 y = Node->m_Up;
00642 while ((y != NULL) && (Node == y->m_Right))
00643 {
00644 Node = y;
00645 y = y->m_Up;
00646 }
00647 }
00648
00649 return y;
00650 }
00651
00652 template <class Data, class ConfigData>
00653 RedBlackNode<Data>* RedBlackTree<Data, ConfigData>::GetPredecessor(const RedBlackNode<Data>* Node)
00654 {
00655 RedBlackNode<Data> *y;
00656
00657 if (Node->m_Left != NULL)
00658 {
00659
00660
00661 for (y = Node->m_Left; y->m_Right != NULL; y = y->m_Right);
00662 }
00663 else
00664 {
00665
00666
00667
00668
00669 y = Node->m_Up;
00670 while ((y != NULL) && (Node == y->m_Left))
00671 {
00672 Node = y;
00673 y = y->m_Up;
00674 }
00675 }
00676
00677 return y;
00678 }
00679
00680 #endif