00001
00002
00003
00004
00005
00006
00007
00008
00043 #ifdef _MSC_VER
00044 #pragma once
00045 #endif
00046
00047
00048 #ifndef OGDF_PQ_TREE_H
00049 #define OGDF_PQ_TREE_H
00050
00051
00052 #include <string.h>
00053
00054 #include <ogdf/basic/Stack.h>
00055 #include <ogdf/basic/Queue.h>
00056 #include <ogdf/basic/Array.h>
00057
00058 #include <ogdf/internal/planarity/PQNode.h>
00059 #include <ogdf/internal/planarity/PQInternalNode.h>
00060 #include <ogdf/internal/planarity/PQLeaf.h>
00061 #include <ogdf/internal/planarity/PQLeafKey.h>
00062 #include <ogdf/internal/planarity/PQInternalKey.h>
00063 #include <ogdf/internal/planarity/PQNodeKey.h>
00064
00065
00066 namespace ogdf {
00067
00068
00069 template<class T,class X,class Y>
00070
00071 class PQTree
00072 {
00073 public:
00074
00075 PQTree();
00076
00085 virtual ~PQTree() { Cleanup(); }
00086
00087 bool addNewLeavesToTree(
00088 PQInternalNode<T,X,Y> *father,
00089 SListPure<PQLeafKey<T,X,Y>*> &leafKeys);
00090
00091 void emptyNode(PQNode<T,X,Y>* nodePtr);
00092
00093 virtual void front(
00094 PQNode<T,X,Y>* nodePtr,
00095 SListPure<PQLeafKey<T,X,Y>*> &leafKeys);
00096
00097 virtual void CleanNode(PQNode<T,X,Y>* ) { }
00098
00099 virtual void Cleanup();
00100
00107 virtual void clientDefinedEmptyNode(PQNode<T,X,Y>* nodePtr) {
00108 emptyNode(nodePtr);
00109 }
00110
00111 virtual void emptyAllPertinentNodes();
00112
00113 virtual int Initialize(SListPure<PQLeafKey<T,X,Y>*> &leafKeys);
00114
00115 virtual bool Reduction(SListPure<PQLeafKey<T,X,Y>*> &leafKeys);
00116
00120 PQNode<T,X,Y>* root() const {
00121 return m_root;
00122 }
00123
00124 void writeGML(const char *fileName);
00125 void writeGML(ostream &os);
00126
00127
00128 protected:
00129
00130
00132 PQNode<T,X,Y>* m_root;
00133
00135 PQNode<T,X,Y>* m_pertinentRoot;
00136
00138 PQNode<T,X,Y>* m_pseudoRoot;
00139
00141
00145 int m_identificationNumber;
00146
00148 int m_numberOfLeaves;
00149
00158 List<PQNode<T,X,Y>*> *m_pertinentNodes;
00159
00160
00161 virtual bool Bubble(SListPure<PQLeafKey<T,X,Y>*> &leafKeys);
00162
00163 virtual bool Reduce(SListPure<PQLeafKey<T,X,Y>*> &leafKeys);
00164
00165 virtual bool templateL1(PQNode<T,X,Y> *nodePtr,
00166 bool isRoot);
00167
00168 virtual bool templateP1(PQNode<T,X,Y> *nodePtr,
00169 bool isRoot);
00170
00171 virtual bool templateP2(PQNode<T,X,Y> **nodePtr);
00172
00173 virtual bool templateP3(PQNode<T,X,Y> *nodePtr);
00174
00175 virtual bool templateP4(PQNode<T,X,Y> **nodePtr);
00176
00177 virtual bool templateP5(PQNode<T,X,Y> *nodePtr);
00178
00179 virtual bool templateP6(PQNode<T,X,Y> **nodePtr);
00180
00181 virtual bool templateQ1(PQNode<T,X,Y> *nodePtr, bool isRoot);
00182
00183 virtual bool templateQ2(PQNode<T,X,Y> *nodePtr, bool isRoot);
00184
00185 virtual bool templateQ3(PQNode<T,X,Y> *nodePtr);
00186
00187
00188
00189 virtual bool addNodeToNewParent(PQNode<T,X,Y>* parent,
00190 PQNode<T,X,Y>* child);
00191
00192 virtual bool addNodeToNewParent(PQNode<T,X,Y>* parent,
00193 PQNode<T,X,Y>* child,
00194 PQNode<T,X,Y>* leftBrother,
00195 PQNode<T,X,Y>* rightBrother);
00196
00197 virtual bool checkIfOnlyChild(PQNode<T,X,Y> *child,
00198 PQNode<T,X,Y> *parent);
00199
00205 virtual void destroyNode(PQNode<T,X,Y> *nodePtr) {
00206 nodePtr->status(TO_BE_DELETED);
00207 }
00208
00209 virtual void exchangeNodes(PQNode<T,X,Y> *oldNode,
00210 PQNode<T,X,Y> *newNode);
00211
00212 virtual void linkChildrenOfQnode(PQNode<T,X,Y> *installed,
00213 PQNode<T,X,Y> *newChild);
00214
00215 virtual void removeChildFromSiblings(PQNode<T,X,Y>* nodePtr);
00216
00217 virtual int removeNodeFromTree(PQNode<T,X,Y>* parent,
00218 PQNode<T,X,Y>* child);
00219
00220
00221 List<PQNode<T,X,Y>*>* fullChildren(PQNode<T,X,Y>* nodePtr) {
00222 return nodePtr->fullChildren;
00223 }
00224
00225
00226 List<PQNode<T,X,Y>*>* partialChildren(PQNode<T,X,Y>* nodePtr) {
00227 return nodePtr->partialChildren;
00228 }
00229
00230 virtual PQNode<T,X,Y>* clientLeftEndmost(PQNode<T,X,Y>* nodePtr) const {
00231 return nodePtr->m_leftEndmost;
00232 }
00233
00234 virtual PQNode<T,X,Y>* clientRightEndmost(PQNode<T,X,Y>* nodePtr) const {
00235 return nodePtr->m_rightEndmost;
00236 }
00237
00238 virtual PQNode<T,X,Y>* clientNextSib(PQNode<T,X,Y>* nodePtr,
00239 PQNode<T,X,Y>* other) const {
00240 return nodePtr->getNextSib(other);
00241 }
00242
00243 virtual PQNode<T,X,Y>* clientSibLeft(PQNode<T,X,Y>* nodePtr) const {
00244 return nodePtr->m_sibLeft;
00245 }
00246
00247 virtual PQNode<T,X,Y>* clientSibRight(PQNode<T,X,Y>* nodePtr) const {
00248 return nodePtr->m_sibRight;
00249 }
00250
00251 virtual int clientPrintNodeCategorie(PQNode<T,X,Y>* nodePtr);
00252
00253 virtual const char* clientPrintStatus(PQNode<T,X,Y>* nodePtr);
00254
00255 virtual const char* clientPrintType(PQNode<T,X,Y>* nodePtr);
00256
00257 private:
00258
00259 bool checkChain(
00260 PQNode<T,X,Y> *nodePtr,
00261 PQNode<T,X,Y> *firstFull,
00262 PQNode<T,X,Y> **seqStart,
00263 PQNode<T,X,Y> **seqEnd);
00264
00265 void copyFullChildrenToPartial(
00266 PQNode<T,X,Y> *nodePtr,
00267 PQNode<T,X,Y> *partialChild);
00268
00269 PQNode<T,X,Y>* createNodeAndCopyFullChildren(List<PQNode<T,X,Y>*> *fullNodes);
00270
00271 void printNode(
00272 char *filename,
00273 int number,
00274 PQNode<T,X,Y>* father,
00275 PQNode<T,X,Y>* son);
00276
00277 void removeBlock(PQNode<T,X,Y> *nodePtr, bool isRoot);
00278
00279 void sortExceptions(int Exceptions[], int arraySize);
00280 };
00281
00282
00283
00284
00285
00286
00287
00304 template<class T,class X,class Y>
00305 bool PQTree<T,X,Y>::addNewLeavesToTree(
00306 PQInternalNode<T,X,Y> *father,
00307 SListPure<PQLeafKey<T,X,Y>*> &leafKeys)
00308 {
00309 if (!leafKeys.empty())
00310 {
00311 OGDF_ASSERT(!father->m_childCount)
00312
00313
00314
00315 SListIterator<PQLeafKey<T,X,Y>*> it = leafKeys.begin();
00316 PQLeafKey<T,X,Y>* newKey = *it;
00317
00318 PQNode<T,X,Y>* aktualSon = OGDF_NEW PQLeaf<T,X,Y>(m_identificationNumber++,EMPTY,newKey);
00319 PQNode<T,X,Y>* firstSon = aktualSon;
00320 firstSon->m_parent = father;
00321 firstSon->m_parentType = father->type();
00322 father->m_childCount++;
00323 PQNode<T,X,Y>* oldSon = firstSon;
00324
00326 for (++it; it.valid(); ++it)
00327 {
00328 newKey = *it;
00329 aktualSon = OGDF_NEW PQLeaf<T,X,Y>(m_identificationNumber++,
00330 EMPTY,newKey);
00331 aktualSon->m_parent = father;
00332 aktualSon->m_parentType = father->type();
00333 father->m_childCount++;
00334 oldSon->m_sibRight = aktualSon;
00335 aktualSon->m_sibLeft = oldSon;
00336 oldSon = aktualSon;
00337 }
00338 if (father->type() == PQNodeRoot::PNode)
00340 {
00341 firstSon->m_sibLeft = oldSon;
00342 oldSon->m_sibRight = firstSon;
00343 father->m_referenceChild = firstSon;
00344 firstSon->m_referenceParent = father;
00345 }
00346 else if (father->type() == PQNodeRoot::QNode)
00348 {
00349 father->m_leftEndmost = firstSon;
00350 father->m_rightEndmost = oldSon;
00351 }
00352 return true;
00353 }
00354
00355 return false;
00356 }
00357
00358
00359
00360
00361
00362
00363
00380 template<class T,class X,class Y>
00381 bool PQTree<T,X,Y>::addNodeToNewParent(
00382 PQNode<T,X,Y>* parent,
00383 PQNode<T,X,Y>* child)
00384 {
00385 OGDF_ASSERT(parent->type() == PQNodeRoot::PNode && parent->type() == PQNodeRoot::QNode)
00386
00387
00388 if (child != 0)
00389 {
00390 OGDF_ASSERT(parent->m_childCount == 0)
00391
00392 child->m_parent = parent;
00393 child->m_parentType = parent->type();
00394 parent->m_childCount++;
00395
00396
00397
00398
00399
00400
00401
00402 if (parent->type() == PQNodeRoot::PNode)
00403 {
00404 child->m_sibLeft = child;
00405 child->m_sibRight = child;
00406 parent->m_referenceChild = child;
00407 child->m_referenceParent = parent;
00408 }
00409 else if (parent->type() == PQNodeRoot::QNode)
00410 {
00411 parent->m_leftEndmost = child;
00412 parent->m_rightEndmost = child;
00413 }
00414
00415 return true;
00416 }
00417
00418 return false;
00419 }
00420
00421
00422
00423
00424
00425
00460 template<class T,class X,class Y>
00461 bool PQTree<T,X,Y>::addNodeToNewParent(
00462 PQNode<T,X,Y>* parent,
00463 PQNode<T,X,Y>* child,
00464 PQNode<T,X,Y>* leftBrother,
00465 PQNode<T,X,Y>* rightBrother)
00466 {
00467
00468 if (parent != 0)
00469 {
00470 OGDF_ASSERT(parent->type() == PQNodeRoot::PNode || parent->type() == PQNodeRoot::QNode)
00471
00472 if ((leftBrother == 0) && (rightBrother == 0))
00473 return addNodeToNewParent(parent,child);
00474 else if (child != 0)
00475 {
00476 child->m_parent = parent;
00477 child->m_parentType = parent->type();
00478 parent->m_childCount++;
00479
00480 if (parent->type() == PQNodeRoot::PNode)
00481 {
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491 PQNode<T,X,Y>* brother = (leftBrother != 0) ? leftBrother : rightBrother;
00492 PQNode<T,X,Y>* sister = brother->m_sibRight;
00493 child->m_sibLeft = brother;
00494 child->m_sibRight = sister;
00495 brother->m_sibRight = child;
00496 sister->m_sibLeft = child;
00497 return true;
00498 }
00499
00500 else if (leftBrother == 0)
00501 {
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515 if (rightBrother == parent->m_leftEndmost)
00516 {
00517 parent->m_leftEndmost = child;
00518 child->m_sibRight = rightBrother;
00519 rightBrother->putSibling(child,LEFT);
00520 return true;
00521 }
00522
00523
00524 OGDF_ASSERT(rightBrother == parent->m_rightEndmost);
00525 parent->m_rightEndmost = child;
00526 child->m_sibLeft = rightBrother;
00527 rightBrother->putSibling(child,LEFT);
00528 return true;
00529 }
00530
00531 else if (rightBrother == 0)
00532 {
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546 if (leftBrother == parent->m_rightEndmost)
00547 {
00548 parent->m_rightEndmost = child;
00549 child->m_sibLeft = leftBrother;
00550 leftBrother->putSibling(child,RIGHT);
00551 return true;
00552 }
00553
00554
00555 OGDF_ASSERT(leftBrother == parent->m_leftEndmost);
00556 parent->m_leftEndmost = child;
00557 child->m_sibRight = leftBrother;
00558 leftBrother->putSibling(child,RIGHT);
00559 return true;
00560 }
00561
00562 else
00563 {
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580 #ifdef OGDF_DEBUG
00581 bool ok =
00582 #endif
00583 rightBrother->changeSiblings(leftBrother,child) && leftBrother->changeSiblings(rightBrother,child);
00584
00585
00586 OGDF_ASSERT(ok);
00587
00588 if (leftBrother->m_sibRight == child)
00589 {
00590 child->m_sibLeft = leftBrother;
00591 child->m_sibRight = rightBrother;
00592 }
00593 else
00594 {
00595 child->m_sibLeft = rightBrother;
00596 child->m_sibRight = leftBrother;
00597 }
00598 return true;
00599 }
00600 }
00601 else
00602 return false;
00603 }
00604 else if (leftBrother != 0 && rightBrother != 0)
00605 {
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622 #ifdef OGDF_DEBUG
00623 bool ok =
00624 #endif
00625 rightBrother->changeSiblings(leftBrother,child) && leftBrother->changeSiblings(rightBrother,child);
00626
00627
00628 OGDF_ASSERT(ok);
00629
00630 if (leftBrother->m_sibRight == child)
00631 {
00632 child->m_sibLeft = leftBrother;
00633 child->m_sibRight = rightBrother;
00634 }
00635 else
00636 {
00637 child->m_sibLeft = rightBrother;
00638 child->m_sibRight = leftBrother;
00639 }
00640 return true;
00641 }
00642
00643 return true;
00644 }
00645
00646
00647
00648
00649
00650
00651
00686 template<class T,class X,class Y>
00687 bool PQTree<T,X,Y>::Bubble(SListPure<PQLeafKey<T,X,Y>*> &leafKeys)
00688 {
00689 Queue<PQNode<T,X,Y>*> processNodes;
00690
00691
00692
00693
00694
00695
00696
00697
00698 SListIterator<PQLeafKey<T,X,Y>*> it;
00699 for (it = leafKeys.begin(); it.valid(); ++it)
00700 {
00701 PQNode<T,X,Y>* checkLeaf = (*it)->nodePointer();
00702 checkLeaf->mark(QUEUED);
00703 processNodes.append(checkLeaf);
00704 m_pertinentNodes->pushFront(checkLeaf);
00705 }
00706
00707 int blockCount = 0;
00708 int numBlocked = 0;
00709 int offTheTop = 0;
00710 int blockedSiblings = 0;
00711 PQNode<T,X,Y>* checkSib = 0;
00712 Stack<PQNode<T,X,Y>*> blockedNodes;
00713
00714 while ((processNodes.size() + blockCount + offTheTop) > 1)
00715 {
00716 if (processNodes.size() == 0)
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730 return false;
00731
00732
00733
00734
00735
00736 PQNode<T,X,Y>* checkNode = processNodes.pop();
00737 blockedNodes.push(checkNode);
00738 checkNode->mark(BLOCKED);
00739 blockedSiblings = 0;
00740
00741
00742
00743
00744
00745
00746
00747
00748 if ((checkNode->m_parentType != PQNodeRoot::PNode) && (checkNode != m_root))
00749
00750
00751 {
00752 if (clientSibLeft(checkNode) == 0)
00753
00754
00755
00756 {
00757 checkNode->mark(UNBLOCKED);
00758 if (clientSibRight(checkNode) &&
00759 clientSibRight(checkNode)->mark() == BLOCKED)
00760 blockedSiblings++;
00761 }
00762
00763 else if (clientSibRight(checkNode) == 0)
00764
00765
00766
00767 {
00768 checkNode->mark(UNBLOCKED);
00769 if (clientSibLeft(checkNode) &&
00770 clientSibLeft(checkNode)->mark() == BLOCKED)
00771 blockedSiblings++;
00772 }
00773
00774
00775 else
00776
00777
00778
00779 {
00780 if (clientSibLeft(checkNode)->mark() == UNBLOCKED)
00781
00782
00783 {
00784 checkNode->mark(UNBLOCKED);
00785 checkNode->m_parent = clientSibLeft(checkNode)->m_parent;
00786 }
00787 else if (clientSibLeft(checkNode)->mark() == BLOCKED)
00788 blockedSiblings++;
00789
00790 if (clientSibRight(checkNode)->mark() == UNBLOCKED)
00791
00792
00793 {
00794 checkNode->mark(UNBLOCKED);
00795 checkNode->m_parent = clientSibRight(checkNode)->m_parent;
00796 }
00797 else if (clientSibRight(checkNode)->mark() == BLOCKED)
00798 blockedSiblings++;
00799 }
00800 }
00801
00802 else
00803
00804
00805 checkNode->mark(UNBLOCKED);
00806
00807 if (checkNode->mark() == UNBLOCKED)
00808 {
00809 PQNode<T,X,Y>* parent = checkNode->m_parent;
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829 if (blockedSiblings > 0)
00830 {
00831 if (clientSibLeft(checkNode) != 0)
00832 {
00833 checkSib = clientSibLeft(checkNode);
00834 PQNode<T,X,Y>* oldSib = checkNode;
00835 while (checkSib->mark() == BLOCKED)
00836 {
00837 checkSib->mark(UNBLOCKED);
00838 checkSib->m_parent = parent;
00839 numBlocked--;
00840 parent->m_pertChildCount++;
00841 PQNode<T,X,Y>* holdSib = clientNextSib(checkSib,oldSib);
00842 oldSib = checkSib;
00843 checkSib = holdSib;
00844
00845 }
00846 }
00847
00848 if (clientSibRight(checkNode) != 0)
00849 {
00850 checkSib = clientSibRight(checkNode);
00851 PQNode<T,X,Y>* oldSib = checkNode;
00852 while (checkSib->mark() == BLOCKED)
00853 {
00854 checkSib->mark(UNBLOCKED);
00855 checkSib->m_parent = parent;
00856 numBlocked--;
00857 parent->m_pertChildCount++;
00858 PQNode<T,X,Y>* holdSib = clientNextSib(checkSib,oldSib);
00859 oldSib = checkSib;
00860 checkSib = holdSib;
00861
00862 }
00863 }
00864 }
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882 if (parent == 0)
00883
00884 offTheTop = 1;
00885 else
00886
00887 {
00888 parent->m_pertChildCount++;
00889 if (parent->mark() == UNMARKED)
00890 {
00891 processNodes.append(parent);
00892 m_pertinentNodes->pushFront(parent);
00893 parent->mark(QUEUED);
00894 }
00895 }
00896
00897 blockCount -= blockedSiblings;
00898 blockedSiblings = 0;
00899
00900 }
00901
00902 else
00903 {
00904
00905
00906
00907
00908
00909
00910
00911 blockCount += 1 - blockedSiblings;
00912 numBlocked++;
00913 }
00914
00915 }
00916
00917 if (blockCount == 1)
00918 {
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937 while (!blockedNodes.empty())
00938 {
00939 PQNode<T,X,Y>* checkNode = blockedNodes.pop();
00940 if (checkNode->mark() == BLOCKED)
00941 {
00942 checkNode->mark(UNBLOCKED);
00943 checkNode->m_parent = m_pseudoRoot;
00944 m_pseudoRoot->m_pertChildCount++;
00945 OGDF_ASSERT(!checkNode->endmostChild())
00946
00947 }
00948 }
00949 }
00950
00951 return true;
00952 }
00953
00954
00955
00956
00957
00958
01003 template<class T,class X,class Y>
01004 bool PQTree<T,X,Y>::checkChain(
01005 PQNode<T,X,Y> *nodePtr,
01006 PQNode<T,X,Y> *firstFull,
01007 PQNode<T,X,Y> **seqStart,
01008 PQNode<T,X,Y> **seqEnd)
01009 {
01010 bool notFull = false;
01011 int fullCount = nodePtr->fullChildren->size();
01012 fullCount--;
01013
01014
01015
01016
01017
01018
01019 PQNode<T,X,Y> *leftNext = clientSibLeft(firstFull);
01020 (*seqEnd) = firstFull;
01021 if (leftNext != 0)
01022 {
01023 if (leftNext->status() == FULL) {
01024 fullCount--;
01025
01026 PQNode<T,X,Y> *leftOld = firstFull;
01027 PQNode<T,X,Y> *checkNode = leftNext;
01028
01029 while (fullCount > 0 && !notFull)
01030
01031
01032
01033 {
01034 leftNext = clientNextSib(checkNode,leftOld);
01035 if (leftNext != 0 && leftNext->status() == FULL)
01036 fullCount--;
01037 else
01038 notFull = true;
01039 leftOld = checkNode;
01040 checkNode = leftNext;
01041 }
01042
01043 if (checkNode != 0 && checkNode->status() == FULL)
01044 (*seqEnd) = checkNode;
01045
01046 else {
01047
01048 OGDF_ASSERT(leftOld != 0 && leftOld->status() == FULL);
01049 (*seqEnd) = leftOld;
01050 }
01051
01052 } else {
01053 (*seqEnd) = firstFull;
01054 }
01055 }
01056
01057
01058
01059
01060
01061
01062 notFull = false;
01063 PQNode<T,X,Y> *rightNext = clientSibRight(firstFull);
01064 (*seqStart) = firstFull;
01065 if(rightNext != 0)
01066 {
01067 if (rightNext->status() == FULL) {
01068 fullCount--;
01069
01070 PQNode<T,X,Y> *rightOld = firstFull;
01071 PQNode<T,X,Y> *checkNode = rightNext;
01072
01073 while (fullCount > 0 && !notFull)
01074
01075
01076
01077 {
01078 rightNext = clientNextSib(checkNode,rightOld);
01079 if (rightNext != 0 && rightNext->status() == FULL)
01080 fullCount--;
01081 else
01082 notFull = true;
01083 rightOld = checkNode;
01084 checkNode = rightNext;
01085 }
01086 if (checkNode != 0 && checkNode->status() == FULL)
01087 (*seqStart) = checkNode;
01088
01089 else {
01090 OGDF_ASSERT(rightOld != 0 && rightOld->status() == FULL);
01091 (*seqStart) = rightOld;
01092
01093 }
01094
01095 } else {
01096 (*seqStart) = firstFull;
01097 }
01098 }
01099
01100
01101
01102 if (firstFull == (*seqEnd))
01103 {
01104 PQNode<T,X,Y> *checkNode = (*seqEnd);
01105 (*seqEnd) = (*seqStart);
01106 (*seqStart) = checkNode;
01107 }
01108
01109 if (fullCount == 0)
01110
01111
01112 return true;
01113 else
01114 return false;
01115 }
01116
01117
01118
01119
01120
01121
01137 template<class T,class X,class Y>
01138 bool PQTree<T,X,Y>::checkIfOnlyChild(
01139 PQNode<T,X,Y> *child,
01140 PQNode<T,X,Y> *parent)
01141
01142 {
01143 if ((parent->type() == PQNodeRoot::PNode && parent->m_childCount == 1)
01144 || (parent->type() == PQNodeRoot::QNode && parent->m_leftEndmost == child
01145 && parent->m_rightEndmost == child))
01146 {
01147 removeChildFromSiblings(child);
01148 child->m_parent = parent->m_parent;
01149 if (parent->m_parent != 0)
01150 exchangeNodes(parent,child);
01151 else
01152 {
01153 exchangeNodes(parent,child);
01154 m_root = child;
01155 }
01156 destroyNode(parent);
01157 return true;
01158 }
01159 else
01160 return false;
01161 }
01162
01163
01164
01165
01166
01167
01200 template<class T,class X,class Y>
01201 void PQTree<T,X,Y>::Cleanup()
01202 {
01203 PQNode<T,X,Y>* nextSon = 0;
01204 PQNode<T,X,Y>* lastSon = 0;
01205 PQNode<T,X,Y>* oldSib = 0;
01206
01207 Queue<PQNode<T,X,Y>*> helpqueue;
01208
01209 if (m_root != 0)
01210 {
01211 emptyAllPertinentNodes();
01212
01213
01214
01215
01216
01217 if (m_root->type() == PQNodeRoot::PNode)
01218 {
01219 if (m_root->m_referenceChild != 0)
01220 {
01221 PQNode<T,X,Y>* firstSon = m_root->m_referenceChild;
01222 helpqueue.append(firstSon);
01223
01224 if (firstSon->m_sibRight != 0)
01225 nextSon = firstSon->m_sibRight;
01226 while (nextSon != firstSon)
01227 {
01228 helpqueue.append(nextSon);
01229 nextSon = nextSon->m_sibRight;
01230 }
01231 }
01232 }
01233 else if (m_root->type() == PQNodeRoot::QNode)
01234 {
01235 PQNode<T,X,Y>* firstSon = m_root->m_leftEndmost;
01236 helpqueue.append(firstSon);
01237
01238 lastSon = m_root->m_rightEndmost;
01239 helpqueue.append(lastSon);
01240
01241 nextSon = lastSon->getNextSib(oldSib);
01242 oldSib = lastSon;
01243 while (nextSon != firstSon)
01244 {
01245 helpqueue.append(nextSon);
01246 PQNode<T,X,Y>* holdSib = nextSon->getNextSib(oldSib);
01247 oldSib = nextSon;
01248 nextSon = holdSib;
01249 }
01250 }
01251
01252
01253 CleanNode(m_root);
01254 delete m_root;
01255
01256 while (!helpqueue.empty())
01257 {
01258 PQNode<T,X,Y>* checkNode = helpqueue.pop();
01259
01260
01261
01262
01263
01264
01265 if (checkNode->type() == PQNodeRoot::PNode)
01266 {
01267 if (checkNode->m_referenceChild != 0)
01268 {
01269 PQNode<T,X,Y>* firstSon = checkNode->m_referenceChild;
01270 helpqueue.append(firstSon);
01271
01272 if (firstSon->m_sibRight != 0)
01273 nextSon = firstSon->m_sibRight;
01274 while (nextSon != firstSon)
01275 {
01276 helpqueue.append(nextSon);
01277 nextSon = nextSon->m_sibRight;
01278 }
01279 }
01280 }
01281 else if (checkNode->type() == PQNodeRoot::QNode)
01282 {
01283 oldSib = 0;
01284
01285 PQNode<T,X,Y>*firstSon = checkNode->m_leftEndmost;
01286 helpqueue.append(firstSon);
01287
01288 lastSon = checkNode->m_rightEndmost;
01289 helpqueue.append(lastSon);
01290
01291 nextSon = lastSon->getNextSib(oldSib);
01292 oldSib = lastSon;
01293 while (nextSon != firstSon)
01294 {
01295 helpqueue.append(nextSon);
01296 PQNode<T,X,Y>* holdSib = nextSon->getNextSib(oldSib);
01297 oldSib = nextSon;
01298 nextSon = holdSib;
01299 }
01300 }
01301
01302 CleanNode(checkNode);
01303 delete checkNode;
01304 }
01305 }
01306
01307 CleanNode(m_pseudoRoot);
01308 delete m_pseudoRoot;
01309
01310 delete m_pertinentNodes;
01311
01312 m_root = 0;
01313 m_pertinentRoot = 0;
01314 m_pseudoRoot = 0;
01315 m_pertinentNodes = 0;
01316
01317 m_numberOfLeaves = 0;
01318 m_identificationNumber = 0;
01319 }
01320
01321
01322
01323
01324
01325
01336 template<class T,class X,class Y>
01337 int PQTree<T,X,Y>::clientPrintNodeCategorie(PQNode<T,X,Y>* nodePtr)
01338 {
01339 return (nodePtr != 0) ? 1 : 0;
01340
01341 }
01342
01343
01344
01345
01346
01347
01358 template<class T,class X,class Y>
01359 const char* PQTree<T,X,Y>::clientPrintStatus(PQNode<T,X,Y>* nodePtr)
01360 {
01361 return (nodePtr != 0) ? "ERROR" : "ERROR: clientPrintStatus: NO NODE ACCESSED";
01362 }
01363
01364
01365
01366
01367
01368
01379 template<class T,class X,class Y>
01380 const char* PQTree<T,X,Y>::clientPrintType(PQNode<T,X,Y>* nodePtr)
01381 {
01382 return (nodePtr != 0) ? "ERROR" : "ERROR: clientPrintType: NO NODE ACCESSED";
01383 }
01384
01385
01386
01387
01388
01389
01390
01391 template<class T,class X,class Y> PQTree<T,X,Y>::PQTree()
01392 {
01393 m_root = 0;
01394 m_pertinentRoot = 0;
01395 m_pseudoRoot = 0;
01396
01397 m_numberOfLeaves = 0;
01398 m_identificationNumber = 0;
01399
01400 m_pertinentNodes = 0;
01401 }
01402
01403
01404
01405
01406
01407
01408
01424 template<class T,class X,class Y>
01425 void PQTree<T,X,Y>::copyFullChildrenToPartial(PQNode<T,X,Y> *nodePtr,
01426 PQNode<T,X,Y> *partialChild)
01427 {
01428 if (nodePtr->fullChildren->size() > 0)
01429
01430
01431 {
01432 nodePtr->m_childCount = nodePtr->m_childCount -
01433 nodePtr->fullChildren->size();
01434
01435 PQNode<T,X,Y> *newNode = createNodeAndCopyFullChildren(nodePtr->fullChildren);
01436
01437
01438
01439 partialChild->m_childCount++;
01440 partialChild->fullChildren->pushFront(newNode);
01441
01442 if (clientLeftEndmost(partialChild)->status() == FULL)
01443 {
01444 PQNode<T,X,Y> *checkNode = partialChild->m_leftEndmost;
01445 partialChild->m_leftEndmost = newNode;
01446 linkChildrenOfQnode(checkNode,newNode);
01447
01448 }
01449 else {
01450
01451 OGDF_ASSERT(clientRightEndmost(partialChild)->status() == FULL);
01452
01453 PQNode<T,X,Y> *checkNode = partialChild->m_rightEndmost;
01454 partialChild->m_rightEndmost = newNode;
01455 linkChildrenOfQnode(checkNode,newNode);
01456 }
01457
01458 newNode->m_parent = partialChild;
01459 newNode->m_parentType = PQNodeRoot::QNode;
01460 }
01461 }
01462
01463
01464
01465
01466
01467
01493 template<class T,class X,class Y>
01494 PQNode<T,X,Y>* PQTree<T,X,Y>::createNodeAndCopyFullChildren(
01495 List<PQNode<T,X,Y>*> *fullNodes)
01496 {
01497 PQNode<T,X,Y> *newNode = 0;
01498
01499 if (fullNodes->size() == 1)
01500 {
01501
01502
01503
01504
01505 newNode = fullNodes->popFrontRet();
01506 removeChildFromSiblings(newNode);
01507 }
01508
01509 else
01510 {
01511
01512
01513
01514
01515
01516
01517
01518
01519
01520
01521 newNode = OGDF_NEW PQInternalNode<T,X,Y>(m_identificationNumber++,PQNodeRoot::PNode,FULL);
01522 m_pertinentNodes->pushFront(newNode);
01523 newNode->m_pertChildCount = fullNodes->size();
01524 newNode->m_childCount = fullNodes->size();
01525
01526
01527
01528
01529
01530 PQNode<T,X,Y> *firstSon = fullNodes->popFrontRet();
01531 removeChildFromSiblings(firstSon);
01532 newNode->fullChildren->pushFront(firstSon);
01533 firstSon->m_parent = newNode;
01534 firstSon->m_parentType = newNode->type();
01535 PQNode<T,X,Y> *oldSon = firstSon;
01536
01537
01538
01539
01540
01541
01542
01543
01544
01545 while (!fullNodes->empty())
01546 {
01547 PQNode<T,X,Y> *checkSon = fullNodes->popFrontRet();
01548 removeChildFromSiblings(checkSon);
01549 newNode->fullChildren->pushFront(checkSon);
01550 oldSon->m_sibRight = checkSon;
01551 checkSon->m_sibLeft = oldSon;
01552 checkSon->m_parent = newNode;
01553 checkSon->m_parentType = newNode->type();
01554 oldSon = checkSon;
01555 }
01556 firstSon->m_sibLeft = oldSon;
01557 oldSon->m_sibRight = firstSon;
01558 newNode->m_referenceChild = firstSon;
01559 firstSon->m_referenceParent = newNode;
01560 }
01561
01562 return newNode;
01563 }
01564
01565
01566
01567
01568
01569
01579 template<class T,class X,class Y>
01580 void PQTree<T,X,Y>::emptyAllPertinentNodes()
01581 {
01582 PQNode<T,X,Y> *nodePtr;
01583
01584 while(!m_pertinentNodes->empty())
01585 {
01586 nodePtr = m_pertinentNodes->popFrontRet();
01587 switch (nodePtr->status())
01588 {
01589 case TO_BE_DELETED:
01590 if (nodePtr == m_root)
01591 m_root = 0;
01592 CleanNode(nodePtr);
01593
01594 delete nodePtr;
01595 break;
01596
01597 case FULL:
01598 emptyNode(nodePtr);
01599 break;
01600
01601 case PARTIAL:
01602 emptyNode(nodePtr);
01603 break;
01604
01605 default:
01606 clientDefinedEmptyNode(nodePtr);
01607 break;
01608 }
01609 }
01610 m_pseudoRoot->m_pertChildCount = 0;
01611 m_pseudoRoot->m_pertLeafCount = 0;
01612 m_pseudoRoot->fullChildren->clear();
01613 m_pseudoRoot->partialChildren->clear();
01614 m_pseudoRoot->status(EMPTY);
01615 m_pseudoRoot->mark(UNMARKED);
01616 }
01617
01618
01619
01620
01621
01622
01628 template<class T,class X,class Y>
01629 void PQTree<T,X,Y>::emptyNode(PQNode<T,X,Y> *nodePtr)
01630 {
01631 nodePtr->status(EMPTY);
01632 nodePtr->m_pertChildCount = 0;
01633 nodePtr->m_pertLeafCount = 0;
01634 nodePtr->fullChildren->clear();
01635 nodePtr->partialChildren->clear();
01636 nodePtr->mark(UNMARKED);
01637 }
01638
01639
01640
01641
01642
01643
01659 template<class T,class X,class Y>
01660 void PQTree<T,X,Y>::exchangeNodes(
01661 PQNode<T,X,Y> *oldNode,
01662 PQNode<T,X,Y> *newNode)
01663 {
01664 if (oldNode->m_referenceParent != 0)
01665 {
01666
01667
01668
01669
01670
01671
01672 oldNode->m_referenceParent->m_referenceChild = newNode;
01673 newNode->m_referenceParent = oldNode->m_referenceParent;
01674 oldNode->m_referenceParent = 0;
01675 }
01676
01677 else if (oldNode->endmostChild())
01678 {
01679
01680
01681
01682
01683
01684
01685 if (oldNode->m_parent->m_leftEndmost == oldNode)
01686 oldNode->m_parent->m_leftEndmost = newNode;
01687 else if (oldNode->m_parent->m_rightEndmost == oldNode)
01688 oldNode->m_parent->m_rightEndmost = newNode;
01689 }
01690
01691 if ((oldNode->m_sibLeft == oldNode) && (oldNode->m_sibRight == oldNode))
01692 {
01693
01694
01695
01696
01697
01698
01699
01700
01701
01702
01703
01704
01705
01706 oldNode->m_sibLeft = 0;
01707 oldNode->m_sibRight = 0;
01708 if (oldNode->m_parent == 0)
01709 {
01710 newNode->m_sibLeft = newNode;
01711 newNode->m_sibRight = newNode;
01712 }
01713 else
01714 {
01715 newNode->m_sibLeft = newNode;
01716 newNode->m_sibRight = newNode;
01717 }
01718 }
01719 else
01720 {
01721 OGDF_ASSERT(!(oldNode->m_sibLeft == oldNode))
01722
01723 OGDF_ASSERT(!(oldNode->m_sibRight == oldNode))
01724
01725 }
01726
01727
01728
01729
01730
01731
01732 if (oldNode->m_sibLeft != 0)
01733 {
01734 if (oldNode->m_sibLeft->m_sibRight == oldNode)
01735 oldNode->m_sibLeft->m_sibRight = newNode;
01736 else {
01737
01738 OGDF_ASSERT(oldNode->m_sibLeft->m_sibLeft == oldNode);
01739 oldNode->m_sibLeft->m_sibLeft = newNode;
01740 }
01741 newNode->m_sibLeft = oldNode->m_sibLeft;
01742 oldNode->m_sibLeft = 0;
01743 }
01744
01745 if (oldNode->m_sibRight != 0)
01746 {
01747 if (oldNode->m_sibRight->m_sibLeft == oldNode)
01748 oldNode->m_sibRight->m_sibLeft = newNode;
01749 else {
01750
01751 OGDF_ASSERT(oldNode->m_sibRight->m_sibRight == oldNode);
01752 oldNode->m_sibRight->m_sibRight = newNode;
01753 }
01754 newNode->m_sibRight = oldNode->m_sibRight;
01755 oldNode->m_sibRight = 0;
01756 }
01757
01758 newNode->m_parentType = oldNode->m_parentType;
01759 newNode->m_parent = oldNode->m_parent;
01760 }
01761
01762
01763
01764
01765
01766
01780 template<class T,class X,class Y>
01781 void PQTree<T,X,Y>::front(
01782 PQNode<T,X,Y>* nodePtr,
01783 SListPure<PQLeafKey<T,X,Y>*> &leafKeys)
01784 {
01785 Queue<PQNode<T,X,Y>*> helpqueue;
01786 helpqueue.append(nodePtr);
01787
01788 while (!helpqueue.empty())
01789 {
01790 PQNode<T,X,Y>* checkNode = helpqueue.pop();
01791
01792 if (checkNode->type() == PQNodeRoot::leaf)
01793 leafKeys.pushBack(checkNode->getKey());
01794 else
01795 {
01796 PQNode<T,X,Y>* firstSon = 0;
01797 PQNode<T,X,Y>* nextSon = 0;
01798 PQNode<T,X,Y>* oldSib = 0;
01799 PQNode<T,X,Y>* holdSib = 0;
01800
01801 if (checkNode->type() == PQNodeRoot::PNode)
01802 {
01803 OGDF_ASSERT(checkNode->m_referenceChild)
01804 firstSon = checkNode->m_referenceChild;
01805 }
01806 else if (checkNode->type() == PQNodeRoot::QNode)
01807 {
01808 OGDF_ASSERT(checkNode->m_leftEndmost)
01809 firstSon = checkNode->m_leftEndmost;
01810 }
01811 helpqueue.append(firstSon);
01812 nextSon = firstSon->getNextSib(oldSib);
01813 oldSib = firstSon;
01814 while (nextSon && nextSon != firstSon)
01815 {
01816 helpqueue.append(nextSon);
01817 holdSib = nextSon->getNextSib(oldSib);
01818 oldSib = nextSon;
01819 nextSon = holdSib;
01820 }
01821 }
01822 }
01823 }
01824
01825
01826
01827
01828
01829
01848 template<class T,class X,class Y>
01849 int PQTree<T,X,Y>::Initialize(SListPure<PQLeafKey<T,X,Y>*> &leafKeys)
01850 {
01851 m_pertinentNodes = OGDF_NEW List<PQNode<T,X,Y>*>;
01852
01853 if (!leafKeys.empty())
01854 {
01855 PQInternalNode<T,X,Y> *newNode2 = OGDF_NEW PQInternalNode<T,X,Y>(-1,PQNodeRoot::QNode,PARTIAL);
01856 m_pseudoRoot = newNode2;
01857
01858 if (leafKeys.begin() != leafKeys.end())
01859 {
01860 PQInternalNode<T,X,Y> *newNode = OGDF_NEW PQInternalNode<T,X,Y>(m_identificationNumber++,PQNodeRoot::PNode,EMPTY);
01861 m_root = newNode;
01862 m_root->m_sibLeft = m_root;
01863 m_root->m_sibRight = m_root;
01864 return addNewLeavesToTree(newNode,leafKeys);
01865 }
01866 PQLeaf<T,X,Y> *newLeaf = OGDF_NEW PQLeaf<T,X,Y>(m_identificationNumber++,EMPTY,*leafKeys.begin());
01867 m_root = newLeaf;
01868 m_root->m_sibLeft = m_root;
01869 m_root->m_sibRight = m_root;
01870 return 1;
01871 }
01872
01873 return 0;
01874 }
01875
01876
01877
01878
01879
01880
01890 template<class T,class X,class Y>
01891 void PQTree<T,X,Y>::linkChildrenOfQnode(
01892 PQNode<T,X,Y> *installed,
01893 PQNode<T,X,Y> *newChild)
01894 {
01895 if ((installed != 0) && (newChild != 0))
01896 {
01897 if (installed->m_sibLeft == 0)
01898 {
01899 installed->m_sibLeft = newChild;
01900 if (newChild->m_sibRight == 0)
01901 newChild->m_sibRight = installed;
01902 else
01903 newChild->m_sibLeft = installed;
01904 }
01905 else {
01906
01907 OGDF_ASSERT(installed->m_sibRight == 0);
01908
01909 installed->m_sibRight = newChild;
01910 if (newChild->m_sibLeft == 0)
01911 newChild->m_sibLeft = installed;
01912 else
01913 newChild->m_sibRight = installed;
01914 }
01915 }
01916 }
01917
01918
01919
01920
01921
01922
01923
01930 template<class T,class X,class Y>
01931 void PQTree<T,X,Y>::writeGML(const char *fileName)
01932 {
01933 ofstream os(fileName);
01934 writeGML(os);
01935 }
01936
01937 template<class T,class X,class Y>
01938 void PQTree<T,X,Y>::writeGML(ostream &os)
01939 {
01940 Array<int> id(0,m_identificationNumber,0);
01941 int nextId = 0;
01942
01943 SListPure<PQNode<T,X,Y>*> helpQueue;
01944 SListPure<PQNode<T,X,Y>*> secondTrace;
01945
01946 os.setf(ios::showpoint);
01947 os.precision(10);
01948
01949 os << "Creator \"ogdf::PQTree::writeGML\"\n";
01950 os << "directed 1\n";
01951
01952 os << "graph [\n";
01953
01954 PQNode<T,X,Y>* checkNode = m_root;
01955 PQNode<T,X,Y>* firstSon = 0;
01956 PQNode<T,X,Y>* nextSon = 0;
01957 PQNode<T,X,Y>* lastSon = 0;
01958 PQNode<T,X,Y>* oldSib = 0;
01959 PQNode<T,X,Y>* holdSib = 0;
01960
01961 if (checkNode->type() != PQNodeRoot::leaf)
01962 secondTrace.pushBack(checkNode);
01963
01964 while (checkNode)
01965 {
01966 os << "node [\n";
01967
01968 os << "id " << (id[checkNode->m_identificationNumber] = nextId++) << "\n";
01969
01970 os << "label \"" << checkNode->m_identificationNumber;
01971 if (checkNode->getKey() != 0)
01972 os << checkNode->getKey()->print();
01973 os << "\"\n";
01974
01975 os << "graphics [\n";
01976 if (m_root->status() == FULL)
01977 {
01978 if (checkNode->type() == PQNodeRoot::PNode)
01979 os << "fill \"#FF0000\"\n";
01980 else if (checkNode->type() == PQNodeRoot::QNode)
01981 os << "fill \"#0000A0\"\n";
01982 else if (checkNode->type() == PQNodeRoot::leaf)
01983 os << "fill \"#FFFFE6\"\n";
01984 }
01985 else if (m_root->status() == EMPTY)
01986 {
01987 if (checkNode->type() == PQNodeRoot::PNode)
01988 os << "fill \"#FF0000\"\n";
01989 else if (checkNode->type() == PQNodeRoot::QNode)
01990 os << "fill \"#0000A0\"\n";
01991 else if (checkNode->type() == PQNodeRoot::leaf)
01992 os << "fill \"#00FF00\"\n";
01993 }
01994 else if (m_root->status() == PARTIAL)
01995 {
01996 if (checkNode->type() == PQNodeRoot::PNode)
01997 os << "fill \"#FF0000\"\n";
01998 else if (checkNode->type() == PQNodeRoot::QNode)
01999 os << "fill \"#0000A0\"\n";
02000 else if (checkNode->type() == PQNodeRoot::leaf)
02001 os << "fill \"#FFFFE6\"\n";
02002 }
02003 else if (m_root->status() == PERTINENT)
02004 {
02005 if (checkNode->type() == PQNodeRoot::PNode)
02006 os << "fill \"#FF0000\"\n";
02007 else if (checkNode->type() == PQNodeRoot::QNode)
02008 os << "fill \"#0000A0\"\n";
02009 else if (checkNode->type() == PQNodeRoot::leaf)
02010 os << "fill \"#FFFFE6\"\n";
02011 }
02012
02013 os << "]\n";
02014 os << "]\n";
02015
02016 if (checkNode->type() == PQNodeRoot::PNode)
02017 {
02018 if (checkNode->m_referenceChild != 0)
02019 {
02020 firstSon = checkNode->m_referenceChild;
02021 helpQueue.pushBack(firstSon);
02022
02023 if (firstSon->m_sibRight != 0)
02024 nextSon = firstSon->m_sibRight;
02025 while (nextSon != firstSon)
02026 {
02027 helpQueue.pushBack(nextSon);
02028 nextSon = nextSon->m_sibRight;
02029 }
02030 }
02031 }
02032 else if (checkNode->type() == PQNodeRoot::QNode)
02033 {
02034 oldSib = 0;
02035 holdSib = 0;
02036
02037 firstSon = checkNode->m_leftEndmost;
02038 helpQueue.pushBack(firstSon);
02039
02040 lastSon = checkNode->m_rightEndmost;
02041 if ( firstSon != lastSon)
02042 {
02043 helpQueue.pushBack(lastSon);
02044 nextSon = lastSon->getNextSib(oldSib);
02045 oldSib = lastSon;
02046 while (nextSon != firstSon)
02047 {
02048 helpQueue.pushBack(nextSon);
02049 holdSib = nextSon->getNextSib(oldSib);
02050 oldSib = nextSon;
02051 nextSon = holdSib;
02052 }
02053 }
02054 }
02055 if (!helpQueue.empty())
02056 {
02057 checkNode = helpQueue.popFrontRet();
02058 if (checkNode->type() != PQNodeRoot::leaf)
02059 secondTrace.pushBack(checkNode);
02060 }
02061 else
02062 checkNode = 0;
02063 }
02064
02065
02066 SListIterator<PQNode<T,X,Y>*> it;
02067
02068 for (it = secondTrace.begin(); it.valid(); it++)
02069 {
02070 checkNode = *it;
02071 if (checkNode->type() == PQNodeRoot::PNode)
02072 {
02073 if (checkNode->m_referenceChild != 0)
02074 {
02075 firstSon = checkNode->m_referenceChild;
02076 os << "edge [\n";
02077 os << "source " << id[checkNode->m_identificationNumber] << "\n";
02078 os << "target " << id[firstSon->m_identificationNumber] << "\n";
02079 os << "]\n";
02080
02081 if (firstSon->m_sibRight != 0)
02082 nextSon = firstSon->m_sibRight;
02083 while (nextSon != firstSon)
02084 {
02085 os << "edge [\n";
02086 os << "source " << id[checkNode->m_identificationNumber] << "\n";
02087 os << "target " << id[nextSon->m_identificationNumber] << "\n";
02088 os << "]\n";
02089 nextSon = nextSon->m_sibRight;
02090 }
02091 }
02092 }
02093 else if (checkNode->type() == PQNodeRoot::QNode)
02094 {
02095 oldSib = 0;
02096 holdSib = 0;
02097
02098 firstSon = checkNode->m_leftEndmost;
02099 lastSon = checkNode->m_rightEndmost;
02100
02101 os << "edge [\n";
02102 os << "source " << id[checkNode->m_identificationNumber] << "\n";
02103 os << "target " << id[lastSon->m_identificationNumber] << "\n";
02104 os << "]\n";
02105 if ( firstSon != lastSon)
02106 {
02107 nextSon = lastSon->getNextSib(oldSib);
02108 os << "edge [\n";
02109 os << "source " << id[checkNode->m_identificationNumber] << "\n";
02110 os << "target " << id[nextSon->m_identificationNumber] << "\n";
02111 os << "]\n";
02112
02113 oldSib = lastSon;
02114 while (nextSon != firstSon)
02115 {
02116 holdSib = nextSon->getNextSib(oldSib);
02117 oldSib = nextSon;
02118 nextSon = holdSib;
02119 os << "edge [\n";
02120 os << "source " << id[checkNode->m_identificationNumber] << "\n";
02121 os << "target " << id[nextSon->m_identificationNumber] << "\n";
02122 os << "]\n";
02123
02124 }
02125 }
02126 }
02127 }
02128 os << "]\n";
02129 }
02130
02131
02132
02133
02134
02135
02136
02180 template<class T,class X,class Y>
02181 bool PQTree<T,X,Y>::Reduce(SListPure<PQLeafKey<T,X,Y>*> &leafKeys)
02182 {
02183 int pertLeafCount = 0;
02184 Queue<PQNode<T,X,Y>*> processNodes;
02185
02186
02187
02188
02189
02190
02191
02192 SListIterator<PQLeafKey<T,X,Y>*> it;
02193 for (it = leafKeys.begin(); it.valid(); ++it)
02194 {
02195 PQNode<T,X,Y>* checkLeaf = (*it)->nodePointer();
02196 checkLeaf->status(FULL);
02197 checkLeaf->m_pertLeafCount = 1;
02198 processNodes.append(checkLeaf);
02199 pertLeafCount++;
02200 }
02201
02202 PQNode<T,X,Y>* checkNode = processNodes.top();
02203 while ((checkNode != 0) && (processNodes.size() > 0))
02204 {
02205 checkNode = processNodes.pop();
02206
02207 if (checkNode->m_pertLeafCount < pertLeafCount)
02208 {
02209
02210
02211
02212
02213
02214
02215
02216
02217
02218
02219
02220
02221 checkNode->m_parent->m_pertLeafCount =
02222 checkNode->m_parent->m_pertLeafCount
02223 + checkNode->m_pertLeafCount;
02224
02225 checkNode->m_parent->m_pertChildCount--;
02226 if (!checkNode->m_parent->m_pertChildCount)
02227 processNodes.append(checkNode->m_parent);
02228 if (!templateL1(checkNode,0))
02229 if (!templateP1(checkNode,0))
02230 if (!templateP3(checkNode))
02231 if (!templateP5(checkNode))
02232 if (!templateQ1(checkNode,0))
02233 if (!templateQ2(checkNode,0))
02234 checkNode= 0;
02235 }
02236 else
02237 {
02238
02239
02240
02241
02242
02243
02244
02245
02246
02247
02248 if (!templateL1(checkNode,1))
02249 if (!templateP1(checkNode,1))
02250 if (!templateP2(&checkNode))
02251 if (!templateP4(&checkNode))
02252 if (!templateP6(&checkNode))
02253 if (!templateQ1(checkNode,1))
02254 if (!templateQ2(checkNode,1))
02255 if (!templateQ3(checkNode))
02256 checkNode = 0;
02257 }
02258 }
02259
02260 m_pertinentRoot = checkNode;
02261 return (m_pertinentRoot != 0);
02262 }
02263
02264
02265
02266
02267
02268
02269
02285 template<class T,class X,class Y>
02286 bool PQTree<T,X,Y>::Reduction(SListPure<PQLeafKey<T,X,Y>*> &leafKeys)
02287 {
02288 bool success = Bubble(leafKeys);
02289
02290 if (!success)
02291 return false;
02292 else
02293 return Reduce(leafKeys);
02294
02295 }
02296
02297
02298
02299
02300
02301
02319 template<class T,class X,class Y>
02320 void PQTree<T,X,Y>::removeBlock(PQNode<T,X,Y> *nodePtr,bool isRoot)
02321
02322 {
02323
02324
02325
02326
02327
02328
02329
02330
02331
02333 PQNode<T,X,Y> *partial_1 = 0;
02334
02335
02336
02337
02338
02339
02340
02341 PQNode<T,X,Y> *endfull_1 = 0;
02342
02343
02344
02345
02346
02347
02348
02349 PQNode<T,X,Y> *endempty_1 = 0;
02350
02351
02352
02353
02354
02355
02356 PQNode<T,X,Y> *realfull_1 = 0;
02357
02358
02359
02360
02361
02362
02363 PQNode<T,X,Y> *realempty_1 = 0;
02364
02365
02366 PQNode<T,X,Y> *partial_2 = 0;
02367
02368
02369
02370
02371
02372
02373
02374 PQNode<T,X,Y> *endfull_2 = 0;
02375
02376
02377
02378
02379
02380
02381
02382 PQNode<T,X,Y> *endempty_2 = 0;
02383
02384
02385
02386
02387
02388
02389 PQNode<T,X,Y> *realfull_2 = 0;
02390
02391
02392
02393
02394
02395
02396 PQNode<T,X,Y> *realempty_2 = 0;
02397
02398
02399
02400
02401
02402
02403
02404
02405 PQNode<T,X,Y> *sibfull_1 = 0;
02406
02407
02408
02409
02410
02411
02412
02413
02414 PQNode<T,X,Y> *sibpartial_1 = 0;
02415
02416
02417
02418
02419
02420
02421
02422
02423 PQNode<T,X,Y> *sibempty_1 = 0;
02424
02425
02426
02427
02428
02429
02430
02431
02432
02433
02434
02435
02436 PQNode<T,X,Y> *nonstatussib_1 = 0;
02437
02438
02439
02440
02441
02442
02443
02444
02445 PQNode<T,X,Y> *sibfull_2 = 0;
02446
02447
02448
02449
02450
02451
02452
02453
02454 PQNode<T,X,Y> *sibpartial_2 = 0;
02455
02456
02457
02458
02459
02460
02461
02462
02463 PQNode<T,X,Y> *sibempty_2 = 0;
02464
02465
02466
02467
02468
02469
02470
02471
02472
02473
02474
02475
02476 PQNode<T,X,Y> *nonstatussib_2 = 0;
02477
02478 PQNode<T,X,Y> *helpptr = 0;
02479
02480 PQNode<T,X,Y> *checkVarLeft = 0;
02481
02482 PQNode<T,X,Y> *checkVarRight = 0;
02483
02484
02485
02486
02487
02488 int endmostcheck = 0;
02489
02490
02491 nodePtr->status(PARTIAL);
02492 if (!isRoot)
02493 nodePtr->m_parent->partialChildren->pushFront(nodePtr);
02494
02495 if (!nodePtr->partialChildren->empty())
02496
02497 {
02498 partial_1 = nodePtr->partialChildren->popFrontRet();
02499
02500
02501
02502
02503 checkVarLeft = clientLeftEndmost(partial_1);
02504 checkVarRight = clientRightEndmost(partial_1);
02505 if (checkVarLeft->status() == FULL)
02506 {
02507 endfull_1 = partial_1->m_leftEndmost;
02508 realfull_1 = checkVarLeft;
02509 }
02510 else {
02511
02512 OGDF_ASSERT(checkVarRight->status() == FULL);
02513
02514 endfull_1 = partial_1->m_rightEndmost;
02515 realfull_1 = checkVarRight;
02516 }
02517
02518 if (checkVarLeft->status() == EMPTY)
02519 {
02520 endempty_1 = partial_1->m_leftEndmost;
02521 realempty_1 = checkVarLeft;
02522 }
02523 else {
02524
02525 OGDF_ASSERT(checkVarRight->status() == EMPTY);
02526
02527 endempty_1 = partial_1->m_rightEndmost;
02528 realempty_1 = checkVarRight;
02529 }
02530
02531
02532
02533
02534 if (clientSibLeft(partial_1) != 0)
02535 {
02536 if (clientSibLeft(partial_1)->status() == FULL)
02537 sibfull_1 = partial_1->m_sibLeft;
02538 else if (clientSibLeft(partial_1)->status() == EMPTY)
02539 sibempty_1 = partial_1->m_sibLeft;
02540 else if (clientSibLeft(partial_1)->status() == PARTIAL)
02541 sibpartial_1 = partial_1->m_sibLeft;
02542 }
02543 else
02544 nonstatussib_1 = partial_1->m_sibLeft;
02545
02546 if (clientSibRight(partial_1) != 0)
02547 {
02548 if (clientSibRight(partial_1)->status() == FULL)
02549 sibfull_1 = partial_1->m_sibRight;
02550 else if (clientSibRight(partial_1)->status() == EMPTY)
02551 sibempty_1 = partial_1->m_sibRight;
02552 else if (clientSibRight(partial_1)->status() == PARTIAL)
02553 sibpartial_1 = partial_1->m_sibRight;
02554 }
02555 else {
02556
02557 OGDF_ASSERT(nonstatussib_1 == 0);
02558 nonstatussib_1 = partial_1->m_sibRight;
02559 }
02560 }
02561
02562
02563 if (!nodePtr->partialChildren->empty())
02564
02565 {
02566 partial_2 = nodePtr->partialChildren->popFrontRet();
02567
02568
02569
02570
02571 checkVarLeft = clientLeftEndmost(partial_2);
02572 checkVarRight = clientRightEndmost(partial_2);
02573 if (checkVarLeft->status() == FULL)
02574 {
02575 endfull_2 = partial_2->m_leftEndmost;
02576 realfull_2 = checkVarLeft;
02577 }
02578 else {
02579
02580 OGDF_ASSERT(checkVarRight->status() == FULL);
02581
02582 endfull_2 = partial_2->m_rightEndmost;
02583 realfull_2 = checkVarRight;
02584 }
02585
02586 if (checkVarLeft->status() == EMPTY)
02587 {
02588 endempty_2 = partial_2->m_leftEndmost;
02589 realempty_2 = checkVarLeft;
02590 }
02591 else {
02592
02593 OGDF_ASSERT(checkVarRight->status() == EMPTY);
02594
02595 endempty_2 = partial_2->m_rightEndmost;
02596 realempty_2 = checkVarRight;
02597 }
02598
02599
02600
02601 if (clientSibLeft(partial_2) != 0)
02602 {
02603 if (clientSibLeft(partial_2)->status() == FULL)
02604 sibfull_2 = partial_2->m_sibLeft;
02605 else if (clientSibLeft(partial_2)->status() == EMPTY)
02606 sibempty_2 = partial_2->m_sibLeft;
02607 else if (clientSibLeft(partial_2)->status() == PARTIAL)
02608 sibpartial_2 = partial_2->m_sibLeft;
02609 }
02610 else
02611 nonstatussib_2 = partial_2->m_sibLeft;
02612
02613
02614 if (clientSibRight(partial_2) != 0)
02615 {
02616 if (clientSibRight(partial_2)->status() == FULL)
02617 sibfull_2 = partial_2->m_sibRight;
02618 else if (clientSibRight(partial_2)->status() == EMPTY)
02619 sibempty_2 = partial_2->m_sibRight;
02620 else if (clientSibRight(partial_2)->status() == PARTIAL)
02621 sibpartial_2 = partial_2->m_sibRight;
02622 }
02623 else {
02624 OGDF_ASSERT(nonstatussib_2 == 0);
02625 nonstatussib_2 = partial_2->m_sibRight;
02626 }
02627 }
02628
02629
02630 if (partial_1 != 0 && partial_2 != 0)
02631
02632
02633
02634
02635
02636
02637
02638
02639
02640
02641
02642
02643
02644
02645 {
02646 if (sibfull_1 != 0 && sibfull_2 != 0)
02647
02648
02649
02650
02651
02652
02653 {
02654 sibfull_1->changeSiblings(partial_1,endfull_1);
02655 endfull_1->putSibling(sibfull_1);
02656 sibfull_2->changeSiblings(partial_2,endfull_2);
02657 endfull_2->putSibling(sibfull_2);
02658 }
02659
02660 else if (sibpartial_1 != 0 && sibpartial_2 != 0)
02661
02662
02663
02664
02665 {
02666 if (partial_1 == sibpartial_2 && partial_2 == sibpartial_1)
02667
02668 {
02669 endfull_1->putSibling(endfull_2);
02670 endfull_2->putSibling(endfull_1);
02671 }
02672
02673
02674 else
02675 {
02676 endfull_1->putSibling(sibpartial_1);
02677 sibpartial_1->changeSiblings(partial_1,endfull_1);
02678 endfull_2->putSibling(sibpartial_2);
02679 sibpartial_2->changeSiblings(partial_2,endfull_2);
02680 }
02681
02682 }
02683
02684
02685
02686
02687
02688 if (sibempty_1 == 0)
02689
02690
02691
02692
02693 {
02694 if (nonstatussib_1 == 0)
02695
02696 {
02697 nodePtr->changeEndmost(partial_1,endempty_1);
02698 }
02699 else
02700
02701
02702 {
02703 nonstatussib_1->changeSiblings(partial_1,endempty_1);
02704 endempty_1->putSibling(nonstatussib_1);
02705 }
02706 endempty_1->m_parent = nodePtr;
02707 realempty_1->m_parent = nodePtr;
02708 }
02709
02710 else
02711
02712 {
02713 sibempty_1->changeSiblings(partial_1,endempty_1);
02714 endempty_1->putSibling(sibempty_1);
02715 }
02716
02717
02718 if (sibempty_2 == 0)
02719
02720
02721
02722
02723 {
02724 if (nonstatussib_2 == 0)
02725
02726 {
02727 nodePtr->changeEndmost(partial_2,endempty_2);
02728 }
02729 else
02730
02731
02732
02733 {
02734 nonstatussib_2->changeSiblings(partial_2,endempty_2);
02735 endempty_2->putSibling(nonstatussib_2);
02736 }
02737 endempty_2->m_parent = nodePtr;
02738 realempty_2->m_parent = nodePtr;
02739 }
02740
02741 else
02742
02743 {
02744 sibempty_2->changeSiblings(partial_2,endempty_2);
02745 endempty_2->putSibling(sibempty_2);
02746 }
02747
02748
02749
02750
02751 while (!partial_2->fullChildren->empty())
02752 {
02753 helpptr = partial_2->fullChildren->popFrontRet();
02754 nodePtr->fullChildren->pushFront(helpptr);
02755 }
02756 nodePtr->m_childCount = nodePtr->m_childCount +partial_2->m_childCount - 1;
02757
02758 destroyNode(partial_2);
02759
02760 while (!partial_1->fullChildren->empty())
02761 {
02762 helpptr = partial_1->fullChildren->popFrontRet();
02763 nodePtr->fullChildren->pushFront(helpptr);
02764 }
02765 nodePtr->m_childCount = nodePtr->m_childCount +partial_1->m_childCount - 1;
02766
02767 destroyNode(partial_1);
02768 }
02769
02770
02771 else if (partial_1 != 0)
02772
02773
02774
02775
02776
02777
02778
02779
02780
02781
02782
02783
02784
02785
02786
02787 {
02788 if ((clientLeftEndmost(nodePtr) == partial_1) ||
02789 (clientRightEndmost(nodePtr) == partial_1))
02790
02791 endmostcheck = 1;
02792
02793 if (sibfull_1 != 0)
02794
02795
02796
02797
02798
02799 {
02800 sibfull_1->changeSiblings(partial_1,endfull_1);
02801 endfull_1->putSibling(sibfull_1);
02802 }
02803
02804 else if (!endmostcheck)
02805
02806
02807
02808
02809
02810
02811 {
02812 if (partial_1->m_sibLeft != sibempty_1)
02813 sibempty_2 = partial_1->m_sibLeft;
02814 else
02815 sibempty_2 = partial_1->m_sibRight;
02816
02817 sibempty_2->changeSiblings(partial_1,endfull_1);
02818 endfull_1->putSibling(sibempty_2);
02819 }
02820
02821 else
02822
02823
02824
02825
02826
02827 {
02828
02829 if (nonstatussib_1 == 0)
02830
02831 {
02832 nodePtr->changeEndmost(partial_1,endfull_1);
02833 }
02834 else
02835
02836
02837
02838 {
02839 nonstatussib_1->changeSiblings(partial_1,endfull_1);
02840 endfull_1->putSibling(nonstatussib_1);
02841 }
02842 endfull_1->m_parent = nodePtr;
02843 realfull_1->m_parent = nodePtr;
02844
02845 }
02846
02847 if (sibempty_1 == 0)
02848
02849
02850
02851
02852
02853 {
02854 if (nonstatussib_1 == 0)
02855
02856 {
02857 nodePtr->changeEndmost(partial_1,endempty_1);
02858 }
02859 else
02860
02861
02862
02863 {
02864 nonstatussib_1->changeSiblings(partial_1,endempty_1);
02865 endempty_1->putSibling(nonstatussib_1);
02866 }
02867 endempty_1->m_parent = nodePtr;
02868 realempty_1->m_parent = nodePtr;
02869 }
02870
02871 else
02872
02873
02874
02875 {
02876 sibempty_1->changeSiblings(partial_1,endempty_1);
02877 endempty_1->putSibling(sibempty_1);
02878 }
02879
02880 while (!partial_1->fullChildren->empty())
02881 {
02882 helpptr = partial_1->fullChildren->popFrontRet();
02883 nodePtr->fullChildren->pushFront(helpptr);
02884 }
02885
02886 nodePtr->m_childCount = nodePtr->m_childCount + partial_1->m_childCount - 1;
02887 destroyNode(partial_1);
02888
02889 }
02890
02891 }
02892
02893
02894
02895
02896
02897
02908 template<class T,class X,class Y>
02909 void PQTree<T,X,Y>::removeChildFromSiblings(PQNode<T,X,Y>* nodePtr)
02910 {
02911 if (nodePtr->m_referenceParent != 0)
02912 {
02913
02914
02915
02916
02917
02918 nodePtr->m_referenceParent->m_referenceChild = nodePtr->m_sibRight;
02919 nodePtr->m_sibRight->m_referenceParent = nodePtr->m_referenceParent;
02920 if (nodePtr->m_referenceParent->m_referenceChild == nodePtr)
02921 nodePtr->m_referenceParent->m_referenceChild = 0;
02922 nodePtr->m_referenceParent = 0;
02923 }
02924 else if (nodePtr->endmostChild())
02925 {
02926
02927
02928
02929
02930
02931
02932 PQNode<T,X,Y> *sibling = nodePtr->getNextSib(0);
02933 if (nodePtr->m_parent->m_leftEndmost == nodePtr)
02934 nodePtr->m_parent->m_leftEndmost = sibling;
02935 else if (nodePtr->m_parent->m_rightEndmost == nodePtr)
02936 nodePtr->m_parent->m_rightEndmost = sibling;
02937 if (sibling != 0)
02938 sibling->m_parent = nodePtr->m_parent;
02939 }
02940
02941
02942
02943
02944
02945 if ((nodePtr->m_sibRight != 0) && (nodePtr->m_sibRight != nodePtr))
02946 {
02947 if (nodePtr->m_sibRight->m_sibLeft == nodePtr)
02948 nodePtr->m_sibRight->m_sibLeft = nodePtr->m_sibLeft;
02949 else {
02950
02951 OGDF_ASSERT(nodePtr->m_sibRight->m_sibRight == nodePtr);
02952 nodePtr->m_sibRight->m_sibRight = nodePtr->m_sibLeft;
02953 }
02954 }
02955 if ((nodePtr->m_sibLeft != 0) && (nodePtr->m_sibLeft != nodePtr))
02956 {
02957 if (nodePtr->m_sibLeft->m_sibRight == nodePtr)
02958 nodePtr->m_sibLeft->m_sibRight = nodePtr->m_sibRight;
02959 else {
02960
02961 OGDF_ASSERT(nodePtr->m_sibLeft->m_sibLeft == nodePtr);
02962 nodePtr->m_sibLeft->m_sibLeft = nodePtr->m_sibRight;
02963 }
02964 }
02965
02966 nodePtr->m_sibRight = 0;
02967 nodePtr->m_sibLeft = 0;
02968 }
02969
02970
02971
02972
02973
02974
03024 template<class T,class X,class Y>
03025 int PQTree<T,X,Y>::removeNodeFromTree(PQNode<T,X,Y>* parent,PQNode<T,X,Y>* child)
03026 {
03027 if (parent !=0)
03028 {
03029 removeChildFromSiblings(child);
03030 parent->m_childCount--;
03031 if ((child->status() == FULL) || (child->status() == PARTIAL))
03032 parent->m_pertChildCount--;
03033 return parent->m_childCount;
03034 }
03035 else
03036 {
03037
03038 return -1;
03039 }
03040 }
03041
03042
03043
03044
03045
03046
03053 template<class T,class X,class Y>
03054 void PQTree<T,X,Y>::sortExceptions(int Exceptions[],int arraySize)
03055 {
03056 bool changed = true;
03057 while (changed)
03058 {
03059 changed = false;
03060 for (int i = 0; i < (arraySize-1); i++)
03061 {
03062 if (Exceptions[i] > Exceptions[i+1])
03063 {
03064 swap(Exceptions[i],Exceptions[i+1]);
03065 changed = true;
03066 }
03067 }
03068 }
03069 }
03070
03071
03072
03073
03074
03075
03098 template<class T,class X,class Y>
03099 bool PQTree<T,X,Y>::templateL1(PQNode<T,X,Y> *nodePtr, bool isRoot)
03100 {
03101 if ((nodePtr->type() == PQNodeRoot::leaf) && (nodePtr->status() == FULL))
03102 {
03103 if (!isRoot)
03104 nodePtr->m_parent->fullChildren->pushFront(nodePtr);
03105 return true;
03106 }
03107
03108 return false;
03109 }
03110
03111
03112
03113
03114
03115
03138 template<class T,class X,class Y>
03139 bool PQTree<T,X,Y>::templateP1(PQNode<T,X,Y> *nodePtr,
03140 bool isRoot)
03141 {
03142 if (nodePtr->type() != PQNodeRoot::PNode ||
03143 nodePtr->fullChildren->size() != nodePtr->m_childCount)
03144 return false;
03145 else
03146 {
03147 nodePtr->status(FULL);
03148 if (!isRoot)
03149 nodePtr->m_parent->fullChildren->pushFront(nodePtr);
03150
03151 return true;
03152 }
03153 }
03154
03155
03156
03157
03158
03159
03181 template<class T,class X,class Y>
03182 bool PQTree<T,X,Y>::templateP2(PQNode<T,X,Y> **nodePtr)
03183 {
03184 if ((*nodePtr)->type() != PQNodeRoot::PNode ||
03185 (*nodePtr)->partialChildren->size() > 0)
03186 return false;
03187
03188 (*nodePtr)->m_childCount =
03189 (*nodePtr)->m_childCount - (*nodePtr)->fullChildren->size() + 1;
03190
03191
03192
03193
03194 PQNode<T,X,Y> *newNode = createNodeAndCopyFullChildren((*nodePtr)->fullChildren);
03195
03196
03197
03198 newNode->m_parent = (*nodePtr);
03199 newNode->m_sibRight = (*nodePtr)->m_referenceChild->m_sibRight;
03200 newNode->m_sibLeft = newNode->m_sibRight->m_sibLeft;
03201 newNode->m_sibLeft->m_sibRight = newNode;
03202 newNode->m_sibRight->m_sibLeft = newNode;
03203 newNode->m_parentType = PQNodeRoot::PNode;
03204
03205
03206 (*nodePtr) = newNode;
03207
03208 return true;
03209 }
03210
03211
03212
03213
03214
03215
03216
03217
03218
03219
03220
03221
03222
03223
03224
03225
03226
03227
03228
03229
03230
03231
03232
03233
03234
03235
03236
03237
03238
03239
03240
03241
03242
03243
03244
03245
03246
03247
03248
03249 template<class T,class X,class Y>
03250 bool PQTree<T,X,Y>::templateP3(PQNode<T,X,Y> *nodePtr)
03251 {
03252 if (nodePtr->type() != PQNodeRoot::PNode || nodePtr->partialChildren->size() > 0)
03253 return false;
03254
03255
03256
03257
03258
03259
03260
03261 PQInternalNode<T,X,Y> *newNode = OGDF_NEW PQInternalNode<T,X,Y>(m_identificationNumber++,PQNodeRoot::QNode,PARTIAL);
03262 PQNode<T,X,Y> *newQnode = newNode;
03263 m_pertinentNodes->pushFront(newQnode);
03264
03265 exchangeNodes(nodePtr,newQnode);
03266 nodePtr->m_parent = newQnode;
03267 nodePtr->m_parentType = PQNodeRoot::QNode;
03268
03269 newQnode->m_leftEndmost = (nodePtr);
03270 newQnode->m_childCount = 1;
03271
03272
03273
03274
03275
03276
03277
03278 if (nodePtr->fullChildren->size() > 0)
03279 {
03280 nodePtr->m_childCount = nodePtr->m_childCount -
03281 nodePtr->fullChildren->size();
03282
03283 PQNode<T,X,Y> *newPnode = createNodeAndCopyFullChildren(nodePtr->fullChildren);
03284 newPnode->m_parentType = PQNodeRoot::QNode;
03285
03286
03287 newQnode->m_childCount++;
03288 newQnode->fullChildren->pushFront(newPnode);
03289
03290 nodePtr->m_sibRight = newPnode;
03291 newPnode->m_sibLeft = nodePtr;
03292 newQnode->m_rightEndmost = newPnode;
03293 newPnode->m_parent = newQnode;
03294 }
03295
03296
03297
03298
03299 PQNode<T,X,Y> *emptyNode = nodePtr->m_referenceChild;
03300 checkIfOnlyChild(emptyNode,nodePtr);
03301
03302
03303 newQnode->m_parent->partialChildren->pushFront(newQnode);
03304
03305 return true;
03306 }
03307
03308
03309
03310
03311
03312
03339 template<class T,class X,class Y>
03340 bool PQTree<T,X,Y>::templateP4(PQNode<T,X,Y> **nodePtr)
03341 {
03342 if ((*nodePtr)->type() != PQNodeRoot::PNode ||
03343 (*nodePtr)->partialChildren->size() != 1)
03344 return false;
03345
03346 PQNode<T,X,Y> *partialChild = (*nodePtr)->partialChildren->popFrontRet();
03347 copyFullChildrenToPartial(*nodePtr,partialChild);
03348
03349
03350
03351
03352 checkIfOnlyChild(partialChild,*nodePtr);
03353
03354
03355 *nodePtr = partialChild;
03356
03357 return true;
03358 }
03359
03360
03361
03362
03363
03364
03400 template<class T,class X,class Y>
03401 bool PQTree<T,X,Y>::templateP5(PQNode<T,X,Y> *nodePtr)
03402 {
03403 if ((nodePtr->type() != PQNodeRoot::PNode) ||
03404 (nodePtr->partialChildren->size() != 1))
03405 return false;
03406
03407
03408
03409
03410
03411
03412
03413
03414
03415
03416
03417 int emptyChildCount = nodePtr->m_childCount -
03418 nodePtr->fullChildren->size() - 1;
03419 PQNode<T,X,Y> *partialChild = nodePtr->partialChildren->popFrontRet();
03420 nodePtr->m_parent->partialChildren->pushFront(partialChild);
03421 removeChildFromSiblings(partialChild);
03422 exchangeNodes(nodePtr,partialChild);
03423 copyFullChildrenToPartial(nodePtr,partialChild);
03424
03425 if (emptyChildCount > 0)
03426 {
03427
03428
03429
03430
03431
03432
03433
03434
03435 PQNode<T,X,Y> *emptyNode;
03436 if (emptyChildCount == 1)
03437 {
03438 emptyNode = nodePtr->m_referenceChild;
03439 removeChildFromSiblings(emptyNode);
03440
03441 } else {
03442 emptyNode = nodePtr;
03443 emptyNode->m_childCount = emptyChildCount;
03444 }
03445
03446
03447
03448
03449
03450
03451 PQNode<T,X,Y> *checkNode;
03452 if (clientLeftEndmost(partialChild)->status() == EMPTY)
03453 {
03454 checkNode = partialChild->m_leftEndmost;
03455 partialChild->m_leftEndmost = emptyNode;
03456 }
03457 else {
03458
03459 OGDF_ASSERT(clientRightEndmost(partialChild)->status() == EMPTY);
03460
03461 checkNode = partialChild->m_rightEndmost;
03462 partialChild->m_rightEndmost = emptyNode;
03463 }
03464
03465 linkChildrenOfQnode(checkNode,emptyNode);
03466 emptyNode->m_parent = partialChild;
03467 emptyNode->m_parentType = PQNodeRoot::QNode;
03468 partialChild->m_childCount++;
03469 }
03470
03471
03472 if (emptyChildCount <= 1)
03473 destroyNode(nodePtr);
03474
03475 return true;
03476 }
03477
03478
03479
03480
03481
03482
03524 template<class T,class X,class Y>
03525 bool PQTree<T,X,Y>::templateP6(PQNode<T,X,Y> **nodePtr)
03526 {
03527
03528
03529
03530
03531
03532
03533
03534 if ((*nodePtr)->type() != PQNodeRoot::PNode ||
03535 (*nodePtr)->partialChildren->size() != 2)
03536 return false;
03537
03538
03539
03540
03541
03542
03543
03544
03545
03546 PQNode<T,X,Y> *partial_1 = (*nodePtr)->partialChildren->popFrontRet();
03547 PQNode<T,X,Y> *partial_2 = (*nodePtr)->partialChildren->popFrontRet();
03548
03549 removeChildFromSiblings(partial_2);
03550 (*nodePtr)->m_childCount--;
03551 copyFullChildrenToPartial(*nodePtr,partial_1);
03552
03553
03554
03555
03556
03557
03558 PQNode<T,X,Y> *fullEnd_1;
03559 if (clientLeftEndmost(partial_1)->status() == FULL)
03560 fullEnd_1 = partial_1->m_leftEndmost;
03561 else {
03562
03563 OGDF_ASSERT(clientRightEndmost(partial_1)->status() == FULL);
03564 fullEnd_1 = partial_1->m_rightEndmost;
03565 }
03566
03567 PQNode<T,X,Y> *fullEnd_2 = 0;
03568 PQNode<T,X,Y> *emptyEnd_2 = 0;
03569 PQNode<T,X,Y> *realEmptyEnd_2 = 0;
03570 if (clientLeftEndmost(partial_2)->status() == FULL)
03571 fullEnd_2 = partial_2->m_leftEndmost;
03572 else {
03573
03574 OGDF_ASSERT(clientLeftEndmost(partial_2)->status() == EMPTY);
03575
03576 emptyEnd_2 = partial_2->m_leftEndmost;
03577 realEmptyEnd_2 = clientLeftEndmost(partial_2);
03578 }
03579
03580 if (clientRightEndmost(partial_2)->status() == FULL)
03581 fullEnd_2 = partial_2->m_rightEndmost;
03582 else {
03583
03584 OGDF_ASSERT(clientRightEndmost(partial_2)->status() == EMPTY);
03585
03586 emptyEnd_2 = partial_2->m_rightEndmost;
03587 realEmptyEnd_2 = clientRightEndmost(partial_2);
03588 }
03589
03590 OGDF_ASSERT(fullEnd_2 != emptyEnd_2)
03591
03592
03593
03594
03595
03596
03597
03598
03599
03600
03601 while (!partial_2->fullChildren->empty())
03602 partial_1->fullChildren->pushFront(partial_2->fullChildren->popFrontRet());
03603 linkChildrenOfQnode(fullEnd_1,fullEnd_2);
03604 if (partial_1->m_leftEndmost == fullEnd_1)
03605 partial_1->m_leftEndmost = emptyEnd_2;
03606 else
03607 partial_1->m_rightEndmost = emptyEnd_2;
03608
03609 emptyEnd_2->m_parent = partial_1;
03610 emptyEnd_2->m_parentType = PQNodeRoot::QNode;
03611
03612 realEmptyEnd_2->m_parent = partial_1;
03613 realEmptyEnd_2->m_parentType = PQNodeRoot::QNode;
03614
03615 partial_1->m_childCount = partial_1->m_childCount +
03616 partial_2->m_childCount;
03617 destroyNode(partial_2);
03618
03619
03620
03621
03622
03623
03624
03625 checkIfOnlyChild(partial_1,*nodePtr);
03626
03627
03628 *nodePtr = partial_1;
03629
03630 return true;
03631 }
03632
03633
03634
03635
03636
03637
03665 template<class T,class X,class Y>
03666 bool PQTree<T,X,Y>::templateQ1(PQNode<T,X,Y> *nodePtr, bool isRoot)
03667 {
03668 if (nodePtr->type() == PQNodeRoot::QNode &&
03669 nodePtr != m_pseudoRoot &&
03670 clientLeftEndmost(nodePtr)->status() == FULL &&
03671 clientRightEndmost(nodePtr)->status() == FULL)
03672 {
03673 PQNode<T,X,Y>* seqStart = 0;
03674 PQNode<T,X,Y>* seqEnd = 0;
03675 if (checkChain(nodePtr,clientLeftEndmost(nodePtr),&seqStart,&seqEnd))
03676 {
03677 nodePtr->status(FULL);
03678 if (!isRoot)
03679 nodePtr->m_parent->fullChildren->pushFront(nodePtr);
03680 return true;
03681 }
03682 }
03683
03684 return false;
03685 }
03686
03687
03688
03689
03690
03691
03746 template<class T,class X,class Y>
03747 bool PQTree<T,X,Y>::templateQ2(PQNode<T,X,Y> *nodePtr,bool isRoot)
03748 {
03749 if (nodePtr->type() != PQNodeRoot::QNode ||
03750 nodePtr->partialChildren->size() > 1)
03751 return false;
03752
03753 bool sequenceCons = false;
03754 if (nodePtr->fullChildren->size() > 0)
03755 {
03756
03757
03758
03759
03760 PQNode<T,X,Y> *fullNode = 0;
03761 if (nodePtr->m_leftEndmost != 0)
03762 {
03763 fullNode = clientLeftEndmost(nodePtr);
03764 if (fullNode->status() != FULL)
03765 fullNode = 0;
03766 }
03767 if (nodePtr->m_rightEndmost != 0 && fullNode == 0)
03768 {
03769 fullNode = clientRightEndmost(nodePtr);
03770 if (fullNode->status() != FULL)
03771 fullNode = 0;
03772 }
03773
03774
03775
03776
03777
03778
03779
03780
03781
03782
03783
03784
03785
03786
03787
03788 PQNode<T,X,Y> *sequenceBegin = 0;
03789 PQNode<T,X,Y> *sequenceEnd = 0;
03790 if (fullNode != 0)
03791 sequenceCons = checkChain(nodePtr,fullNode,&sequenceBegin,&sequenceEnd);
03792
03793 if (sequenceCons && (nodePtr->partialChildren->size() == 1))
03794 {
03795 PQNode<T,X,Y> *partialChild = nodePtr->partialChildren->front();
03796 sequenceCons = false;
03797
03798 if (clientSibLeft(sequenceEnd) == partialChild ||
03799 clientSibRight(sequenceEnd) == partialChild)
03800 sequenceCons = true;
03801 }
03802 }
03803 else
03804 {
03805 if (!nodePtr->partialChildren->empty())
03806 {
03807
03808
03809
03810
03811
03812
03813
03814
03815
03816 PQNode<T,X,Y> *partialChild = nodePtr->partialChildren->front();
03817 if ((clientLeftEndmost(nodePtr) == partialChild) ||
03818 (clientRightEndmost(nodePtr) == partialChild))
03819 sequenceCons = true;
03820 }
03821 }
03822
03823 if (sequenceCons)
03824 removeBlock(nodePtr,isRoot);
03825
03826 return sequenceCons;
03827 }
03828
03829
03830
03831
03832
03833
03834
03835
03836
03837
03838
03839
03840
03841
03842
03843
03844
03845
03846
03847
03848
03849
03850
03851
03852
03853
03854
03855
03856
03857
03858
03859
03860
03861
03862
03863
03864
03865
03866
03867
03868
03869
03870
03871
03872
03873
03874
03875
03876
03877
03878
03879
03880
03881
03882
03883
03884
03885
03886
03887
03888
03889
03890
03891
03892 template<class T,class X,class Y>
03893 bool PQTree<T,X,Y>::templateQ3(PQNode<T,X,Y> *nodePtr)
03894 {
03895 if (nodePtr->type() != PQNodeRoot::QNode || nodePtr->partialChildren->size() >= 3)
03896 return false;
03897
03898 bool conssequence = false;
03899 bool found = false;
03900
03901
03902
03903
03904
03905
03906
03907
03908
03909
03910
03911
03912
03913
03914
03915
03916
03917
03918 if (!nodePtr->fullChildren->empty())
03919 {
03920
03921
03922
03923
03924
03925
03926
03927
03928 PQNode<T,X,Y> *fullChild = nodePtr->fullChildren->front();
03929 PQNode<T,X,Y> *fullStart = 0;
03930 PQNode<T,X,Y> *fullEnd = 0;
03931 conssequence = checkChain(nodePtr,fullChild,&fullStart,&fullEnd);
03932 if (conssequence)
03933 {
03934 ListIterator<PQNode<T,X,Y>*> it;
03935 for (it = nodePtr->partialChildren->begin(); it.valid(); ++it)
03936 {
03937 PQNode<T,X,Y> *partial_1 = *it;
03938 found = false;
03939 if ((clientSibLeft(fullStart) == partial_1) ||
03940 (clientSibRight(fullStart) == partial_1) ||
03941 (clientSibLeft(fullEnd) == partial_1) ||
03942 (clientSibRight(fullEnd) == partial_1) )
03943 found = true;
03944 if (!found)
03945 conssequence = found;
03946 }
03947 }
03948 }
03949
03950 else if (nodePtr->partialChildren->size() == 2)
03951 {
03952
03953
03954
03955
03956 PQNode<T,X,Y> *partial_1 = nodePtr->partialChildren->front();
03957 PQNode<T,X,Y> *partial_2 = nodePtr->partialChildren->back();
03958 if ((clientSibLeft(partial_1) == partial_2) ||
03959 (clientSibRight(partial_1) == partial_2) )
03960 found = true;
03961 conssequence = found;
03962 }
03963
03964 if (conssequence)
03965 removeBlock(nodePtr,true);
03966
03967 return conssequence;
03968 }
03969
03970
03971 }
03972
03973 #endif