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
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
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
00288 Node = Tree->m_Root->m_Left;
00289 while (Node->m_Right)
00290 Node = Node->m_Right;
00291 }
00292 else
00293 {
00294
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
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
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
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
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