Open
Graph Drawing
Framework

 v.2012.05
 

PQTree.h
Go to the documentation of this file.
00001 /*
00002  * $Revision: 2299 $
00003  * 
00004  * last checkin:
00005  *   $Author: gutwenger $ 
00006  *   $Date: 2012-05-07 15:57:08 +0200 (Mon, 07 May 2012) $ 
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>* /* nodePtr */) { }
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                       addNewLeavesToTree
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         // Father has children. Brothers expected
00313 
00314         
00315         SListIterator<PQLeafKey<T,X,Y>*> it = leafKeys.begin();
00316         PQLeafKey<T,X,Y>* newKey = *it; //leafKeys[0];
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; //leafKeys[i];
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                       addNodeToNewParent
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         //parent type not valid.
00387 
00388     if (child != 0)
00389     {
00390         OGDF_ASSERT(parent->m_childCount == 0)   
00391             //when adding new nodes: Brothers expected.
00392         child->m_parent = parent;
00393         child->m_parentType = parent->type();
00394         parent->m_childCount++;
00395 
00396         /*
00397         Set the reference pointers in case that [[parent]] is a $P$-node.
00398         If [[parent]] is a $Q$-node, this chunk sets the endmost children 
00399         of [[parent]]. Since [[child]] is the only child of [[parent]] 
00400         both endmost pointers are set to [[child]].
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                       addNodeToNewParent
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             //parent type not valid
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                 The parent is a $P$-node with children.
00484                 Either [[leftBrother]] or [[rightBrother]] stores 
00485                 a pointer to an existing child of [[parent]] and [[parent]] 
00486                 is a $P$-node. In case that two brothers are stored, an 
00487                 arbitrary one is choosen to be the next sibling of [[child]].
00488                 This brother is stored in [[brother]]. The pointer [[sister]]
00489                 denotes a pointer to an arbitrary sibling of [[brother]].
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                 The parent is a $Q$-node with children.
00504                 The [[leftBrother]] is a [[0]]-pointer while the 
00505                 [[rightBrother]] denotes an existing child of [[parent]].
00506                 The node [[rightBrother]] {\bf must be} one of the two endmost 
00507                 children of [[parent]]. If this is not the case, the chunk 
00508                 detects this, halts the procedure [[addNewLeavesToTree]] 
00509                 printing an error message and returning [[0]].
00510                 If [[rightBrother]] is endmost child of [[parent]], then 
00511                 this chunk adds [[child]] at the one end where
00512                 [[rightBrother]] hides. The node [[child]] is then made the
00513                 new endmost child of [[parent]] on the corresponding side.
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                 // missing second brother?
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                 The parent is a $Q$-node with children. 
00535                 The [[rightBrother]] is a [[0]]-pointer while the 
00536                 [[leftBrother]] denotes an existing child of [[parent]]. The 
00537                 node [[leftBrother]] {\bf must be} one of the two endmost 
00538                 children of [[parent]]. If this is not the case, the chunk 
00539                 detects this, halts the procedure [[addNodeToNewParent]] 
00540                 printing an error message and returning [[0]].
00541                 If [[leftBrother]] is endmost child of [[parent]], then this 
00542                 chunk adds [[child]] at the one end where [[leftBrother]] 
00543                 hides. The node [[child]] is then made new endmost child of 
00544                 [[parent]] on the corresponding side.
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                 // missing second brother?
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                 The parent is a $Q$-node with children. 
00566                 Both the [[rightBrother]] and the [[leftBrother]] denote 
00567                 existing children of [[parent]]. In this case, [[leftBrother]] 
00568                 and [[rightBrother]] must be immideate siblings. If this is 
00569                 not the case, this will be detected during the function call
00570                 [[changeSiblings]] of the class [[PQNode.h]] (see 
00571                 \ref{PQNode.changeSiblings}) in the first two lines of this 
00572                 chunk. If the chunk recognizes the failure of 
00573                 [[changeSiblings]] it halts the procedure 
00574                 [[addNewLeavesToTree]], printing an error message and 
00575                 returning [[0]].
00576                 If the two brothers are immediate siblings, this chunk 
00577                 adds [[child]] between the two brothers as interior child of 
00578                 the $Q$-node [[parent]].
00579                 */
00580 #ifdef OGDF_DEBUG
00581                 bool ok =
00582 #endif
00583                     rightBrother->changeSiblings(leftBrother,child) && leftBrother->changeSiblings(rightBrother,child);
00584 
00585                 // brothers are not siblings?
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         The parent is a $Q$-node with children. 
00608         Both the [[rightBrother]] and the [[leftBrother]] denote 
00609         existing children of [[parent]]. In this case, [[leftBrother]] 
00610         and [[rightBrother]] must be immideate siblings. If this is 
00611         not the case, this will be detected during the function call
00612         [[changeSiblings]] of the class [[PQNode.h]] (see 
00613         \ref{PQNode.changeSiblings}) in the first two lines of this 
00614         chunk. If the chunk recognizes the failure of 
00615         [[changeSiblings]] it halts the procedure 
00616         [[addNewLeavesToTree]], printing an error message and 
00617         returning [[0]].
00618         If the two brothers are immediate siblings, this chunk 
00619         adds [[child]] between the two brothers as interior child of 
00620         the $Q$-node [[parent]].
00621         */
00622 #ifdef OGDF_DEBUG
00623         bool ok =
00624 #endif
00625             rightBrother->changeSiblings(leftBrother,child) && leftBrother->changeSiblings(rightBrother,child);
00626 
00627         // brothers are not siblings?
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                            Bubble
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     Enter the [[Full]] leaves into the queue [[processNodes]].
00693     In a first step the pertinent leaves have to be identified in the tree
00694     and entered on to the queue [[processNodes]]. The identification of
00695     the leaves can be done with the help of a pointer stored in every 
00696     [[PQLeafKey]] (see \ref{PQLeafKey}) in constant time for every element. 
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(); //leafKeys[i]->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             No consecutive sequence possible.
00719             The queue [[processNodes]] does not contain any nodes for
00720             processing and the sum of [[blockCount]] and [[offTheTop]] is
00721             greater than 1. If the queue is empty, the root of the pertinent 
00722             subtree was already processed. Nevertheless, there are blocked 
00723             nodes since [[offTheTop]] is either be [[0]] or [[1]], hence 
00724             [[blockCount]] must be at least [[1]]. Such blocked nodes cannot 
00725             form a consecutive sequence with all nodes in the set 
00726             [[leafKeys]]. Observe that this chunk finishes the function 
00727             [[Bubble]]. Hence every memory allocated by the function [[Bubble]] 
00728             has to be deleted here as well.        
00729             */
00730             return false;
00731         /*
00732         If there are still nodes to be processed in which case the queue
00733         [[processNodes]] is not empty, we get the next node from the queue.
00734         By default this node has to be marked as blocked.
00735         */
00736         PQNode<T,X,Y>* checkNode = processNodes.pop();
00737         blockedNodes.push(checkNode);
00738         checkNode->mark(BLOCKED);
00739         blockedSiblings = 0;
00740 
00741         /*
00742         Check if node is adjacent to an unblocked node.
00743         After getting the node [[checkNode]] from the queue, its siblings are 
00744         checked, whether they are unblocked. If they are, then they have a 
00745         valid pointer to their parent and the parent pointer of [[checkNode]] 
00746         is updated.
00747         */
00748         if ((checkNode->m_parentType != PQNodeRoot::PNode) && (checkNode != m_root))
00749                                             // checkNode is son of a QNode.
00750                                             // Check if it is blocked.
00751         {
00752             if (clientSibLeft(checkNode) == 0)
00753                                             // checkNode is endmost child of
00754                                             // a QNode. It has a valid pointer
00755                                             // to its parent.
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                                             // checkNode is endmost child of
00765                                             // a QNode. It has a valid pointer
00766                                             // to its parent.
00767             {
00768                 checkNode->mark(UNBLOCKED);
00769                 if (clientSibLeft(checkNode) && 
00770                     clientSibLeft(checkNode)->mark() == BLOCKED)
00771                     blockedSiblings++;
00772             }
00773              
00774 
00775             else
00776                                             // checkNode is not endmost child of
00777                                             // a QNode. It has not a valid 
00778                                             // pointer to its parent.
00779             {
00780                 if (clientSibLeft(checkNode)->mark() == UNBLOCKED)
00781                                             // checkNode is adjacent to an
00782                                             // unblocked node. Take its parent.
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                                             // checkNode is adjacent to an 
00792                                             // unblocked node. Take its parent.
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                                // checkNode is son of a PNode
00803                                             // and children of P_NODEs
00804                                             // cannot be blocked.
00805             checkNode->mark(UNBLOCKED);
00806 
00807         if (checkNode->mark() == UNBLOCKED)
00808         {
00809             PQNode<T,X,Y>* parent = checkNode->m_parent;
00810 
00811             /*
00812             Get maximal consecutive set of blocked siblings.
00813             This chunk belongs to the procedure [[bubble]].
00814             The node [[checkNode]] is [[UNBLOCKED]].
00815             If the parent of [[checkNode]] is a $Q$-Node, then we check the
00816             siblings [[checkSib]] of [[checkNode]] whether they are 
00817             [[BLOCKED]]. If they are blocked,  they have to be marked 
00818             [[UNBLOCKED]] since they are adjacent to the [[UNBLOCKED]] node 
00819             [[checkNode]]. We then have to proceed with the siblings of 
00820             [[checkSib]] in order to find [[BLOCKED]] nodes
00821             adjacent to [[checkSib]]. This is repeated until no [[BLOCKED]]
00822             nodes are found any more.
00823 
00824             Observe that while running through the children of the $Q$-Node
00825             (referred by the pointer [[parent]]), their parent pointers, 
00826             as well as the [[pertChildCount]] of [[parent]] are updated. 
00827             Furthermore we reduce simultaneously the count [[numBlocked]].  
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                             //Blocked node as endmost child of a QNode.
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                             //Blocked node as endmost child of a QNode.
00862                     }
00863                 }
00864             }// if (blockedSiblings > 0)
00865 
00866 
00867             /*
00868             Process parent of [[checkNode]]
00869             After processing the siblings of the [[UNBLOCKED]] [[checkNode]]
00870             the parent has to be processed. If [[checkNode]] is the root
00871             of the tree we do nothing except setting the flag [[offTheTop]].
00872             If it is not the root and [[parent]] has not been placed onto the
00873             queue [[processNodes]], the [[parent]] is placed on to 
00874             [[processNodes]].
00875 
00876             Observe that the number [[blockCount]] is updated. Since 
00877             [[checkNode]] was [[UNBLOCKED]] all perinent nodes adjacent 
00878             to that node became [[UNBLOCKED]] as well. Therefore the number 
00879             of blocks is reduced by the number of [[BLOCKED]] siblings of 
00880             [[checkNode]].
00881             */
00882             if (parent == 0)
00883                                            // checkNode is root of the tree.
00884                 offTheTop = 1;
00885             else
00886                                            // checkNode is not the root.
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         }//if (checkNode->mark() == UNBLOCKED)
00901 
00902         else
00903         {
00904             /*
00905             Process blocked [[checkNode]]
00906             Since [[checkNode]] is [[BLOCKED]], we cannot continue 
00907             processing at this point in the Tree. We have to wait until 
00908             this node becomes unblocked. So only the variables 
00909             [[blockCount]] and [[numBlocked]] are updated. 
00910             */
00911             blockCount += 1 - blockedSiblings;
00912             numBlocked++;
00913         }
00914 
00915     }//while ((processNodes.size() + blockCount + offTheTop) > 1)
00916 
00917     if (blockCount == 1)
00918     {
00919         /*
00920         If [[blockCount]] $= 1$ enter [[m_pseudoRoot]] to the tree
00921         In case that the root of the pertinent subtree is a $Q$-node 
00922         with empty children on both sides and the pertinent children 
00923         in the middle, it is possible that the $PQ$-tree is reducible. 
00924         But since the sequence of pertinent children of the $Q$-node is 
00925         blocked, the procedure is not able to find the parent of its 
00926         pertinent children. This is due to the fact that the interior
00927         children of a $Q$-node do not have a valid parent pointer.
00928 
00929         So the root of the pertinent subtree is not known, hence cannot be 
00930         entered into the processing queue used in the function call [[Reduce]]
00931         (see \ref{Reduce}). To solve this problem a special node only designed 
00932         for this cases is used: [[m_pseudoRoot]]. It simulates the root of the 
00933         pertinent subtree. This works out well, since for this node the only 
00934         possible template maching is [[templateQ3]] (see \ref{templateQ3}), 
00935         where no pointers to the endmost children of a $Q$-node are used. 
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                     //Blocked node as endmost child of a QNode.
00947             }
00948         }
00949     }
00950 
00951     return true;
00952 }
00953 
00954 
00955 /************************************************************************
00956                           checkChain
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--;                    // firstFull does have a FULL label.
01013 
01014     /*
01015     Start at the [[firstFull]] child sweeping through the full children on 
01016     the left side of [[firstfull]]. It stops as soon as a nonfull child is 
01017     detected. The last found full child is stored in [[seqEnd]].
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                                        // There are still full children to be
01031                                        // counted, and no empty child has been
01032                                        // encountered on this side.
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                 //searching consecutive sequence in Q2 or Q3.
01048                 OGDF_ASSERT(leftOld != 0 && leftOld->status() == FULL);
01049                 (*seqEnd) = leftOld;
01050             }
01051 
01052         } else {
01053             (*seqEnd) = firstFull;
01054         }
01055     }
01056 
01057     /*
01058     Start at the [[firstFull]] child sweeping through the full children on 
01059     the right side of [[firstfull]]. It stops as soon as a nonfull child is 
01060     detected.
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                                        // There are still full children to be
01075                                        // counted, and no empty child has been
01076                                        // encountered on this side.
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                      //searching consecutive seqeuence in Q2 or Q3.
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                                     // All full children occupy a consecutive
01111                                     // sequence.
01112         return true;
01113     else
01114         return false;
01115 }
01116 
01117 
01118 /************************************************************************
01119                           checkIfOnlyChild
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)         // parent is not the root.
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                          Cleanup
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         Process the [[m_root]] of the [[PQTree]]. Before deleting [[m_root]],
01215         pointers to all its children are stored in the queue [[helpqueue]].
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             Process an arbitrary node [[checkNode]] of the [[PQTree]].
01262             Before deleting [[checkNode]],
01263             pointers to all its children are stored in the queue [[helpqueue]].
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                         clientPrintNodeCategorie
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         // 1 is the standard node categrie in the Tree Interface.
01341 }
01342 
01343 
01344 /************************************************************************
01345                         clientPrintStatus
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                         clientPrintType
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                          Constructor
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                      copyFullChildrenToPartial
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                                         // There are some full children to
01430                                         // be copied.
01431     {
01432         nodePtr->m_childCount = nodePtr->m_childCount -
01433                                 nodePtr->fullChildren->size();
01434 
01435         PQNode<T,X,Y> *newNode = createNodeAndCopyFullChildren(nodePtr->fullChildren);
01436 
01437                                          // Introduce newNode as endmost
01438                                          // child of the partial Q-node.
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             // ERROR: Endmostchild not found?
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                      createNodeAndCopyFullChildren
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         There is just one full child. So no new $P$-node is created. The
01503         full child is copied as child to the [[partialChild]].
01504         */
01505         newNode = fullNodes->popFrontRet();
01506         removeChildFromSiblings(newNode);
01507     }
01508    
01509     else
01510     {
01511         /*
01512         This chunk belongs to the function [[createNodeAndCopyFullChildren]].
01513         There is more than one full child, so a new $P$-node is created.
01514         This chunk first allocates the memory for the new $P$-node that will
01515         be stored in [[newNode]]. Then it pops the nodes out of the stack 
01516         [[fullNodes]] and introduces them as sons of [[newNode]].
01517         Popping the nodes out of the stack implies at the same time
01518         that they are removed from the [[fullChildren]] stack of the
01519         $P$-node of their parent.
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         The first node is copied separately, since we need the pointer to it 
01528         for setting the pointers to the siblings of the next full nodes.
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         All remaining nodes that are stored in the stack [[fullNodes]] are
01540         introduced as children of the new $P$-node [[newNode]]. Observe
01541         that the children of a $P$-node must form a doubly linked list.
01542         Hence the last node and the [[firstSon]] must be linked via their 
01543         siblings pointers.
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                  emptyAllPertinetNodes
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                 //if (nodePtr)
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                         emptyNode
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                      exchangeNodes
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         The node [[oldNode]] is connected to its parent
01668         via the reference pointer of the doubly linked list. The [[newNode]]
01669         will be the new reference child and is linked via the reference
01670         pointers to the $P$-node.
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         The [[oldNode]] is endmost child of a Q-node. So its parent 
01681         contains an extra pointer to [[oldNode]]. Link the parent of 
01682         [[oldNode]] to [[newNode]] via this pointer and make [[newNode]] 
01683         endmost child of its new parent.
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         Two possible cases are occured.
01695         \begin{enumerate}
01696         \item [[oldNode]] is the only child of a $P$-node. In order to
01697         implement the doubly linked list of children of the $P$-node, the sibling
01698         pointers of [[newNode]] are set to [[newNode]].
01699         \item [[oldNode]] is the [[m_root]] of the $PQ$-tree. Since
01700         by our definition of the $PQ$-tree the sibling pointers of the
01701         [[m_root]] point to the root itself, (i.e. to make sure that 
01702         checking for the endmost child property is also valid for the root)
01703         the sibling pointers of [[newNode]] are set to [[newNode]] as well.
01704         \end{enumerate}
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         //sibling pointers of old node are not compatible
01723         OGDF_ASSERT(!(oldNode->m_sibRight == oldNode))
01724         //sibling pointers of old node are not compatible.
01725     }
01726     /*
01727     Manage the exchange of [[oldNode]] and [[newNode]] according to
01728     [[oldNode]]'s siblings. The chunk checks both siblings of
01729     [[oldNode]] and resets the sibling pointers of [[oldNode]]'s siblings
01730     as well as the sibling pointers of [[newNode]].
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             // Sibling was not connected to child?
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             // Sibling was not connected to child?
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                         front
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                          Initialize
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()) // at least two elements
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                        linkChildrenOfQnode
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             // endmost child with 2 siblings encountered?
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                  writeGML
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"; // graphics
02014         os << "]\n"; // node
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"; // edge
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"; // edge
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"; // edge
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"; // edge
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"; // edge
02123 
02124                 }
02125             }
02126         }
02127     }
02128     os << "]\n"; // graph
02129 }
02130 
02131 
02132 
02133 /************************************************************************
02134                             Reduce
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     In a first step the pertinent leaves have to be identified in the tree
02188     and are entered on to the queue [[processNodes]]. The identification of
02189     the leaves can be done with the help of a pointer stored in every 
02190     [[PQLeafKey]] in constant time for every element.   
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             Application of the template matchings to a pointer [[checkNode]] 
02211             storing the adress of a node that is {\bf not the root} of the 
02212             pertinent subtree. Before applying the template matchings to 
02213             [[checkNode]], some values of the parent of [[checkNode]] are 
02214             updated. The number of the parents pertinent children stored in 
02215             [[pertChildCount]] is count down by one. In case that 
02216             [[checkNode->m_parent->m_pertChildCount == 0]], we know that all 
02217             pertinent children of the parent have been processed. Since the 
02218             parent then is allowed to be processed as well, 
02219             [[checkNode->m_parent]] is stored in the queue [[processNodes]].
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             application of the template matchings to a pointer [[checkNode]] 
02240             that stores the adress of a node that {\bf is the root} of the 
02241             pertinent subtree. In a case that a template matching was 
02242             successfully applied, the pointer [[checkNode]] stores after the 
02243             application the adress of the root of pertinent subtree. This 
02244             includes nodes that have been newly introduced as root of the 
02245             perinent subtree during the application. If no template matching 
02246             was successfully applied [[checkNode]] is a [[0]] pointer.
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                          Reduction
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                           removeBlock
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     For every
02325     partial child we keep a set of pointers. Since there are at most
02326     two partial children, we initialize two sets. Every set contains
02327     besides a pointer to the partial child four pointers to its endmost 
02328     children, sorted according to their full or empty labels and pointers 
02329     to the immediate siblings of the partial child, also sorted according
02330     to their full or empty labels.
02331     */
02333     PQNode<T,X,Y> *partial_1 = 0;
02334     
02335     /*
02336     Pointer to the full endmost child (more
02337     precisely: to the endmost child appearing on the full side) of
02338     [[partial_1]]. In case that ignored nodes are used, this [[endfull_1]]
02339     may store the adress of an ignored node.
02340     */
02341     PQNode<T,X,Y> *endfull_1 = 0;
02342     
02343     /*
02344     Pointer to the empty endmost child  (more
02345     precisely: to the endmost child appearing on the empty side) of
02346     [[partial_1]]. In case that ignored nodes are used, this [[endempty_1]]
02347     may store the adress of an ignored node.
02348     */
02349     PQNode<T,X,Y> *endempty_1 = 0;
02350     
02351     /*
02352     Pointer to the first {\it non ignored} node 
02353     with full status. [[realfull_1]] is identical to [[endfull_1]] if no
02354     ignored nodes appear at the full end of the first partial child.    
02355     */
02356     PQNode<T,X,Y> *realfull_1 = 0;
02357     
02358     /*
02359     Pointer to the first {\it non ignored} node 
02360     with empty status. [[realempty_1]] is identical to [[endempty_1]] if no
02361     ignored nodes appear at the empty end of the first partial child.  
02362     */
02363     PQNode<T,X,Y> *realempty_1 = 0;
02364 
02365     // Pointer to the second partial child.
02366     PQNode<T,X,Y> *partial_2 = 0;
02367     
02368     /*
02369     Pointer to the full endmost child (more
02370     precisely: to the endmost child appearing on the full side) of
02371     [[partial_2]]. In case that ignored nodes are used, this [[endfull_2]]
02372     may store the adress of an ignored node.
02373     */
02374     PQNode<T,X,Y> *endfull_2 = 0;
02375 
02376     /*
02377     Pointer to the empty endmost child  (more
02378     precisely: to the endmost child appearing on the empty side) of
02379     [[partial_2]]. In case that ignored nodes are used, this [[endempty_2]]
02380     may store the adress of an ignored node.
02381     */
02382     PQNode<T,X,Y> *endempty_2 = 0;
02383     
02384     /*
02385     Pointer to the first {\it non ignored} node 
02386     with full status. [[realfull_2]] is identical to [[endfull_2]] if no
02387     ignored nodes appear at the full end of the first partial child. 
02388     */
02389     PQNode<T,X,Y> *realfull_2 = 0;
02390     
02391     /*
02392     Pointer to the first {\it non ignored} node 
02393     with empty status. [[realempty_2]] is identical to [[endempty_2]] if no
02394     ignored nodes appear at the empty end of the first partial child.  
02395     */
02396     PQNode<T,X,Y> *realempty_2 = 0;
02397       
02398     /*
02399     Pointer to a full sibling of
02400     [[partial_1]], if it exists. In case that ignored nodes are used 
02401     this [[sibfull_1]] stores the direct sibling of [[partial_1]]
02402     on the side where the full siblings are. Hence [[sibfull_1]] may
02403     store an ignored node.
02404     */
02405     PQNode<T,X,Y> *sibfull_1 = 0; 
02406     
02407     /*
02408     Pointer to a partial sibling of
02409     [[partial_1]], if it exists. In case that ignored nodes are used 
02410     this [[sibpartial_1]] stores the direct sibling of [[partial_1]]
02411     on the side where a partial sibling is. Hence [[sibpartial_1]] may
02412     store an ignored node.
02413     */
02414     PQNode<T,X,Y> *sibpartial_1 = 0;
02415     
02416     /*
02417     Pointer to an empty sibling of
02418     [[parial_1]], if it exists. In case that ignored nodes are used 
02419     this [[sibempty_1]] stores the direct sibling of [[partial_1]]
02420     on the side where the empty siblings are. Hence [[sibempty_1]] may
02421     store an ignored node.
02422     */
02423     PQNode<T,X,Y> *sibempty_1 = 0;  
02424     
02425     /*
02426     Pointer only used in case that [[partial_1]] has
02427     no non-ignored siblings on one side. [[partial_1]] then is endmost child
02428     of [[nodePtr]], but ignored children may appear between [[partial_1]]
02429     and the end of sequence of children of [[nodePtr]]. The
02430     [[nonstatussib_1]] then stores the adress of the endmost ignored child.
02431     Observe that it is not valid for a $Q$-node to have only one
02432     non-ignored child and several ignored children. Hence this situation
02433     is only allowed to appear {\bf once} on one side of [[partial_1]]. 
02434     Every other situation results in an error message.  
02435     */
02436     PQNode<T,X,Y> *nonstatussib_1 = 0;
02437 
02438     /*
02439     Pointer to a full sibling of
02440     [[partial_2]], if it exists. In case that ignored nodes are used 
02441     this [[sibfull_2]] stores the direct sibling of [[partial_2]]
02442     on the side where the full siblings are. Hence [[sibfull_2]] may
02443     store an ignored node.
02444     */
02445     PQNode<T,X,Y> *sibfull_2 = 0;   
02446     
02447     /*
02448     Pointer to a partial sibling of
02449     [[partial_2]], if it exists. In case that ignored nodes are used 
02450     this [[sibpartial_2]] stores the direct sibling of [[partial_2]]
02451     on the side where a partial sibling is. Hence [[sibpartial_2]] may
02452     store an ignored node.
02453     */
02454     PQNode<T,X,Y> *sibpartial_2 = 0;
02455     
02456     /*
02457     Pointer to an empty sibling of
02458     [[parial_2]], if it exists. In case that ignored nodes are used 
02459     this [[sibempty_2]] stores the direct sibling of [[partial_2]]
02460     on the side where the empty siblings are. Hence [[sibempty_2]] may
02461     store an ignored node.
02462     */
02463     PQNode<T,X,Y> *sibempty_2 = 0;  
02464     
02465     /*
02466     Pointer only used in case that [[partial_2]] has
02467     no non-ignored siblings on one side. [[partial_2]] then is endmost child
02468     of [[nodePtr]], but ignored children may appear between [[partial_2]]
02469     and the end of sequence of children of [[nodePtr]]. The
02470     [[nonstatussib_2]] then stores the adress of the endmost ignored child.
02471     Observe that it is not valid for a $Q$-node to have only one
02472     non-ignored child and several ignored children. Hence this situation
02473     is only allowed to appear {\bf once} on one side of [[partial_2]]. 
02474     Every other situation results in an error message.
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     [[endmostcheck]] is [[1]], if [[partial_1]] is the endmost
02486     child of [[nodePtr]]. Per default, [[endmostcheck]] is [[0]].
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                                                 // Get a partial child.
02497     {
02498         partial_1 = nodePtr->partialChildren->popFrontRet();
02499 
02500                                                 // Get the full and empty 
02501                                                 // endmost children of the 
02502                                                 // partial child [[partial_1]].
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             // partial child with no full endmost child detected?
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             // partial child with no empty endmost child detected?
02525             OGDF_ASSERT(checkVarRight->status() == EMPTY);
02526         
02527             endempty_1  = partial_1->m_rightEndmost;
02528             realempty_1 = checkVarRight;
02529         }
02530 
02531                                                 // Get the immediate 
02532                                                 // siblings of the partial 
02533                                                 // child [[partial_1]].
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             // partial child detected with no siblings of valid status?
02557             OGDF_ASSERT(nonstatussib_1 == 0);
02558             nonstatussib_1 = partial_1->m_sibRight;
02559         }
02560     }
02561 
02562 
02563     if (!nodePtr->partialChildren->empty())
02564                                             // There is a second partial child.
02565     {
02566         partial_2 = nodePtr->partialChildren->popFrontRet();
02567                                             // Get the full and empty endmost 
02568                                             // children of the partial 
02569                                             // child [[partial_2]].
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             // partial child with no full endmost child detected?
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             // partial child with no empty endmost child detected?
02593             OGDF_ASSERT(checkVarRight->status() == EMPTY);
02594         
02595             endempty_2 = partial_2->m_rightEndmost;
02596             realempty_2 = checkVarRight;
02597         }
02598                                                 // Get the immediate siblings 
02599                                                 // of the partial child 
02600                                                 // [[partial_2]].
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     Connect the endmost
02634     children of the partial children [[partial_1]] and [[partial_2]] correctly
02635     with their new siblings. In doing this, all children of the partial
02636     children become children of [[nodePtr]]. The reader should observe that
02637     the parent pointers of the interior children of [[partial_1]] and 
02638     [[partial_2]] are not updated in order to hit the linear time complexity.
02639 
02640     When including the children of the partial children to the children
02641     of [[nodePtr]], it is taken care that all full children
02642     form a consecutive sequence afterwards. If neccessary the pointers to the
02643     endmost children of [[nodePtr]] are updated.
02644     */
02645     {
02646         if (sibfull_1 != 0 && sibfull_2 != 0)
02647                                           // There are full children  between
02648                                           // the 2 partial nodes.
02649                                           // Connect the full children
02650                                           // between the 2 partial children
02651                                           // with the full endmost children
02652                                           // of the 2 partial nodes.
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                                           // There are no full children between
02662                                           // the 2 partial nodes. Connect the
02663                                           // full endmost children of the
02664                                           // partial nodes as siblings.
02665         {
02666             if (partial_1 == sibpartial_2 && partial_2 == sibpartial_1)
02667                                           // Regular Case.
02668             {
02669                 endfull_1->putSibling(endfull_2);
02670                 endfull_2->putSibling(endfull_1);
02671             }
02672                                           // Only ignored children between 
02673                                           // partial_1 and partial_2. 
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                                             // Include the children of the 
02684                                             // partial children with their
02685                                             // full nodes inbetween into
02686                                             // the sequence of the children of
02687                                             // Q-node nodePtr.
02688         if (sibempty_1 == 0)
02689                                             // partial_1 is endmost child of
02690                                             // nodePtr. Make the empty endmost
02691                                             // child of partial_1 be the new 
02692                                             // endmost child of nodePtr.
02693         {
02694             if (nonstatussib_1 == 0)
02695                                             // Regular case.
02696             {
02697                 nodePtr->changeEndmost(partial_1,endempty_1);
02698             }
02699             else
02700                                           // Only ignored children between 
02701                                           // partial_1 and one end of nodePtr. 
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                                             // partial_1 is not endmost child.
02712         {
02713             sibempty_1->changeSiblings(partial_1,endempty_1);
02714             endempty_1->putSibling(sibempty_1);
02715         }
02716 
02717 
02718         if (sibempty_2 == 0)
02719                                             // partial_2 is endmost child of
02720                                             // nodePtr. Make the empty endmost
02721                                             // child of partial_2 be the new 
02722                                             // endmost child of nodePtr.
02723         {
02724             if (nonstatussib_2 == 0)
02725                                             // Regular case.
02726             {
02727                 nodePtr->changeEndmost(partial_2,endempty_2);
02728             }
02729             else
02730                                             // Only ignored children between 
02731                                             // partial_1 and one end of 
02732                                             // nodePtr. 
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                                             // partial_2 is not endmost child.
02743         {
02744             sibempty_2->changeSiblings(partial_2,endempty_2);
02745             endempty_2->putSibling(sibempty_2);
02746         }
02747 
02748                                             // Copy the full children of 
02749                                             // partial_1 and partial_2 to 
02750                                             // nodePtr.
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     Connect the endmost
02775     children of the partial child [[partial_1]] correctly
02776     with their new siblings. In doing this, all children of the partial
02777     child become children of [[nodePtr]]. The reader should observe that
02778     the parent pointers of the interior children of [[partial_1]] 
02779     are not updated in order to hit the linear time complexity.
02780 
02781     When including the children of [[partial_1]] to the children
02782     of [[nodePtr]], it is taken care that all full children
02783     form a consecutive sequence afterwards. If necessary the pointers to the
02784     endmost children of [[nodePtr]] are updated.    
02785     */
02786     
02787     {
02788         if ((clientLeftEndmost(nodePtr) == partial_1) ||
02789             (clientRightEndmost(nodePtr) == partial_1))
02790                                             // partial_1 is endmost child.
02791             endmostcheck = 1;
02792                
02793         if (sibfull_1 != 0)
02794                                             // There are full children on one
02795                                             // side of the partial node.
02796                                             // Connect the full children with
02797                                             // the full endmost child of 
02798                                             // partial_1.
02799         {
02800             sibfull_1->changeSiblings(partial_1,endfull_1);
02801             endfull_1->putSibling(sibfull_1);
02802         }
02803 
02804         else if (!endmostcheck)
02805                                             // There are not any full children
02806                                             // and partial_1 is not endmost.
02807                                             // So get the 2nd empty sibling
02808                                             // of partial_1 and connect it
02809                                             // to the full endmost child
02810                                             // of partial_1.
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                                             // partial_1 is endmost child
02823                                             // and there are no full children.
02824                                             // Make the full endmost child of 
02825                                             // partial_1 be the endmostchild
02826                                             // of nodePtr.
02827         {
02828 
02829             if (nonstatussib_1 == 0)
02830                                             // Regular case.
02831             {
02832                 nodePtr->changeEndmost(partial_1,endfull_1);
02833             }
02834             else
02835                                             // Only ignored children between 
02836                                             // partial_1 and one end of 
02837                                             // nodePtr. 
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                                             // There are no empty children.
02849                                             // partial_1 is endmost child of
02850                                             // nodePtr. Make the empty endmost
02851                                             // child of partial_1 be the new 
02852                                             // endmost child of nodePtr.
02853         {
02854             if (nonstatussib_1 == 0)
02855                                             // Regular case.
02856             {
02857                 nodePtr->changeEndmost(partial_1,endempty_1);
02858             }
02859             else
02860                                             // Only ignored children between 
02861                                             // partial_1 and one end of 
02862                                             // nodePtr. 
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                                             // There are empty children. So 
02873                                             // connect the empty endmost child
02874                                             // of partial_1 with sibempty_1.
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     // else nodePtr does not have partial children. Then nothing is to do. 
02891 }
02892 
02893 
02894 /************************************************************************
02895                      removeChildFromSiblings
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         Checksif [[nodePtr]] is connected with its parent via the reference
02915         pointers (see \ref{PQNode}). If so, the next sibling of [[nodePtr]]
02916         will be the the new reference child.
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         Check if [[nodePtr]] is the endmost child of a $Q$-node.
02928         If so, the next sibling of [[nodePtr]] will be the the new endmost
02929         child of the $Q$-node. Observe that the sibling then gets a valid
02930         pointer to its parent.
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     Remove [[nodePtr]] from its immediate siblings and links the
02943     siblings via the [[sibRight]] and [[sibLeft]] pointers.
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             // Sibling was not connected to child?
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             // Sibling was not connected to child?
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                  removeNodeFromTree
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         //parent is invalid 0-pointer.
03038         return -1;
03039     }   
03040 }
03041 
03042 
03043 /************************************************************************
03044                        sortExceptions
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                           templateL1
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                           templateP1
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                           templateP2
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                                    // Gather all full children of nodePtr
03191                                    // as children of the new P-node.
03192                                    // Delete them from nodePtr.
03193 
03194     PQNode<T,X,Y> *newNode = createNodeAndCopyFullChildren((*nodePtr)->fullChildren);
03195                                    // Correct parent-pointer and
03196                                    // sibling-pointers of the new P-node.
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                                    // The new P-node now is the root of
03205                                    // the pertinent subtree.
03206     (*nodePtr) = newNode;
03207 
03208     return true;
03209 }
03210 
03211 
03212 /************************************************************************
03213                           templateP3
03214 ************************************************************************/ 
03215 
03216 /*
03217  * The function templateP3() implements the template matching for a
03218  * P-node with full \b and empty children that is \b not the root of
03219  * the pertinent subtree.
03220  * The function requires as input any pointer to a node stored in
03221  * \ nodePtr. If the node stored in \a nodePtr is a P-node with
03222  * no partial children,
03223  * templateP3() considers itself responsible for the node and will
03224  * apply the template matching \b P3 to \a nodePtr.
03225  * Observe that the user calling this function has to make sure that
03226  * \a nodePtr is partial and is not the root of the pertinent subtree.
03227  *
03228  * If templateP3() was responsible for \a nodePtr and the
03229  * reduction was successful, the return value is 1. Otherwise
03230  * the return value is 0.
03231  *
03232  * The function templateP3() creates
03233  * a new full P-node, stored in \a newPnode and copies the full children
03234  * of \a nodePtr to \a newPnode. \a nodePtr keeps all empty children
03235  * and will be labeled empty. A new partial Q-node will be created and stored
03236  * in \a newQnode. \a newQnode is placed at the position of \a nodePtr
03237  * in the tree and gets two children: \a nodePtr itself and the newly
03238  * created \a newPnode.
03239  *
03240  * The function templateP3() uses a few variables.
03241  *   - \a newPnode is the pointer to the new P-node, or, in case
03242  *     that \a nodePtr has only one full child, is the pointer of this child.
03243  *   - \a newQnode is the pointer to the new Q-node.
03244  *   - \a newNode is used for the proper allocation of the new
03245  *     Q-node.
03246  *   - \a emptyNode is a pointer to any empty child of nodePtr.
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     Create a new partial $Q$-node stored in [[newQnode]].
03257     It replaces [[nodePtr]] by the Q-node [[newQnode]] in the $PQ$-tree
03258     and makes [[nodePtr]] endmost child of [[newQnode]].
03259     This is done by updating parent-pointers and sibling-pointers. 
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     Create a new full $P$-node stored in [[newPnode]].
03274     It copies the full children of [[nodePtr]] to [[newPnode]].
03275     The new $P$-node will then be included into the tree as child of
03276     the new $Q$-node [[newQnode]].
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                                        // Update newQnode.
03287         newQnode->m_childCount++;
03288         newQnode->fullChildren->pushFront(newPnode);
03289                                        // Update sibling pointers.
03290         nodePtr->m_sibRight = newPnode;
03291         newPnode->m_sibLeft = nodePtr;
03292         newQnode->m_rightEndmost = newPnode;
03293         newPnode->m_parent = newQnode;
03294     }
03295 
03296                                   // Check if nodePtr contains
03297                                   // only one son. If so, nodePtr
03298                                   // will be deleted from the tree.
03299     PQNode<T,X,Y> *emptyNode = nodePtr->m_referenceChild;
03300     checkIfOnlyChild(emptyNode,nodePtr);
03301                                   // Update partialchildren stack of
03302                                   // the parent of the new Q-node.
03303     newQnode->m_parent->partialChildren->pushFront(newQnode);      
03304 
03305     return true;
03306 }
03307 
03308 
03309 /************************************************************************
03310                           templateP4
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                                   // If nodePtr does not have any
03349                                   // empty children, then it has to
03350                                   // be deleted and the partial node
03351                                   // is occupying its place in the tree.
03352     checkIfOnlyChild(partialChild,*nodePtr);
03353                                   // The partial child now is
03354                                   // root of the pertinent subtree.
03355     *nodePtr = partialChild;
03356 
03357     return true;
03358 }
03359 
03360 
03361 /************************************************************************
03362                           templateP5
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     Remove [[partialChild]] from the children of [[nodePtr]]. The node
03409     [[partialChild]] then occupies the position of [[nodePtr]] in the 
03410     $PQ$-tree which is done in the function call [[exchangeNodes]] 
03411     (\ref{exchangeNodes}). The chunk then removes all full children from 
03412     [[nodePtr]] and adds them as children of a new $P$-node as endmost
03413     child of [[partialChild]]. This is done in the function call
03414     [[copyFullChildrenToPartial]] (\ref{copyFullChildrenToPartial}).
03415     When this chunk has finished, [[nodePtr]] has only empty children.
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         Check if [[nodePtr]] has just one empty child. If so, the child 
03429         is stored in [[emptyNode]] in order to be added to the empty
03430         side of the partial $Q$-node [[partialChild]]. If [[nodePtr]] 
03431         has more than one empty child, [[nodePtr]] is stored in 
03432         [[emptyNode]] in order to be added to the empty
03433         side of the partial $Q$-node [[partialChild]].
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         Check at which side of [[partialChild]]
03448         the empty children hide. [[emptyNode]] stores the empty node
03449         that is added to the empty side of [[partialChild]].
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             // Endmostchild not found?
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                                    // If nodePtr did not have any empty
03471                                    // children it has to be deleted.
03472     if (emptyChildCount <= 1)
03473         destroyNode(nodePtr);
03474 
03475     return true;
03476 }
03477 
03478 
03479 /************************************************************************
03480                           templateP6
03481 ************************************************************************/ 
03482 
03524 template<class T,class X,class Y>
03525 bool PQTree<T,X,Y>::templateP6(PQNode<T,X,Y> **nodePtr)
03526 {
03527     //PQNode<T,X,Y>  *partial_1       = 0;
03528     //PQNode<T,X,Y>  *partial_2       = 0;
03529     //PQNode<T,X,Y>  *fullEnd_1       = 0;
03530     //PQNode<T,X,Y>  *fullEnd_2       = 0;
03531     //PQNode<T,X,Y>  *emptyEnd_2      = 0;
03532     //PQNode<T,X,Y>  *realEmptyEnd_2  = 0;   
03533 
03534     if ((*nodePtr)->type() != PQNodeRoot::PNode   ||
03535         (*nodePtr)->partialChildren->size() != 2)
03536         return false;
03537       
03538     /*
03539     Get the partial children of [[nodePtr]] and removes the second 
03540     partial child stored in [[partial_2]] from the children of 
03541     [[nodePtr]]. If there are any full children of [[nodePtr]], the 
03542     chunk removes them from the children of [[nodePtr]] and copies them 
03543     as children to a new $P$-node. This new $P$-node is then made
03544     endmost child of [[partial_1]].
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     Check the endmost children of the two partial children of [[nodePtr]]
03555     and stores them at approriate places, remembering what kind of type
03556     the endmost children are.       
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         // partial child with no FULL endmost child detected?
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         // partial child with no FULL or EMPTY endmost child detected?
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         // partial child with no FULL or EMPTY endmost child detected?
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         //partial child with same type of endmost child detected
03592 
03593     /*
03594     The children of [[partial_2]] are removed from their parent and
03595     added as children to [[partial_1]]. This is done by resetting the
03596     sibling pointers of the two endmost children of [[partial_1]] and
03597     [[partial_2]] and the endmost child pointers of [[partial_1]].
03598     Observe that the parent pointers are not updated. The node
03599     [[partial_2]] is deleted.
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                                   // If nodePtr does not have any
03622                                   // empty children, then it has to
03623                                   // be deleted and the partial node
03624                                   // is occupying its place in the tree.
03625     checkIfOnlyChild(partial_1,*nodePtr);
03626                                 // partial_1 is now root of the
03627                                 // pertinent subtree.
03628     *nodePtr = partial_1;
03629 
03630     return true;
03631 }
03632 
03633 
03634 /************************************************************************
03635                           templateQ1
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                           templateQ2
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         Get a full endmost child of
03758         the $Q$-node [[nodePtr]] if there exists one.
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         In case that a full endmost child of [[nodePtr]] exists, this 
03776         child has been stored in [[fullNode]] and the chunk checks by 
03777         calling the function [[checkChain]] (\ref{checkChain}), if all
03778         full children of [[nodePtr]] form a consecutive sequence.
03779         In case that the full children
03780         of [[nodePtr]] form a consecutive sequence the
03781         return value of [[checkChain]] is [[1]]. If a partial child
03782         stored in [[partialChild]] exists, the chunk checks if
03783         [[partialChild]] is adjacent to the sequence of full children.
03784         If the latter case is [[1]], the flag [[sequenceCons]] is 
03785         set to [[1]] and the function [[templateQ2]] is allowed to 
03786         reduce the pertient children of [[nodePtr]].
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             If the $Q$-node [[nodePtr]] has no full children but one 
03809             partial child this chunk checks, if the partial child is 
03810             endmost child of the [[nodePtr]]. If this is not the case, 
03811             [[nodePtr]] cannot be reduced by the template matching 
03812             {\bf Q2}.
03813             */
03814             //nodePtr->partialChildren->startAtBottom();
03815             //partialChild = nodePtr->partialChildren->readNext();
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                           templateQ3
03832 ************************************************************************/ 
03833 
03834 /*
03835  * The function templateQ3() implements the template matching for
03836  * Q-nodes with empty and/or partial children at both ends and a sequence
03837  * of full and/or partial children in the middle. The Q-node must be the
03838  * root of the pertinent subtree.
03839  * The function requires as input any pointer to a node stored in
03840  * \a nodePtr. If the node stored in \a nodePtr is a Q-node 
03841  * with empty and/or partial children at both ends and a sequence
03842  * full or partial children in the middle,
03843  * templateQ3() considers itself responsible for the node and will
03844  * apply the template matching \b Q3 to \a nodePtr.
03845  * Observe that the user calling this function has to make sure that
03846  * \a nodePtr is the root of the pertinent subtree.
03847  *
03848  * If templateQ3() was responsible for \a nodePtr and the
03849  * reduction was successful, the return value is 1. Otherwise
03850  * the return value is 0.
03851  *
03852  * Below a short description is given of all different cases that
03853  * may occure and are handled by the function templateQ3(), \b regardless
03854  * whether the Q-node \a nodePtr is the root of the pertinent subtree or not.
03855  * The description is somewhat trunkated and should be understood as a
03856  * stenographic description of the labels of the children of \a nodePtr
03857  * when running through the children from one side to the other. Of course
03858  * we leave the mirror-images out.
03859  *   - empty, full, empty
03860  *   - empty, partial, full, partial, empty
03861  *   - empty, partial, full, empty
03862  *   - empty, partial, full, partial
03863  *   - partial, full, partial
03864  *   - empty, partial, partial, empty
03865  *   - empty, partial, partial
03866  *   - partial, partial
03867  *
03868  * The function templateQ3() uses the following variables.
03869  *   - \a fullChild is a pointer to an arbitrary full child of \a nodePtr.
03870  *   - \a fullStart is a pointer to the first full child of a
03871  *     consecutive sequence of full children.
03872  *   - \a fullEnd is a pointer to the last full child of a
03873  *     consecutive sequence of full children.
03874  *   - \a partial_1 is a pointer to the first partial child of \a nodePtr.
03875  *   - \a partial_2 is a pointer to the second partial child of \a nodePtr.
03876  *   - \a conssequence is 1 if the pertinent children of
03877  *     \a nodePtr form a consecutive sequence with at most one partial
03878  *     child at every end of the sequence.
03879  *   - \a found is a help variable.
03880  *
03881  * templateQ3() first checks if one of the above mentioned cases
03882  * occures and then applies the neccessary template matching.
03883  * No special action has to be performed for the full nodes. If there exist
03884  * one or two partial children which will be stored in \a partial_1
03885  * or \a partial_2, their children
03886  * are made children of \a nodePtr. So to say, \a partial_1 and
03887  * partial_2 are lifted up to the Q-node \a nodePtr
03888  * and the occurance of their children
03889  * is fixed within the children of \a nodePtr.
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     Check ifthe
03903     pertinent children of [[nodePtr]] form a consecutive sequence. We
03904     differ between two cases:
03905     \begin{enumerate}
03906     \item There exist full children of [[nodePtr]]. First check with
03907     the function [[checkChain]] (\ref{checkChain}) if the full children
03908     form a consecutive sequence. In case that the check was
03909     successful, check if each partial child is adjacent to a full child.
03910     If both checks were successful, the pertient children form a
03911     consecutive sequence.
03912     \item There do not exist full children. Check if the partial
03913     children (there are at most two of them) form a consecutive sequence.
03914     If the test was successful, the pertinent children form a
03915     consecutive sequence.
03916     */
03917     
03918     if (!nodePtr->fullChildren->empty())
03919     {
03920         /*
03921         A consecutive
03922         sequence of full children has been detected, containing all full
03923         children of [[nodePtr]]. The chunk checks if each partial child 
03924         of [[nodePtr]] is adjacent to a full child. Observe that the 
03925         function [[templateQ3]] only reaches this chunk when [[nodePtr]] 
03926         has less than three partial children.
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         In case that the node [[nodePtr]] does not have any full children,
03954         this chunk checks if the partial children are adjacent.
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