Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

PQTree.h
Go to the documentation of this file.
1 
32 #pragma once
33 
34 #include <ogdf/basic/Array.h>
35 #include <ogdf/basic/ArrayBuffer.h>
36 #include <ogdf/basic/List.h>
37 #include <ogdf/basic/Queue.h>
38 #include <ogdf/basic/SList.h>
39 #include <ogdf/basic/basic.h>
43 #include <ogdf/basic/pqtree/PQLeafKey.h> // IWYU pragma: keep
46 
47 #include <fstream>
48 #include <utility>
49 
50 namespace ogdf {
51 
52 template<class T, class X, class Y>
53 class PQTree {
54 public:
55  PQTree();
56 
66  virtual ~PQTree() { Cleanup(); }
67 
84  SListPure<PQLeafKey<T, X, Y>*>& leafKeys);
85 
90  void emptyNode(PQNode<T, X, Y>* nodePtr);
91 
101  virtual void front(PQNode<T, X, Y>* nodePtr, SListPure<PQLeafKey<T, X, Y>*>& leafKeys);
102 
103  virtual void CleanNode(PQNode<T, X, Y>* /* nodePtr */) { }
104 
116  virtual void Cleanup();
117 
124  virtual void clientDefinedEmptyNode(PQNode<T, X, Y>* nodePtr) { emptyNode(nodePtr); }
125 
134  virtual void emptyAllPertinentNodes();
135 
153  virtual int Initialize(SListPure<PQLeafKey<T, X, Y>*>& leafKeys);
154 
166  virtual bool Reduction(SListPure<PQLeafKey<T, X, Y>*>& leafKeys);
167 
169  PQNode<T, X, Y>* root() const { return m_root; }
170 
173  void writeGML(const char* fileName);
174  void writeGML(std::ostream& os);
176 
177 protected:
180 
183 
186 
188 
193 
196 
206 
215  virtual bool Bubble(SListPure<PQLeafKey<T, X, Y>*>& leafKeys);
216 
245  virtual bool Reduce(SListPure<PQLeafKey<T, X, Y>*>& leafKeys);
246 
267  virtual bool templateL1(PQNode<T, X, Y>* nodePtr, bool isRoot);
268 
289  virtual bool templateP1(PQNode<T, X, Y>* nodePtr, bool isRoot);
290 
310  virtual bool templateP2(PQNode<T, X, Y>** nodePtr);
311 
335  virtual bool templateP3(PQNode<T, X, Y>* nodePtr);
336 
361  virtual bool templateP4(PQNode<T, X, Y>** nodePtr);
362 
378  virtual bool templateP5(PQNode<T, X, Y>* nodePtr);
379 
403  virtual bool templateP6(PQNode<T, X, Y>** nodePtr);
404 
430  virtual bool templateQ1(PQNode<T, X, Y>* nodePtr, bool isRoot);
431 
461  virtual bool templateQ2(PQNode<T, X, Y>* nodePtr, bool isRoot);
462 
463  /*
464  * Template matching for Q-nodes with empty and/or partial children at both
465  * ends and a sequence of full and/or partial children in the middle.
466  * The Q-node must be the root of the pertinent subtree.
467  * The function requires as input any pointer to a node stored in
468  * \p nodePtr. If the node stored in \p nodePtr is a Q-node
469  * with empty and/or partial children at both ends and a sequence
470  * full or partial children in the middle,
471  * templateQ3() considers itself responsible for the node and will
472  * apply the template matching \b Q3 to \p nodePtr.
473  * Observe that the user calling this function has to make sure that
474  * \p nodePtr is the root of the pertinent subtree.
475  *
476  * If templateQ3() was responsible for \p nodePtr and the
477  * reduction was successful, the return value is 1. Otherwise
478  * the return value is 0.
479  *
480  * Below a short description is given of all different cases that
481  * may occure and are handled by the function templateQ3(), \b regardless
482  * whether the Q-node \p nodePtr is the root of the pertinent subtree or not.
483  * The description is somewhat trunkated and should be understood as a
484  * stenographic description of the labels of the children of \p nodePtr
485  * when running through the children from one side to the other. Of course
486  * we leave the mirror-images out.
487  * - empty, full, empty
488  * - empty, partial, full, partial, empty
489  * - empty, partial, full, empty
490  * - empty, partial, full, partial
491  * - partial, full, partial
492  * - empty, partial, partial, empty
493  * - empty, partial, partial
494  * - partial, partial
495  */
496  virtual bool templateQ3(PQNode<T, X, Y>* nodePtr);
497 
509  virtual bool addNodeToNewParent(PQNode<T, X, Y>* parent, PQNode<T, X, Y>* child);
510 
542  virtual bool addNodeToNewParent(PQNode<T, X, Y>* parent, PQNode<T, X, Y>* child,
543  PQNode<T, X, Y>* leftBrother, PQNode<T, X, Y>* rightBrother);
544 
560  virtual bool checkIfOnlyChild(PQNode<T, X, Y>* child, PQNode<T, X, Y>* parent);
561 
567  virtual void destroyNode(PQNode<T, X, Y>* nodePtr) {
569  }
570 
585  virtual void exchangeNodes(PQNode<T, X, Y>* oldNode, PQNode<T, X, Y>* newNode);
586 
595  virtual void linkChildrenOfQnode(PQNode<T, X, Y>* installed, PQNode<T, X, Y>* newChild);
596 
606  virtual void removeChildFromSiblings(PQNode<T, X, Y>* nodePtr);
607 
656  virtual int removeNodeFromTree(PQNode<T, X, Y>* parent, PQNode<T, X, Y>* child);
657 
659 
661  return nodePtr->partialChildren;
662  }
663 
665  return nodePtr->m_leftEndmost;
666  }
667 
669  return nodePtr->m_rightEndmost;
670  }
671 
673  return nodePtr->getNextSib(other);
674  }
675 
676  virtual PQNode<T, X, Y>* clientSibLeft(PQNode<T, X, Y>* nodePtr) const {
677  return nodePtr->m_sibLeft;
678  }
679 
680  virtual PQNode<T, X, Y>* clientSibRight(PQNode<T, X, Y>* nodePtr) const {
681  return nodePtr->m_sibRight;
682  }
683 
691  virtual int clientPrintNodeCategorie(PQNode<T, X, Y>* nodePtr);
692 
700  virtual const char* clientPrintStatus(PQNode<T, X, Y>* nodePtr);
701 
709  virtual const char* clientPrintType(PQNode<T, X, Y>* nodePtr);
710 
711 private:
733  bool checkChain(PQNode<T, X, Y>* nodePtr, PQNode<T, X, Y>* firstFull,
734  PQNode<T, X, Y>** seqStart, PQNode<T, X, Y>** seqEnd);
735 
749  void copyFullChildrenToPartial(PQNode<T, X, Y>* nodePtr, PQNode<T, X, Y>* partialChild);
750 
765 
782  void removeBlock(PQNode<T, X, Y>* nodePtr, bool isRoot);
783 
788  void sortExceptions(int Exceptions[], int arraySize);
789 };
790 
791 template<class T, class X, class Y>
793  SListPure<PQLeafKey<T, X, Y>*>& leafKeys) {
794  if (!leafKeys.empty()) {
795  OGDF_ASSERT(!father->m_childCount);
796  // Father has children. Brothers expected
797 
799  SListIterator<PQLeafKey<T, X, Y>*> it = leafKeys.begin();
800  PQLeafKey<T, X, Y>* newKey = *it; //leafKeys[0];
801 
802  PQNode<T, X, Y>* aktualSon = new PQLeaf<T, X, Y>(m_identificationNumber++,
804  PQNode<T, X, Y>* firstSon = aktualSon;
805  firstSon->m_parent = father;
806  firstSon->m_parentType = father->type();
807  father->m_childCount++;
808  PQNode<T, X, Y>* oldSon = firstSon;
809 
811  for (++it; it.valid(); ++it) {
812  newKey = *it; //leafKeys[i];
813  aktualSon = new PQLeaf<T, X, Y>(m_identificationNumber++,
815  aktualSon->m_parent = father;
816  aktualSon->m_parentType = father->type();
817  father->m_childCount++;
818  oldSon->m_sibRight = aktualSon;
819  aktualSon->m_sibLeft = oldSon;
820  oldSon = aktualSon;
821  }
822  if (father->type() == PQNodeRoot::PQNodeType::PNode)
824  {
825  firstSon->m_sibLeft = oldSon;
826  oldSon->m_sibRight = firstSon;
827  father->m_referenceChild = firstSon;
828  firstSon->m_referenceParent = father;
829  } else if (father->type() == PQNodeRoot::PQNodeType::QNode)
831  {
832  father->m_leftEndmost = firstSon;
833  father->m_rightEndmost = oldSon;
834  }
835  return true;
836  }
837 
838  return false;
839 }
840 
841 template<class T, class X, class Y>
845  //parent type not valid.
846 
847  if (child != nullptr) {
848  OGDF_ASSERT(parent->m_childCount == 0);
849  //when adding new nodes: Brothers expected.
850  child->m_parent = parent;
851  child->m_parentType = parent->type();
852  parent->m_childCount++;
853 
854  /*
855  Set the reference pointers in case that [[parent]] is a $P$-node.
856  If [[parent]] is a $Q$-node, this chunk sets the endmost children
857  of [[parent]]. Since [[child]] is the only child of [[parent]]
858  both endmost pointers are set to [[child]].
859  */
860  if (parent->type() == PQNodeRoot::PQNodeType::PNode) {
861  child->m_sibLeft = child;
862  child->m_sibRight = child;
863  parent->m_referenceChild = child;
864  child->m_referenceParent = parent;
865  } else if (parent->type() == PQNodeRoot::PQNodeType::QNode) {
866  parent->m_leftEndmost = child;
867  parent->m_rightEndmost = child;
868  }
869 
870  return true;
871  }
872 
873  return false;
874 }
875 
876 template<class T, class X, class Y>
878  PQNode<T, X, Y>* leftBrother, PQNode<T, X, Y>* rightBrother) {
879  if (parent != nullptr) {
881  || parent->type() == PQNodeRoot::PQNodeType::QNode);
882  //parent type not valid
883  if (leftBrother == nullptr && rightBrother == nullptr) {
884  return addNodeToNewParent(parent, child);
885  } else if (child != nullptr) {
886  child->m_parent = parent;
887  child->m_parentType = parent->type();
888  parent->m_childCount++;
889 
890  if (parent->type() == PQNodeRoot::PQNodeType::PNode) {
891  /*
892  The parent is a $P$-node with children.
893  Either [[leftBrother]] or [[rightBrother]] stores
894  a pointer to an existing child of [[parent]] and [[parent]]
895  is a $P$-node. In case that two brothers are stored, an
896  arbitrary one is choosen to be the next sibling of [[child]].
897  This brother is stored in [[brother]]. The pointer [[sister]]
898  denotes a pointer to an arbitrary sibling of [[brother]].
899  */
900  PQNode<T, X, Y>* brother = (leftBrother != nullptr) ? leftBrother : rightBrother;
901  PQNode<T, X, Y>* sister = brother->m_sibRight;
902  child->m_sibLeft = brother;
903  child->m_sibRight = sister;
904  brother->m_sibRight = child;
905  sister->m_sibLeft = child;
906  return true;
907  }
908 
909  else if (leftBrother == nullptr) {
910  /*
911  The parent is a $Q$-node with children.
912  The [[leftBrother]] is a [[0]]-pointer while the
913  [[rightBrother]] denotes an existing child of [[parent]].
914  The node [[rightBrother]] <b>must be</b> one of the two endmost
915  children of [[parent]]. If this is not the case, the chunk
916  detects this, halts the procedure [[addNewLeavesToTree]]
917  printing an error message and returning [[0]].
918  If [[rightBrother]] is endmost child of [[parent]], then
919  this chunk adds [[child]] at the one end where
920  [[rightBrother]] hides. The node [[child]] is then made the
921  new endmost child of [[parent]] on the corresponding side.
922  */
923  if (rightBrother == parent->m_leftEndmost) {
924  parent->m_leftEndmost = child;
925  child->m_sibRight = rightBrother;
926  rightBrother->putSibling(child, PQNodeRoot::SibDirection::Left);
927  return true;
928  }
929 
930  // missing second brother?
931  OGDF_ASSERT(rightBrother == parent->m_rightEndmost);
932  parent->m_rightEndmost = child;
933  child->m_sibLeft = rightBrother;
934  rightBrother->putSibling(child, PQNodeRoot::SibDirection::Left);
935  return true;
936  }
937 
938  else if (rightBrother == nullptr) {
939  /*
940  The parent is a $Q$-node with children.
941  The [[rightBrother]] is a [[0]]-pointer while the
942  [[leftBrother]] denotes an existing child of [[parent]]. The
943  node [[leftBrother]] <b>must be</b> one of the two endmost
944  children of [[parent]]. If this is not the case, the chunk
945  detects this, halts the procedure [[addNodeToNewParent]]
946  printing an error message and returning [[0]].
947  If [[leftBrother]] is endmost child of [[parent]], then this
948  chunk adds [[child]] at the one end where [[leftBrother]]
949  hides. The node [[child]] is then made new endmost child of
950  [[parent]] on the corresponding side.
951  */
952  if (leftBrother == parent->m_rightEndmost) {
953  parent->m_rightEndmost = child;
954  child->m_sibLeft = leftBrother;
955  leftBrother->putSibling(child, PQNodeRoot::SibDirection::Right);
956  return true;
957  }
958 
959  // missing second brother?
960  OGDF_ASSERT(leftBrother == parent->m_leftEndmost);
961  parent->m_leftEndmost = child;
962  child->m_sibRight = leftBrother;
963  leftBrother->putSibling(child, PQNodeRoot::SibDirection::Right);
964  return true;
965  }
966 
967  else {
968  /*
969  The parent is a $Q$-node with children.
970  Both the [[rightBrother]] and the [[leftBrother]] denote
971  existing children of [[parent]]. In this case, [[leftBrother]]
972  and [[rightBrother]] must be immideate siblings. If this is
973  not the case, this will be detected during the function call
974  [[changeSiblings]] of the class [[PQNode.h]] (see
975  \ref{PQNode.changeSiblings}) in the first two lines of this
976  chunk. If the chunk recognizes the failure of
977  [[changeSiblings]] it halts the procedure
978  [[addNewLeavesToTree]], printing an error message and
979  returning [[0]].
980  If the two brothers are immediate siblings, this chunk
981  adds [[child]] between the two brothers as interior child of
982  the $Q$-node [[parent]].
983  */
984 #ifdef OGDF_DEBUG
985  bool ok =
986 #endif
987  rightBrother->changeSiblings(leftBrother, child)
988  && leftBrother->changeSiblings(rightBrother, child);
989 
990  // brothers are not siblings?
991  OGDF_ASSERT(ok);
992 
993  if (leftBrother->m_sibRight == child) {
994  child->m_sibLeft = leftBrother;
995  child->m_sibRight = rightBrother;
996  } else {
997  child->m_sibLeft = rightBrother;
998  child->m_sibRight = leftBrother;
999  }
1000  return true;
1001  }
1002  } else {
1003  return false;
1004  }
1005  } else if (leftBrother != nullptr && rightBrother != nullptr) {
1006  /*
1007  The parent is a $Q$-node with children.
1008  Both the [[rightBrother]] and the [[leftBrother]] denote
1009  existing children of [[parent]]. In this case, [[leftBrother]]
1010  and [[rightBrother]] must be immideate siblings. If this is
1011  not the case, this will be detected during the function call
1012  [[changeSiblings]] of the class [[PQNode.h]] (see
1013  \ref{PQNode.changeSiblings}) in the first two lines of this
1014  chunk. If the chunk recognizes the failure of
1015  [[changeSiblings]] it halts the procedure
1016  [[addNewLeavesToTree]], printing an error message and
1017  returning [[0]].
1018  If the two brothers are immediate siblings, this chunk
1019  adds [[child]] between the two brothers as interior child of
1020  the $Q$-node [[parent]].
1021  */
1022 #ifdef OGDF_DEBUG
1023  bool ok =
1024 #endif
1025  rightBrother->changeSiblings(leftBrother, child)
1026  && leftBrother->changeSiblings(rightBrother, child);
1027 
1028  // brothers are not siblings?
1029  OGDF_ASSERT(ok);
1030 
1031  if (leftBrother->m_sibRight == child) {
1032  child->m_sibLeft = leftBrother;
1033  child->m_sibRight = rightBrother;
1034  } else {
1035  child->m_sibLeft = rightBrother;
1036  child->m_sibRight = leftBrother;
1037  }
1038  return true;
1039  }
1040 
1041  return true;
1042 }
1043 
1044 template<class T, class X, class Y>
1046  /* Variables:
1047  * - \a blockcount is the number of blocks of blocked nodes during
1048  * the bubbling up phase.
1049  * - \a numBlocked is the number of blocked nodes during the
1050  * bubbling up phase.
1051  * - \a blockedSiblings counts the number of blocked siblings that
1052  * are adjacent to \a checkNode. A node has 0, 1 or 2 blocked siblings.
1053  * A child of a P-node has no blocked siblings. Endmost children of
1054  * Q-nodes have at most 1 blocked sibling. The interior children of
1055  * a Q-Node have at most 2 blocked siblings.
1056  * - \a checkLeaf is a pointer used for finding the pertinent leaves.
1057  * - \a checkNode is a pointer to the actual node.
1058  * - \a checkSib is a pointer used to examin the siblings of [[checkNode]].
1059  * - \a offTheTop is a variable which is either 0 (that is its
1060  * initial value) or 1 in case that the root of the tree has been
1061  * process during the first phase.
1062  * - \a parent is a pointer to the parent of \a checkNode, if \a checkNode
1063  * has a valid parent pointer.
1064  * - \a processNodes is a first-in first-out list that is used for
1065  * sequencing the order in which the nodes are processed.
1066  * - \a blockedNodes is a stack storing all nodes that have been
1067  * once blocked. In case that the [[m_pseudoRoot]] has to be
1068  * introduced, the stack contains the blocked nodes.
1069  */
1070  Queue<PQNode<T, X, Y>*> processNodes;
1071 
1072  /*
1073  Enter the [[Full]] leaves into the queue [[processNodes]].
1074  In a first step the pertinent leaves have to be identified in the tree
1075  and entered on to the queue [[processNodes]]. The identification of
1076  the leaves can be done with the help of a pointer stored in every
1077  [[PQLeafKey]] (see \ref{PQLeafKey}) in constant time for every element.
1078  */
1080  for (it = leafKeys.begin(); it.valid(); ++it) {
1081  PQNode<T, X, Y>* checkLeaf = (*it)->nodePointer(); //leafKeys[i]->nodePointer();
1083  processNodes.append(checkLeaf);
1084  m_pertinentNodes->pushFront(checkLeaf);
1085  }
1086 
1087  int blockCount = 0;
1088  // int numBlocked = 0;
1089  int offTheTop = 0;
1090  PQNode<T, X, Y>* checkSib = nullptr;
1091  ArrayBuffer<PQNode<T, X, Y>*> blockedNodes;
1092 
1093  while ((processNodes.size() + blockCount + offTheTop) > 1) {
1094  if (processNodes.size() == 0) {
1095  /*
1096  No consecutive sequence possible.
1097  The queue [[processNodes]] does not contain any nodes for
1098  processing and the sum of [[blockCount]] and [[offTheTop]] is
1099  greater than 1. If the queue is empty, the root of the pertinent
1100  subtree was already processed. Nevertheless, there are blocked
1101  nodes since [[offTheTop]] is either be [[0]] or [[1]], hence
1102  [[blockCount]] must be at least [[1]]. Such blocked nodes cannot
1103  form a consecutive sequence with all nodes in the set
1104  [[leafKeys]]. Observe that this chunk finishes the function
1105  [[Bubble]]. Hence every memory allocated by the function [[Bubble]]
1106  has to be deleted here as well.
1107  */
1108  return false;
1109  }
1110  /*
1111  If there are still nodes to be processed in which case the queue
1112  [[processNodes]] is not empty, we get the next node from the queue.
1113  By default this node has to be marked as blocked.
1114  */
1115  PQNode<T, X, Y>* checkNode = processNodes.pop();
1116  blockedNodes.push(checkNode);
1118  int blockedSiblings = 0;
1119 
1120  /*
1121  Check if node is adjacent to an unblocked node.
1122  After getting the node [[checkNode]] from the queue, its siblings are
1123  checked, whether they are unblocked. If they are, then they have a
1124  valid pointer to their parent and the parent pointer of [[checkNode]]
1125  is updated.
1126  */
1127  if (checkNode->m_parentType != PQNodeRoot::PQNodeType::PNode && checkNode != m_root)
1128  // checkNode is son of a QNode.
1129  // Check if it is blocked.
1130  {
1131  if (clientSibLeft(checkNode) == nullptr)
1132  // checkNode is endmost child of
1133  // a QNode. It has a valid pointer
1134  // to its parent.
1135  {
1137  if (clientSibRight(checkNode)
1138  && clientSibRight(checkNode)->mark() == PQNodeRoot::PQNodeMark::Blocked) {
1139  blockedSiblings++;
1140  }
1141  }
1142 
1143  else if (clientSibRight(checkNode) == nullptr)
1144  // checkNode is endmost child of
1145  // a QNode. It has a valid pointer
1146  // to its parent.
1147  {
1149  if (clientSibLeft(checkNode)
1150  && clientSibLeft(checkNode)->mark() == PQNodeRoot::PQNodeMark::Blocked) {
1151  blockedSiblings++;
1152  }
1153  }
1154 
1155 
1156  else
1157  // checkNode is not endmost child of
1158  // a QNode. It has not a valid
1159  // pointer to its parent.
1160  {
1161  if (clientSibLeft(checkNode)->mark() == PQNodeRoot::PQNodeMark::Unblocked)
1162  // checkNode is adjacent to an
1163  // unblocked node. Take its parent.
1164  {
1166  checkNode->m_parent = clientSibLeft(checkNode)->m_parent;
1167  } else if (clientSibLeft(checkNode)->mark() == PQNodeRoot::PQNodeMark::Blocked) {
1168  blockedSiblings++;
1169  }
1170 
1171  if (clientSibRight(checkNode)->mark() == PQNodeRoot::PQNodeMark::Unblocked)
1172  // checkNode is adjacent to an
1173  // unblocked node. Take its parent.
1174  {
1176  checkNode->m_parent = clientSibRight(checkNode)->m_parent;
1177  } else if (clientSibRight(checkNode)->mark() == PQNodeRoot::PQNodeMark::Blocked) {
1178  blockedSiblings++;
1179  }
1180  }
1181  }
1182 
1183  else {
1184  // checkNode is son of a PNode
1185  // and children of P_NODEs
1186  // cannot be blocked.
1188  }
1189 
1190  if (checkNode->mark() == PQNodeRoot::PQNodeMark::Unblocked) {
1191  PQNode<T, X, Y>* parent = checkNode->m_parent;
1192 
1193  /*
1194  Get maximal consecutive set of blocked siblings.
1195  This chunk belongs to the procedure [[bubble]].
1196  The node [[checkNode]] is [[Unblocked]].
1197  If the parent of [[checkNode]] is a $Q$-Node, then we check the
1198  siblings [[checkSib]] of [[checkNode]] whether they are
1199  [[Blocked]]. If they are blocked, they have to be marked
1200  [[Unblocked]] since they are adjacent to the [[Unblocked]] node
1201  [[checkNode]]. We then have to proceed with the siblings of
1202  [[checkSib]] in order to find [[Blocked]] nodes
1203  adjacent to [[checkSib]]. This is repeated until no [[Blocked]]
1204  nodes are found any more.
1205 
1206  Observe that while running through the children of the $Q$-Node
1207  (referred by the pointer [[parent]]), their parent pointers,
1208  as well as the [[pertChildCount]] of [[parent]] are updated.
1209  Furthermore we reduce simultaneously the count [[numBlocked]].
1210  */
1211  if (blockedSiblings > 0) {
1212  if (clientSibLeft(checkNode) != nullptr) {
1213  checkSib = clientSibLeft(checkNode);
1214  PQNode<T, X, Y>* oldSib = checkNode;
1215  while (checkSib->mark() == PQNodeRoot::PQNodeMark::Blocked) {
1217  checkSib->m_parent = parent;
1218  // numBlocked--;
1219  parent->m_pertChildCount++;
1220  PQNode<T, X, Y>* holdSib = clientNextSib(checkSib, oldSib);
1221  oldSib = checkSib;
1222  checkSib = holdSib;
1223  // Blocked node as endmost child of a QNode.
1224  }
1225  }
1226 
1227  if (clientSibRight(checkNode) != nullptr) {
1228  checkSib = clientSibRight(checkNode);
1229  PQNode<T, X, Y>* oldSib = checkNode;
1230  while (checkSib->mark() == PQNodeRoot::PQNodeMark::Blocked) {
1232  checkSib->m_parent = parent;
1233  // numBlocked--;
1234  parent->m_pertChildCount++;
1235  PQNode<T, X, Y>* holdSib = clientNextSib(checkSib, oldSib);
1236  oldSib = checkSib;
1237  checkSib = holdSib;
1238  // Blocked node as endmost child of a QNode.
1239  }
1240  }
1241  }
1242 
1243  /*
1244  Process parent of [[checkNode]]
1245  After processing the siblings of the [[Unblocked]] [[checkNode]]
1246  the parent has to be processed. If [[checkNode]] is the root
1247  of the tree we do nothing except setting the flag [[offTheTop]].
1248  If it is not the root and [[parent]] has not been placed onto the
1249  queue [[processNodes]], the [[parent]] is placed on to
1250  [[processNodes]].
1251 
1252  Observe that the number [[blockCount]] is updated. Since
1253  [[checkNode]] was [[Unblocked]] all pertinent nodes adjacent
1254  to that node became [[Unblocked]] as well. Therefore the number
1255  of blocks is reduced by the number of [[Blocked]] siblings of
1256  [[checkNode]].
1257  */
1258  if (parent == nullptr) {
1259  // checkNode is root of the tree.
1260  offTheTop = 1;
1261  } else
1262  // checkNode is not the root.
1263  {
1264  parent->m_pertChildCount++;
1265  if (parent->mark() == PQNodeRoot::PQNodeMark::Unmarked) {
1266  processNodes.append(parent);
1267  m_pertinentNodes->pushFront(parent);
1269  }
1270  }
1271 
1272  blockCount -= blockedSiblings;
1273  blockedSiblings = 0;
1274  } else {
1275  /*
1276  Process blocked [[checkNode]]
1277  Since [[checkNode]] is [[Blocked]], we cannot continue
1278  processing at this point in the Tree. We have to wait until
1279  this node becomes unblocked. So only the variables
1280  [[blockCount]] and [[numBlocked]] are updated.
1281  */
1282  blockCount += 1 - blockedSiblings;
1283  // numBlocked++;
1284  }
1285  }
1286 
1287  if (blockCount == 1) {
1288  /*
1289  If [[blockCount]] $= 1$ enter [[m_pseudoRoot]] to the tree
1290  In case that the root of the pertinent subtree is a $Q$-node
1291  with empty children on both sides and the pertinent children
1292  in the middle, it is possible that the $PQ$-tree is reducible.
1293  But since the sequence of pertinent children of the $Q$-node is
1294  blocked, the procedure is not able to find the parent of its
1295  pertinent children. This is due to the fact that the interior
1296  children of a $Q$-node do not have a valid parent pointer.
1297 
1298  So the root of the pertinent subtree is not known, hence cannot be
1299  entered into the processing queue used in the function call [[Reduce]]
1300  (see \ref{Reduce}). To solve this problem a special node only designed
1301  for this cases is used: [[m_pseudoRoot]]. It simulates the root of the
1302  pertinent subtree. This works out well, since for this node the only
1303  possible template maching is [[templateQ3]] (see \ref{templateQ3}),
1304  where no pointers to the endmost children of a $Q$-node are used.
1305  */
1306  while (!blockedNodes.empty()) {
1307  PQNode<T, X, Y>* checkNode = blockedNodes.popRet();
1308  if (checkNode->mark() == PQNodeRoot::PQNodeMark::Blocked) {
1310  checkNode->m_parent = m_pseudoRoot;
1311  m_pseudoRoot->m_pertChildCount++;
1312  OGDF_ASSERT(!checkNode->endmostChild());
1313  //Blocked node as endmost child of a QNode.
1314  }
1315  }
1316  }
1317 
1318  return true;
1319 }
1320 
1321 template<class T, class X, class Y>
1323  PQNode<T, X, Y>** seqStart, PQNode<T, X, Y>** seqEnd) {
1324  /* Variables:
1325  * - \a fullCount counts the number of children that are
1326  * discovered by the function checkChain(). This is necessary, since
1327  * checkChain() is used by two template matching functions
1328  * templateQ2() and templateQ3() where in the latter case the
1329  * pointer \a firstFull may point to any full child in the front of the Q-node
1330  * \a nodePtr.
1331  * - \a notFull is set 1 when an empty child is encountered.
1332  * - \a checkNode is the actual node that is examined.
1333  * - \a leftNext is the next node that has to be examined on the
1334  * left side of \a firstFull.
1335  * - \a leftOld is the node that has been examined right before
1336  * \a checkNode on the left side of \a firstFull.
1337  * - \a rightNext is the next node that has to be examined on the
1338  * right side of \a firstFull. Not needed when checkChain() was
1339  * called by templateQ2().
1340  * - \a rightOld is the node that has been examined right before
1341  * \a checkNode on the right side of \a firstFull.
1342  * Not needed when checkChain() was called by templateQ2().
1343  */
1344  bool notFull = false;
1345  int fullCount = nodePtr->fullChildren->size();
1346  fullCount--; // firstFull does have a Full label.
1347 
1348  /*
1349  Start at the [[firstFull]] child sweeping through the full children on
1350  the left side of [[firstfull]]. It stops as soon as a nonfull child is
1351  detected. The last found full child is stored in [[seqEnd]].
1352  */
1353  PQNode<T, X, Y>* leftNext = clientSibLeft(firstFull);
1354  (*seqEnd) = firstFull;
1355  if (leftNext != nullptr) {
1356  if (leftNext->status() == PQNodeRoot::PQNodeStatus::Full) {
1357  fullCount--;
1358 
1359  PQNode<T, X, Y>* leftOld = firstFull;
1360  PQNode<T, X, Y>* checkNode = leftNext;
1361 
1362  while (fullCount > 0 && !notFull)
1363  // There are still full children to be
1364  // counted, and no empty child has been
1365  // encountered on this side.
1366  {
1367  leftNext = clientNextSib(checkNode, leftOld);
1368  if (leftNext != nullptr && leftNext->status() == PQNodeRoot::PQNodeStatus::Full) {
1369  fullCount--;
1370  } else {
1371  notFull = true;
1372  }
1373  leftOld = checkNode;
1374  checkNode = leftNext;
1375  }
1376 
1377  if (checkNode != nullptr && checkNode->status() == PQNodeRoot::PQNodeStatus::Full) {
1378  (*seqEnd) = checkNode;
1379  }
1380 
1381  else {
1382  //searching consecutive sequence in Q2 or Q3.
1383  OGDF_ASSERT(leftOld != nullptr);
1385  (*seqEnd) = leftOld;
1386  }
1387 
1388  } else {
1389  (*seqEnd) = firstFull;
1390  }
1391  }
1392 
1393  /*
1394  Start at the [[firstFull]] child sweeping through the full children on
1395  the right side of [[firstfull]]. It stops as soon as a nonfull child is
1396  detected.
1397  */
1398  notFull = false;
1399  PQNode<T, X, Y>* rightNext = clientSibRight(firstFull);
1400  (*seqStart) = firstFull;
1401  if (rightNext != nullptr) {
1402  if (rightNext->status() == PQNodeRoot::PQNodeStatus::Full) {
1403  fullCount--;
1404 
1405  PQNode<T, X, Y>* rightOld = firstFull;
1406  PQNode<T, X, Y>* checkNode = rightNext;
1407 
1408  while (fullCount > 0 && !notFull)
1409  // There are still full children to be
1410  // counted, and no empty child has been
1411  // encountered on this side.
1412  {
1413  rightNext = clientNextSib(checkNode, rightOld);
1414  if (rightNext != nullptr && rightNext->status() == PQNodeRoot::PQNodeStatus::Full) {
1415  fullCount--;
1416  } else {
1417  notFull = true;
1418  }
1419  rightOld = checkNode;
1420  checkNode = rightNext;
1421  }
1422  if (checkNode != nullptr && checkNode->status() == PQNodeRoot::PQNodeStatus::Full) {
1423  (*seqStart) = checkNode;
1424  }
1425 
1426  else {
1427  OGDF_ASSERT(rightOld != nullptr);
1429  (*seqStart) = rightOld;
1430  //searching consecutive seqeuence in Q2 or Q3.
1431  }
1432 
1433  } else {
1434  (*seqStart) = firstFull;
1435  }
1436  }
1437 
1438  if (firstFull == (*seqEnd)) {
1439  PQNode<T, X, Y>* checkNode = (*seqEnd);
1440  (*seqEnd) = (*seqStart);
1441  (*seqStart) = checkNode;
1442  }
1443 
1444  if (fullCount == 0) {
1445  // All full children occupy a consecutive
1446  // sequence.
1447  return true;
1448  } else {
1449  return false;
1450  }
1451 }
1452 
1453 template<class T, class X, class Y>
1455  if ((parent->type() == PQNodeRoot::PQNodeType::PNode && parent->m_childCount == 1)
1456  || (parent->type() == PQNodeRoot::PQNodeType::QNode && parent->m_leftEndmost == child
1457  && parent->m_rightEndmost == child)) {
1458  removeChildFromSiblings(child);
1459  child->m_parent = parent->m_parent;
1460  if (parent->m_parent != nullptr) { // parent is not the root.
1461  exchangeNodes(parent, child);
1462  } else {
1463  exchangeNodes(parent, child);
1464  m_root = child;
1465  }
1466  destroyNode(parent);
1467  return true;
1468  } else {
1469  return false;
1470  }
1471 }
1472 
1473 template<class T, class X, class Y>
1475  /* In order to free the allocated memory, all nodes of the
1476  * tree have to be deleted, hence there destructors are called.
1477  * In order to achieve this, we start at the root of the tree and go down the
1478  * tree to the leaves for reaching every node. When a node is processed,
1479  * (besides the #m_root, this will always be the node \a checkNode)
1480  * the pointers of all its children are stored in a queue \a helpqueue and
1481  * then the processed node is deleted.
1482  *
1483  * The use of a queue \a helpqueue is a must, since the nodes do not
1484  * have pointers to all of their children, as the children mostly do
1485  * not have a pointer to their parent.
1486  *
1487  * It might look weird at the first glance that the function Cleanup()
1488  * calls the function emptyAllPertinentNodes(), but if some nodes were removed
1489  * during a reduction, they were stored in the stack #m_pertinentNodes.
1490  * These nodes have to be deleted as well
1491  * which is provided by the function emptyAllPertinentNodes().
1492  */
1493  PQNode<T, X, Y>* nextSon = nullptr;
1494  PQNode<T, X, Y>* lastSon = nullptr;
1495 
1496  Queue<PQNode<T, X, Y>*> helpqueue;
1497 
1498  if (m_root != nullptr) {
1499  emptyAllPertinentNodes();
1500  OGDF_ASSERT(m_root != nullptr);
1501  PQNode<T, X, Y>* oldSib = nullptr;
1502 
1503  /*
1504  Process the [[m_root]] of the [[PQTree]]. Before deleting [[m_root]],
1505  pointers to all its children are stored in the queue [[helpqueue]].
1506  */
1507  if (m_root->type() == PQNodeRoot::PQNodeType::PNode) {
1508  if (m_root->m_referenceChild != nullptr) {
1509  PQNode<T, X, Y>* firstSon = m_root->m_referenceChild;
1510  helpqueue.append(firstSon);
1511 
1512  if (firstSon->m_sibRight != nullptr) {
1513  nextSon = firstSon->m_sibRight;
1514  }
1515  while (nextSon != firstSon) {
1516  helpqueue.append(nextSon);
1517  nextSon = nextSon->m_sibRight;
1518  }
1519  }
1520  } else if (m_root->type() == PQNodeRoot::PQNodeType::QNode) {
1521  PQNode<T, X, Y>* firstSon = m_root->m_leftEndmost;
1522  helpqueue.append(firstSon);
1523 
1524  lastSon = m_root->m_rightEndmost;
1525  helpqueue.append(lastSon);
1526 
1527  nextSon = lastSon->getNextSib(oldSib);
1528  oldSib = lastSon;
1529  while (nextSon != firstSon) {
1530  helpqueue.append(nextSon);
1531  PQNode<T, X, Y>* holdSib = nextSon->getNextSib(oldSib);
1532  oldSib = nextSon;
1533  nextSon = holdSib;
1534  }
1535  }
1536 
1537 
1538  CleanNode(m_root);
1539  delete m_root;
1540 
1541  while (!helpqueue.empty()) {
1542  PQNode<T, X, Y>* checkNode = helpqueue.pop();
1543 
1544  /*
1545  Process an arbitrary node [[checkNode]] of the [[PQTree]].
1546  Before deleting [[checkNode]],
1547  pointers to all its children are stored in the queue [[helpqueue]].
1548  */
1549  if (checkNode->type() == PQNodeRoot::PQNodeType::PNode) {
1550  if (checkNode->m_referenceChild != nullptr) {
1551  PQNode<T, X, Y>* firstSon = checkNode->m_referenceChild;
1552  helpqueue.append(firstSon);
1553 
1554  if (firstSon->m_sibRight != nullptr) {
1555  nextSon = firstSon->m_sibRight;
1556  }
1557  while (nextSon != firstSon) {
1558  helpqueue.append(nextSon);
1559  nextSon = nextSon->m_sibRight;
1560  }
1561  }
1562  } else if (checkNode->type() == PQNodeRoot::PQNodeType::QNode) {
1563  oldSib = nullptr;
1564 
1565  PQNode<T, X, Y>* firstSon = checkNode->m_leftEndmost;
1566  helpqueue.append(firstSon);
1567 
1568  lastSon = checkNode->m_rightEndmost;
1569  helpqueue.append(lastSon);
1570 
1571  nextSon = lastSon->getNextSib(oldSib);
1572  oldSib = lastSon;
1573  while (nextSon != firstSon) {
1574  helpqueue.append(nextSon);
1575  PQNode<T, X, Y>* holdSib = nextSon->getNextSib(oldSib);
1576  oldSib = nextSon;
1577  nextSon = holdSib;
1578  }
1579  }
1580 
1581  CleanNode(checkNode);
1582  delete checkNode;
1583  }
1584  }
1585 
1586  CleanNode(m_pseudoRoot);
1587  delete m_pseudoRoot;
1588 
1589  delete m_pertinentNodes;
1590 
1591  m_root = nullptr;
1592  m_pertinentRoot = nullptr;
1593  m_pseudoRoot = nullptr;
1594  m_pertinentNodes = nullptr;
1595 
1596  m_numberOfLeaves = 0;
1597  m_identificationNumber = 0;
1598 }
1599 
1600 template<class T, class X, class Y>
1602  return (nodePtr != nullptr) ? 1 : 0;
1603  // 1 is the standard node categrie in the Tree Interface.
1604 }
1605 
1606 template<class T, class X, class Y>
1608  return (nodePtr != nullptr) ? "ERROR" : "ERROR: clientPrintStatus: NO NODE ACCESSED";
1609 }
1610 
1611 template<class T, class X, class Y>
1613  return (nodePtr != nullptr) ? "ERROR" : "ERROR: clientPrintType: NO NODE ACCESSED";
1614 }
1615 
1616 template<class T, class X, class Y>
1618  m_root = nullptr;
1619  m_pertinentRoot = nullptr;
1620  m_pseudoRoot = nullptr;
1621 
1622  m_numberOfLeaves = 0;
1623  m_identificationNumber = 0;
1624 
1625  m_pertinentNodes = nullptr;
1626 }
1627 
1628 template<class T, class X, class Y>
1630  PQNode<T, X, Y>* partialChild) {
1631  if (nodePtr->fullChildren->size() > 0)
1632  // There are some full children to
1633  // be copied.
1634  {
1635  nodePtr->m_childCount = nodePtr->m_childCount - nodePtr->fullChildren->size();
1636 
1637  PQNode<T, X, Y>* newNode = createNodeAndCopyFullChildren(nodePtr->fullChildren);
1638 
1639  // Introduce newNode as endmost
1640  // child of the partial Q-node.
1641  partialChild->m_childCount++;
1642  partialChild->fullChildren->pushFront(newNode);
1643 
1644  if (clientLeftEndmost(partialChild)->status() == PQNodeRoot::PQNodeStatus::Full) {
1645  PQNode<T, X, Y>* checkNode = partialChild->m_leftEndmost;
1646  partialChild->m_leftEndmost = newNode;
1647  linkChildrenOfQnode(checkNode, newNode);
1648 
1649  } else {
1650  // ERROR: Endmostchild not found?
1651  OGDF_ASSERT(clientRightEndmost(partialChild)->status() == PQNodeRoot::PQNodeStatus::Full);
1652 
1653  PQNode<T, X, Y>* checkNode = partialChild->m_rightEndmost;
1654  partialChild->m_rightEndmost = newNode;
1655  linkChildrenOfQnode(checkNode, newNode);
1656  }
1657 
1658  newNode->m_parent = partialChild;
1660  }
1661 }
1662 
1663 template<class T, class X, class Y>
1665  /* Variables:
1666  * - \a newNode stores the adress of the new allocated P-node or
1667  * the adress of the only full child.
1668  * - \a oldSon is a variable used for adding the full nodes as
1669  * children to the new P-node.
1670  * - \a firstSon stores the adress of the first detected full
1671  * child. It is needed for adding the full nodes as
1672  * children to the new P-node.
1673  * - \a checkSon is a variable used for adding the full nodes as
1674  * children to the new P-node.
1675  * - \a newPQnode is used for proper allocation of the new P-node.
1676  */
1677  PQNode<T, X, Y>* newNode = nullptr;
1678 
1679  if (fullNodes->size() == 1) {
1680  /*
1681  There is just one full child. So no new $P$-node is created. The
1682  full child is copied as child to the [[partialChild]].
1683  */
1684  newNode = fullNodes->popFrontRet();
1685  removeChildFromSiblings(newNode);
1686  }
1687 
1688  else {
1689  /*
1690  This chunk belongs to the function [[createNodeAndCopyFullChildren]].
1691  There is more than one full child, so a new $P$-node is created.
1692  This chunk first allocates the memory for the new $P$-node that will
1693  be stored in [[newNode]]. Then it pops the nodes out of the stack
1694  [[fullNodes]] and introduces them as sons of [[newNode]].
1695  Popping the nodes out of the stack implies at the same time
1696  that they are removed from the [[fullChildren]] stack of the
1697  $P$-node of their parent.
1698  */
1699  newNode = new PQInternalNode<T, X, Y>(m_identificationNumber++,
1701  m_pertinentNodes->pushFront(newNode);
1702  newNode->m_pertChildCount = fullNodes->size();
1703  newNode->m_childCount = fullNodes->size();
1704 
1705  /*
1706  The first node is copied separately, since we need the pointer to it
1707  for setting the pointers to the siblings of the next full nodes.
1708  */
1709  PQNode<T, X, Y>* firstSon = fullNodes->popFrontRet();
1710  removeChildFromSiblings(firstSon);
1711  newNode->fullChildren->pushFront(firstSon);
1712  firstSon->m_parent = newNode;
1713  firstSon->m_parentType = newNode->type();
1714  PQNode<T, X, Y>* oldSon = firstSon;
1715 
1716 
1717  /*
1718  All remaining nodes that are stored in the stack [[fullNodes]] are
1719  introduced as children of the new $P$-node [[newNode]]. Observe
1720  that the children of a $P$-node must form a doubly linked list.
1721  Hence the last node and the [[firstSon]] must be linked via their
1722  siblings pointers.
1723  */
1724  while (!fullNodes->empty()) {
1725  PQNode<T, X, Y>* checkSon = fullNodes->popFrontRet();
1726  removeChildFromSiblings(checkSon);
1727  newNode->fullChildren->pushFront(checkSon);
1728  oldSon->m_sibRight = checkSon;
1729  checkSon->m_sibLeft = oldSon;
1730  checkSon->m_parent = newNode;
1731  checkSon->m_parentType = newNode->type();
1732  oldSon = checkSon;
1733  }
1734  firstSon->m_sibLeft = oldSon;
1735  oldSon->m_sibRight = firstSon;
1736  newNode->m_referenceChild = firstSon;
1737  firstSon->m_referenceParent = newNode;
1738  }
1739 
1740  return newNode;
1741 }
1742 
1743 template<class T, class X, class Y>
1745  while (!m_pertinentNodes->empty()) {
1746  PQNode<T, X, Y>* nodePtr = m_pertinentNodes->popFrontRet();
1747  switch (nodePtr->status()) {
1749  if (nodePtr == m_root) {
1750  m_root = nullptr;
1751  }
1752  CleanNode(nodePtr);
1753  OGDF_ASSERT(nodePtr);
1754  delete nodePtr;
1755  break;
1756 
1758  emptyNode(nodePtr);
1759  break;
1760 
1762  emptyNode(nodePtr);
1763  break;
1764 
1765  default:
1766  clientDefinedEmptyNode(nodePtr);
1767  break;
1768  }
1769  }
1770  m_pseudoRoot->m_pertChildCount = 0;
1771  m_pseudoRoot->m_pertLeafCount = 0;
1772  m_pseudoRoot->fullChildren->clear();
1773  m_pseudoRoot->partialChildren->clear();
1774  m_pseudoRoot->status(PQNodeRoot::PQNodeStatus::Empty);
1775  m_pseudoRoot->mark(PQNodeRoot::PQNodeMark::Unmarked);
1776 }
1777 
1778 template<class T, class X, class Y>
1781  nodePtr->m_pertChildCount = 0;
1782  nodePtr->m_pertLeafCount = 0;
1783  nodePtr->fullChildren->clear();
1784  nodePtr->partialChildren->clear();
1786 }
1787 
1788 template<class T, class X, class Y>
1790  if (oldNode->m_referenceParent != nullptr) {
1791  /*
1792  The node [[oldNode]] is connected to its parent
1793  via the reference pointer of the doubly linked list. The [[newNode]]
1794  will be the new reference child and is linked via the reference
1795  pointers to the $P$-node.
1796  */
1797  oldNode->m_referenceParent->m_referenceChild = newNode;
1798  newNode->m_referenceParent = oldNode->m_referenceParent;
1799  oldNode->m_referenceParent = nullptr;
1800  }
1801 
1802  else if (oldNode->endmostChild()) {
1803  /*
1804  The [[oldNode]] is endmost child of a Q-node. So its parent
1805  contains an extra pointer to [[oldNode]]. Link the parent of
1806  [[oldNode]] to [[newNode]] via this pointer and make [[newNode]]
1807  endmost child of its new parent.
1808  */
1809  if (oldNode->m_parent->m_leftEndmost == oldNode) {
1810  oldNode->m_parent->m_leftEndmost = newNode;
1811  } else if (oldNode->m_parent->m_rightEndmost == oldNode) {
1812  oldNode->m_parent->m_rightEndmost = newNode;
1813  }
1814  }
1815 
1816  if (oldNode->m_sibLeft == oldNode && oldNode->m_sibRight == oldNode) {
1817  /*
1818  Two possible cases are occured.
1819  \begin{enumerate}
1820  \item [[oldNode]] is the only child of a $P$-node. In order to
1821  implement the doubly linked list of children of the $P$-node, the sibling
1822  pointers of [[newNode]] are set to [[newNode]].
1823  \item [[oldNode]] is the [[m_root]] of the $PQ$-tree. Since
1824  by our definition of the $PQ$-tree the sibling pointers of the
1825  [[m_root]] point to the root itself, (i.e. to make sure that
1826  checking for the endmost child property is also valid for the root)
1827  the sibling pointers of [[newNode]] are set to [[newNode]] as well.
1828  \end{enumerate}
1829  */
1830  oldNode->m_sibLeft = nullptr;
1831  oldNode->m_sibRight = nullptr;
1832  if (oldNode->m_parent == nullptr) {
1833  newNode->m_sibLeft = newNode;
1834  newNode->m_sibRight = newNode;
1835  } else {
1836  newNode->m_sibLeft = newNode;
1837  newNode->m_sibRight = newNode;
1838  }
1839  } else {
1840  OGDF_ASSERT(!(oldNode->m_sibLeft == oldNode));
1841  //sibling pointers of old node are not compatible
1842  OGDF_ASSERT(!(oldNode->m_sibRight == oldNode));
1843  //sibling pointers of old node are not compatible.
1844  }
1845  /*
1846  Manage the exchange of [[oldNode]] and [[newNode]] according to
1847  [[oldNode]]'s siblings. The chunk checks both siblings of
1848  [[oldNode]] and resets the sibling pointers of [[oldNode]]'s siblings
1849  as well as the sibling pointers of [[newNode]].
1850  */
1851  if (oldNode->m_sibLeft != nullptr) {
1852  if (oldNode->m_sibLeft->m_sibRight == oldNode) {
1853  oldNode->m_sibLeft->m_sibRight = newNode;
1854  } else {
1855  // Sibling was not connected to child?
1856  OGDF_ASSERT(oldNode->m_sibLeft->m_sibLeft == oldNode);
1857  oldNode->m_sibLeft->m_sibLeft = newNode;
1858  }
1859  newNode->m_sibLeft = oldNode->m_sibLeft;
1860  oldNode->m_sibLeft = nullptr;
1861  }
1862 
1863  if (oldNode->m_sibRight != nullptr) {
1864  if (oldNode->m_sibRight->m_sibLeft == oldNode) {
1865  oldNode->m_sibRight->m_sibLeft = newNode;
1866  } else {
1867  // Sibling was not connected to child?
1868  OGDF_ASSERT(oldNode->m_sibRight->m_sibRight == oldNode);
1869  oldNode->m_sibRight->m_sibRight = newNode;
1870  }
1871  newNode->m_sibRight = oldNode->m_sibRight;
1872  oldNode->m_sibRight = nullptr;
1873  }
1874 
1875  newNode->m_parentType = oldNode->m_parentType;
1876  newNode->m_parent = oldNode->m_parent;
1877 }
1878 
1879 template<class T, class X, class Y>
1881  Queue<PQNode<T, X, Y>*> helpqueue;
1882  helpqueue.append(nodePtr);
1883 
1884  while (!helpqueue.empty()) {
1885  PQNode<T, X, Y>* checkNode = helpqueue.pop();
1886 
1887  if (checkNode->type() == PQNodeRoot::PQNodeType::Leaf) {
1888  leafKeys.pushBack(checkNode->getKey());
1889  } else {
1890  PQNode<T, X, Y>* firstSon = nullptr;
1891  PQNode<T, X, Y>* nextSon = nullptr;
1892  PQNode<T, X, Y>* oldSib = nullptr;
1893  PQNode<T, X, Y>* holdSib = nullptr;
1894 
1895  if (checkNode->type() == PQNodeRoot::PQNodeType::PNode) {
1896  OGDF_ASSERT(checkNode->m_referenceChild);
1897  firstSon = checkNode->m_referenceChild;
1898  } else if (checkNode->type() == PQNodeRoot::PQNodeType::QNode) {
1899  OGDF_ASSERT(checkNode->m_leftEndmost);
1900  firstSon = checkNode->m_leftEndmost;
1901  }
1902  helpqueue.append(firstSon);
1903  nextSon = firstSon->getNextSib(oldSib);
1904  oldSib = firstSon;
1905  while (nextSon && nextSon != firstSon) {
1906  helpqueue.append(nextSon);
1907  holdSib = nextSon->getNextSib(oldSib);
1908  oldSib = nextSon;
1909  nextSon = holdSib;
1910  }
1911  }
1912  }
1913 }
1914 
1915 template<class T, class X, class Y>
1917  m_pertinentNodes = new List<PQNode<T, X, Y>*>;
1918 
1919  if (!leafKeys.empty()) {
1922  m_pseudoRoot = newNode2;
1923 
1924  if (leafKeys.begin() != leafKeys.end()) // at least two elements
1925  {
1926  PQInternalNode<T, X, Y>* newNode = new PQInternalNode<T, X, Y>(m_identificationNumber++,
1928  m_root = newNode;
1929  m_root->m_sibLeft = m_root;
1930  m_root->m_sibRight = m_root;
1931  return addNewLeavesToTree(newNode, leafKeys);
1932  }
1933  PQLeaf<T, X, Y>* newLeaf = new PQLeaf<T, X, Y>(m_identificationNumber++,
1934  PQNodeRoot::PQNodeStatus::Empty, *leafKeys.begin());
1935  m_root = newLeaf;
1936  m_root->m_sibLeft = m_root;
1937  m_root->m_sibRight = m_root;
1938  return 1;
1939  }
1940 
1941  return 0;
1942 }
1943 
1944 template<class T, class X, class Y>
1946  if (installed != nullptr && newChild != nullptr) {
1947  if (installed->m_sibLeft == nullptr) {
1948  installed->m_sibLeft = newChild;
1949  if (newChild->m_sibRight == nullptr) {
1950  newChild->m_sibRight = installed;
1951  } else {
1952  newChild->m_sibLeft = installed;
1953  }
1954  } else {
1955  // endmost child with 2 siblings encountered?
1956  OGDF_ASSERT(installed->m_sibRight == nullptr);
1957 
1958  installed->m_sibRight = newChild;
1959  if (newChild->m_sibLeft == nullptr) {
1960  newChild->m_sibLeft = installed;
1961  } else {
1962  newChild->m_sibRight = installed;
1963  }
1964  }
1965  }
1966 }
1967 
1968 template<class T, class X, class Y>
1969 void PQTree<T, X, Y>::writeGML(const char* fileName) {
1970  std::ofstream os(fileName);
1971  writeGML(os);
1972 }
1973 
1974 template<class T, class X, class Y>
1975 void PQTree<T, X, Y>::writeGML(std::ostream& os) {
1976  Array<int> id(0, m_identificationNumber, 0);
1977  int nextId = 0;
1978 
1979  SListPure<PQNode<T, X, Y>*> helpQueue;
1980  SListPure<PQNode<T, X, Y>*> secondTrace;
1981 
1982  os.setf(std::ios::showpoint);
1983  os.precision(10);
1984 
1985  os << "Creator \"ogdf::PQTree::writeGML\"\n";
1986  os << "graph [\n";
1987  os << " directed 1\n";
1988 
1989  PQNode<T, X, Y>* checkNode = m_root;
1990  PQNode<T, X, Y>* firstSon = 0;
1991  PQNode<T, X, Y>* nextSon = 0;
1992  PQNode<T, X, Y>* lastSon = 0;
1993  PQNode<T, X, Y>* oldSib = 0;
1994  PQNode<T, X, Y>* holdSib = 0;
1995 
1996  if (checkNode->type() != PQNodeRoot::PQNodeType::Leaf) {
1997  secondTrace.pushBack(checkNode);
1998  }
1999 
2000  while (checkNode) {
2001  os << " node [\n";
2002 
2003  os << " id " << (id[checkNode->m_identificationNumber] = nextId++) << "\n";
2004 
2005  os << " label \"" << checkNode->m_identificationNumber;
2006  if (checkNode->getKey() != 0) {
2007  checkNode->getKey()->print(os);
2008  }
2009  os << "\"\n";
2010 
2011  os << " graphics [\n";
2012  if (m_root->status() == PQNodeRoot::PQNodeStatus::Full) {
2013  if (checkNode->type() == PQNodeRoot::PQNodeType::PNode) {
2014  os << " fill \"#FF0000\"\n";
2015  } else if (checkNode->type() == PQNodeRoot::PQNodeType::QNode) {
2016  os << " fill \"#0000A0\"\n";
2017  } else if (checkNode->type() == PQNodeRoot::PQNodeType::Leaf) {
2018  os << "fill \"#FFFFE6\"\n";
2019  }
2020  } else if (m_root->status() == PQNodeRoot::PQNodeStatus::Empty) {
2021  if (checkNode->type() == PQNodeRoot::PQNodeType::PNode) {
2022  os << " fill \"#FF0000\"\n";
2023  } else if (checkNode->type() == PQNodeRoot::PQNodeType::QNode) {
2024  os << " fill \"#0000A0\"\n";
2025  } else if (checkNode->type() == PQNodeRoot::PQNodeType::Leaf) {
2026  os << " fill \"#00FF00\"\n";
2027  }
2028  } else if (m_root->status() == PQNodeRoot::PQNodeStatus::Partial) {
2029  if (checkNode->type() == PQNodeRoot::PQNodeType::PNode) {
2030  os << " fill \"#FF0000\"\n";
2031  } else if (checkNode->type() == PQNodeRoot::PQNodeType::QNode) {
2032  os << " fill \"#0000A0\"\n";
2033  } else if (checkNode->type() == PQNodeRoot::PQNodeType::Leaf) {
2034  os << " fill \"#FFFFE6\"\n";
2035  }
2036  } else if (m_root->status() == PQNodeRoot::PQNodeStatus::Pertinent) {
2037  if (checkNode->type() == PQNodeRoot::PQNodeType::PNode) {
2038  os << " fill \"#FF0000\"\n";
2039  } else if (checkNode->type() == PQNodeRoot::PQNodeType::QNode) {
2040  os << " fill \"#0000A0\"\n";
2041  } else if (checkNode->type() == PQNodeRoot::PQNodeType::Leaf) {
2042  os << " fill \"#FFFFE6\"\n";
2043  }
2044  }
2045 
2046  os << " ]\n"; // graphics
2047  os << " ]\n"; // node
2048 
2049  if (checkNode->type() == PQNodeRoot::PQNodeType::PNode) {
2050  if (checkNode->m_referenceChild != 0) {
2051  firstSon = checkNode->m_referenceChild;
2052  helpQueue.pushBack(firstSon);
2053 
2054  if (firstSon->m_sibRight != 0) {
2055  nextSon = firstSon->m_sibRight;
2056  }
2057  while (nextSon != firstSon) {
2058  helpQueue.pushBack(nextSon);
2059  nextSon = nextSon->m_sibRight;
2060  }
2061  }
2062  } else if (checkNode->type() == PQNodeRoot::PQNodeType::QNode) {
2063  oldSib = 0;
2064  holdSib = 0;
2065 
2066  firstSon = checkNode->m_leftEndmost;
2067  helpQueue.pushBack(firstSon);
2068 
2069  lastSon = checkNode->m_rightEndmost;
2070  if (firstSon != lastSon) {
2071  helpQueue.pushBack(lastSon);
2072  nextSon = lastSon->getNextSib(oldSib);
2073  oldSib = lastSon;
2074  while (nextSon != firstSon) {
2075  helpQueue.pushBack(nextSon);
2076  holdSib = nextSon->getNextSib(oldSib);
2077  oldSib = nextSon;
2078  nextSon = holdSib;
2079  }
2080  }
2081  }
2082  if (!helpQueue.empty()) {
2083  checkNode = helpQueue.popFrontRet();
2084  if (checkNode->type() != PQNodeRoot::PQNodeType::Leaf) {
2085  secondTrace.pushBack(checkNode);
2086  }
2087  } else {
2088  checkNode = 0;
2089  }
2090  }
2091 
2092 
2094 
2095  for (it = secondTrace.begin(); it.valid(); ++it) {
2096  checkNode = *it;
2097  if (checkNode->type() == PQNodeRoot::PQNodeType::PNode) {
2098  if (checkNode->m_referenceChild != 0) {
2099  firstSon = checkNode->m_referenceChild;
2100  os << " edge [\n";
2101  os << " source " << id[checkNode->m_identificationNumber] << "\n";
2102  os << " target " << id[firstSon->m_identificationNumber] << "\n";
2103  os << " ]\n"; // edge
2104 
2105  if (firstSon->m_sibRight != 0) {
2106  nextSon = firstSon->m_sibRight;
2107  }
2108  while (nextSon != firstSon) {
2109  os << " edge [\n";
2110  os << " source " << id[checkNode->m_identificationNumber] << "\n";
2111  os << " target " << id[nextSon->m_identificationNumber] << "\n";
2112  os << " ]\n"; // edge
2113  nextSon = nextSon->m_sibRight;
2114  }
2115  }
2116  } else if (checkNode->type() == PQNodeRoot::PQNodeType::QNode) {
2117  oldSib = 0;
2118  holdSib = 0;
2119 
2120  firstSon = checkNode->m_leftEndmost;
2121  lastSon = checkNode->m_rightEndmost;
2122 
2123  os << " edge [\n";
2124  os << " source " << id[checkNode->m_identificationNumber] << "\n";
2125  os << " target " << id[lastSon->m_identificationNumber] << "\n";
2126  os << " ]\n"; // edge
2127  if (firstSon != lastSon) {
2128  nextSon = lastSon->getNextSib(oldSib);
2129  os << " edge [\n";
2130  os << " source " << id[checkNode->m_identificationNumber] << "\n";
2131  os << " target " << id[nextSon->m_identificationNumber] << "\n";
2132  os << " ]\n"; // edge
2133 
2134  oldSib = lastSon;
2135  while (nextSon != firstSon) {
2136  holdSib = nextSon->getNextSib(oldSib);
2137  oldSib = nextSon;
2138  nextSon = holdSib;
2139  os << " edge [\n";
2140  os << " source " << id[checkNode->m_identificationNumber] << "\n";
2141  os << " target " << id[nextSon->m_identificationNumber] << "\n";
2142  os << " ]\n"; // edge
2143  }
2144  }
2145  }
2146  }
2147  os << "]\n"; // graph
2148 }
2149 
2150 template<class T, class X, class Y>
2152  /* Variables:
2153  * - \a checkLeaf is a pointer to a various PQLeaf of the set of
2154  * elements that has to be reduced.
2155  * - \a checkNode is a pointer to a various node of the pertinent
2156  * subtree.
2157  * - \a pertLeafCount counts the number of pertinent leaves in the
2158  * PQ-tree. Since Reduce() takes care that every node knows the
2159  * number of pertinent leaves in its frontier, the root of the
2160  * pertinent subtree can be identified with the help of \a pertLeafCount.
2161  * - \a processNodes is a queue storing nodes of the pertinent
2162  * subtree that are considered to be reduced next. A node may be
2163  * reduced (and therefore is pushed on to \a processNodes) as soon as
2164  * all its pertinent children have been reduced.
2165  */
2166  int pertLeafCount = 0;
2167  Queue<PQNode<T, X, Y>*> processNodes;
2168 
2169  /*
2170  * In a first step the pertinent leaves have to be identified in the tree
2171  * and are entered on to the queue [[processNodes]]. The identification of
2172  * the leaves can be done with the help of a pointer stored in every
2173  * [[PQLeafKey]] in constant time for every element.
2174  */
2176  for (it = leafKeys.begin(); it.valid(); ++it) {
2177  PQNode<T, X, Y>* checkLeaf = (*it)->nodePointer();
2179  checkLeaf->m_pertLeafCount = 1;
2180  processNodes.append(checkLeaf);
2181  pertLeafCount++;
2182  }
2183 
2184  PQNode<T, X, Y>* checkNode = processNodes.top();
2185  while (checkNode != nullptr && processNodes.size() > 0) {
2186  checkNode = processNodes.pop();
2187 
2188  if (checkNode->m_pertLeafCount < pertLeafCount) {
2189  /*
2190  * Application of the template matchings to a pointer [[checkNode]]
2191  * storing the adress of a node that is <b>not the root</b> of the
2192  * pertinent subtree. Before applying the template matchings to
2193  * [[checkNode]], some values of the parent of [[checkNode]] are
2194  * updated. The number of the parents pertinent children stored in
2195  * [[pertChildCount]] is count down by one. In case that
2196  * [[checkNode->m_parent->m_pertChildCount == 0]], we know that all
2197  * pertinent children of the parent have been processed. Since the
2198  * parent then is allowed to be processed as well,
2199  * [[checkNode->m_parent]] is stored in the queue [[processNodes]].
2200  */
2201  checkNode->m_parent->m_pertLeafCount =
2202  checkNode->m_parent->m_pertLeafCount + checkNode->m_pertLeafCount;
2203 
2204  checkNode->m_parent->m_pertChildCount--;
2205  if (!checkNode->m_parent->m_pertChildCount) {
2206  processNodes.append(checkNode->m_parent);
2207  }
2208  if (!templateL1(checkNode, 0) && !templateP1(checkNode, 0) && !templateP3(checkNode)
2209  && !templateP5(checkNode) && !templateQ1(checkNode, 0)
2210  && !templateQ2(checkNode, 0)) {
2211  checkNode = nullptr;
2212  }
2213  } else {
2214  /*
2215  * application of the template matchings to a pointer [[checkNode]]
2216  * that stores the adress of a node that <b>is the root</b> of the
2217  * pertinent subtree. In a case that a template matching was
2218  * successfully applied, the pointer [[checkNode]] stores after the
2219  * application the adress of the root of pertinent subtree. This
2220  * includes nodes that have been newly introduced as root of the
2221  * pertinent subtree during the application. If no template matching
2222  * was successfully applied [[checkNode]] is a [[0]] pointer.
2223  */
2224  if (!templateL1(checkNode, 1) && !templateP1(checkNode, 1) && !templateP2(&checkNode)
2225  && !templateP4(&checkNode) && !templateP6(&checkNode) && !templateQ1(checkNode, 1)
2226  && !templateQ2(checkNode, 1) && !templateQ3(checkNode)) {
2227  checkNode = nullptr;
2228  }
2229  }
2230  }
2231 
2232  m_pertinentRoot = checkNode;
2233  return m_pertinentRoot != nullptr;
2234 }
2235 
2236 template<class T, class X, class Y>
2238  /* Reduction() calls the procedure Bubble() and if Bubble() was
2239  * successful, Reduction() calls the function Reduce().
2240  */
2241  bool success = Bubble(leafKeys);
2242 
2243  if (!success) {
2244  return false;
2245  } else {
2246  return Reduce(leafKeys);
2247  }
2248 }
2249 
2250 template<class T, class X, class Y>
2251 void PQTree<T, X, Y>::removeBlock(PQNode<T, X, Y>* nodePtr, bool isRoot) {
2252  /*
2253  For every
2254  partial child we keep a set of pointers. Since there are at most
2255  two partial children, we initialize two sets. Every set contains
2256  besides a pointer to the partial child four pointers to its endmost
2257  children, sorted according to their full or empty labels and pointers
2258  to the immediate siblings of the partial child, also sorted according
2259  to their full or empty labels.
2260  */
2262  PQNode<T, X, Y>* partial_1 = nullptr;
2263 
2264  /*
2265  Pointer to the full endmost child (more
2266  precisely: to the endmost child appearing on the full side) of
2267  [[partial_1]]. In case that ignored nodes are used, this [[endfull_1]]
2268  may store the adress of an ignored node.
2269  */
2270  PQNode<T, X, Y>* endfull_1 = nullptr;
2271 
2272  /*
2273  Pointer to the empty endmost child (more
2274  precisely: to the endmost child appearing on the empty side) of
2275  [[partial_1]]. In case that ignored nodes are used, this [[endempty_1]]
2276  may store the adress of an ignored node.
2277  */
2278  PQNode<T, X, Y>* endempty_1 = nullptr;
2279 
2280  /*
2281  Pointer to the first <i>non ignored</i> node
2282  with full status. [[realfull_1]] is identical to [[endfull_1]] if no
2283  ignored nodes appear at the full end of the first partial child.
2284  */
2285  PQNode<T, X, Y>* realfull_1 = nullptr;
2286 
2287  /*
2288  Pointer to the first <i>non ignored</i> node
2289  with empty status. [[realempty_1]] is identical to [[endempty_1]] if no
2290  ignored nodes appear at the empty end of the first partial child.
2291  */
2292  PQNode<T, X, Y>* realempty_1 = nullptr;
2293 
2294  // Pointer to the second partial child.
2295  PQNode<T, X, Y>* partial_2 = nullptr;
2296 
2297  /*
2298  Pointer to the full endmost child (more
2299  precisely: to the endmost child appearing on the full side) of
2300  [[partial_2]]. In case that ignored nodes are used, this [[endfull_2]]
2301  may store the adress of an ignored node.
2302  */
2303  PQNode<T, X, Y>* endfull_2 = nullptr;
2304 
2305  /*
2306  Pointer to the empty endmost child (more
2307  precisely: to the endmost child appearing on the empty side) of
2308  [[partial_2]]. In case that ignored nodes are used, this [[endempty_2]]
2309  may store the adress of an ignored node.
2310  */
2311  PQNode<T, X, Y>* endempty_2 = nullptr;
2312 
2313  /*
2314  Pointer to the first <i>non ignored</i> node
2315  with empty status. [[realempty_2]] is identical to [[endempty_2]] if no
2316  ignored nodes appear at the empty end of the first partial child.
2317  */
2318  PQNode<T, X, Y>* realempty_2 = nullptr;
2319 
2320  /*
2321  Pointer to a full sibling of
2322  [[partial_1]], if it exists. In case that ignored nodes are used
2323  this [[sibfull_1]] stores the direct sibling of [[partial_1]]
2324  on the side where the full siblings are. Hence [[sibfull_1]] may
2325  store an ignored node.
2326  */
2327  PQNode<T, X, Y>* sibfull_1 = nullptr;
2328 
2329  /*
2330  Pointer to a partial sibling of
2331  [[partial_1]], if it exists. In case that ignored nodes are used
2332  this [[sibpartial_1]] stores the direct sibling of [[partial_1]]
2333  on the side where a partial sibling is. Hence [[sibpartial_1]] may
2334  store an ignored node.
2335  */
2336  PQNode<T, X, Y>* sibpartial_1 = nullptr;
2337 
2338  /*
2339  Pointer to an empty sibling of
2340  [[parial_1]], if it exists. In case that ignored nodes are used
2341  this [[sibempty_1]] stores the direct sibling of [[partial_1]]
2342  on the side where the empty siblings are. Hence [[sibempty_1]] may
2343  store an ignored node.
2344  */
2345  PQNode<T, X, Y>* sibempty_1 = nullptr;
2346 
2347  /*
2348  Pointer only used in case that [[partial_1]] has
2349  no non-ignored siblings on one side. [[partial_1]] then is endmost child
2350  of [[nodePtr]], but ignored children may appear between [[partial_1]]
2351  and the end of sequence of children of [[nodePtr]]. The
2352  [[nonstatussib_1]] then stores the adress of the endmost ignored child.
2353  Observe that it is not valid for a $Q$-node to have only one
2354  non-ignored child and several ignored children. Hence this situation
2355  is only allowed to appear <b>once</b> on one side of [[partial_1]].
2356  Every other situation results in an error message.
2357  */
2358  PQNode<T, X, Y>* nonstatussib_1 = nullptr;
2359 
2360  /*
2361  Pointer to a full sibling of
2362  [[partial_2]], if it exists. In case that ignored nodes are used
2363  this [[sibfull_2]] stores the direct sibling of [[partial_2]]
2364  on the side where the full siblings are. Hence [[sibfull_2]] may
2365  store an ignored node.
2366  */
2367  PQNode<T, X, Y>* sibfull_2 = nullptr;
2368 
2369  /*
2370  Pointer to a partial sibling of
2371  [[partial_2]], if it exists. In case that ignored nodes are used
2372  this [[sibpartial_2]] stores the direct sibling of [[partial_2]]
2373  on the side where a partial sibling is. Hence [[sibpartial_2]] may
2374  store an ignored node.
2375  */
2376  PQNode<T, X, Y>* sibpartial_2 = nullptr;
2377 
2378  /*
2379  Pointer to an empty sibling of
2380  [[parial_2]], if it exists. In case that ignored nodes are used
2381  this [[sibempty_2]] stores the direct sibling of [[partial_2]]
2382  on the side where the empty siblings are. Hence [[sibempty_2]] may
2383  store an ignored node.
2384  */
2385  PQNode<T, X, Y>* sibempty_2 = nullptr;
2386 
2387  /*
2388  Pointer only used in case that [[partial_2]] has
2389  no non-ignored siblings on one side. [[partial_2]] then is endmost child
2390  of [[nodePtr]], but ignored children may appear between [[partial_2]]
2391  and the end of sequence of children of [[nodePtr]]. The
2392  [[nonstatussib_2]] then stores the adress of the endmost ignored child.
2393  Observe that it is not valid for a $Q$-node to have only one
2394  non-ignored child and several ignored children. Hence this situation
2395  is only allowed to appear <b>once</b> on one side of [[partial_2]].
2396  Every other situation results in an error message.
2397  */
2398  PQNode<T, X, Y>* nonstatussib_2 = nullptr;
2399 
2400  PQNode<T, X, Y>* helpptr = nullptr;
2401 
2402  PQNode<T, X, Y>* checkVarLeft = nullptr;
2403 
2404  PQNode<T, X, Y>* checkVarRight = nullptr;
2405 
2406  /*
2407  [[endmostcheck]] is [[1]], if [[partial_1]] is the endmost
2408  child of [[nodePtr]]. Per default, [[endmostcheck]] is [[0]].
2409  */
2410  int endmostcheck = 0;
2411 
2412 
2414  if (!isRoot) {
2415  nodePtr->m_parent->partialChildren->pushFront(nodePtr);
2416  }
2417 
2418  if (!nodePtr->partialChildren->empty()) { // Get a partial child.
2419  partial_1 = nodePtr->partialChildren->popFrontRet();
2420 
2421  // Get the full and empty
2422  // endmost children of the
2423  // partial child [[partial_1]].
2424  checkVarLeft = clientLeftEndmost(partial_1);
2425  checkVarRight = clientRightEndmost(partial_1);
2426  if (checkVarLeft->status() == PQNodeRoot::PQNodeStatus::Full) {
2427  endfull_1 = partial_1->m_leftEndmost;
2428  realfull_1 = checkVarLeft;
2429  } else {
2430  // partial child with no full endmost child detected?
2431  OGDF_ASSERT(checkVarRight->status() == PQNodeRoot::PQNodeStatus::Full);
2432 
2433  endfull_1 = partial_1->m_rightEndmost;
2434  realfull_1 = checkVarRight;
2435  }
2436 
2437  if (checkVarLeft->status() == PQNodeRoot::PQNodeStatus::Empty) {
2438  endempty_1 = partial_1->m_leftEndmost;
2439  realempty_1 = checkVarLeft;
2440  } else {
2441  // partial child with no empty endmost child detected?
2442  OGDF_ASSERT(checkVarRight->status() == PQNodeRoot::PQNodeStatus::Empty);
2443 
2444  endempty_1 = partial_1->m_rightEndmost;
2445  realempty_1 = checkVarRight;
2446  }
2447 
2448  // Get the immediate
2449  // siblings of the partial
2450  // child [[partial_1]].
2451  if (clientSibLeft(partial_1) != nullptr) {
2452  if (clientSibLeft(partial_1)->status() == PQNodeRoot::PQNodeStatus::Full) {
2453  sibfull_1 = partial_1->m_sibLeft;
2454  } else if (clientSibLeft(partial_1)->status() == PQNodeRoot::PQNodeStatus::Empty) {
2455  sibempty_1 = partial_1->m_sibLeft;
2456  } else if (clientSibLeft(partial_1)->status() == PQNodeRoot::PQNodeStatus::Partial) {
2457  sibpartial_1 = partial_1->m_sibLeft;
2458  }
2459  } else {
2460  nonstatussib_1 = partial_1->m_sibLeft;
2461  }
2462 
2463  if (clientSibRight(partial_1) != nullptr) {
2464  if (clientSibRight(partial_1)->status() == PQNodeRoot::PQNodeStatus::Full) {
2465  sibfull_1 = partial_1->m_sibRight;
2466  } else if (clientSibRight(partial_1)->status() == PQNodeRoot::PQNodeStatus::Empty) {
2467  sibempty_1 = partial_1->m_sibRight;
2468  } else if (clientSibRight(partial_1)->status() == PQNodeRoot::PQNodeStatus::Partial) {
2469  sibpartial_1 = partial_1->m_sibRight;
2470  }
2471  } else {
2472  // partial child detected with no siblings of valid status?
2473  OGDF_ASSERT(nonstatussib_1 == nullptr);
2474  nonstatussib_1 = partial_1->m_sibRight;
2475  }
2476  }
2477 
2478 
2479  if (!nodePtr->partialChildren->empty()) { // There is a second partial child.
2480  partial_2 = nodePtr->partialChildren->popFrontRet();
2481  // Get the full and empty endmost
2482  // children of the partial
2483  // child [[partial_2]].
2484 
2485  checkVarLeft = clientLeftEndmost(partial_2);
2486  checkVarRight = clientRightEndmost(partial_2);
2487  if (checkVarLeft->status() == PQNodeRoot::PQNodeStatus::Full) {
2488  endfull_2 = partial_2->m_leftEndmost;
2489  } else {
2490  // partial child with no full endmost child detected?
2491  OGDF_ASSERT(checkVarRight->status() == PQNodeRoot::PQNodeStatus::Full);
2492 
2493  endfull_2 = partial_2->m_rightEndmost;
2494  }
2495 
2496  if (checkVarLeft->status() == PQNodeRoot::PQNodeStatus::Empty) {
2497  endempty_2 = partial_2->m_leftEndmost;
2498  realempty_2 = checkVarLeft;
2499  } else {
2500  // partial child with no empty endmost child detected?
2501  OGDF_ASSERT(checkVarRight->status() == PQNodeRoot::PQNodeStatus::Empty);
2502 
2503  endempty_2 = partial_2->m_rightEndmost;
2504  realempty_2 = checkVarRight;
2505  }
2506  // Get the immediate siblings
2507  // of the partial child
2508  // [[partial_2]].
2509  if (clientSibLeft(partial_2) != nullptr) {
2510  if (clientSibLeft(partial_2)->status() == PQNodeRoot::PQNodeStatus::Full) {
2511  sibfull_2 = partial_2->m_sibLeft;
2512  } else if (clientSibLeft(partial_2)->status() == PQNodeRoot::PQNodeStatus::Empty) {
2513  sibempty_2 = partial_2->m_sibLeft;
2514  } else if (clientSibLeft(partial_2)->status() == PQNodeRoot::PQNodeStatus::Partial) {
2515  sibpartial_2 = partial_2->m_sibLeft;
2516  }
2517  } else {
2518  nonstatussib_2 = partial_2->m_sibLeft;
2519  }
2520 
2521 
2522  if (clientSibRight(partial_2) != nullptr) {
2523  if (clientSibRight(partial_2)->status() == PQNodeRoot::PQNodeStatus::Full) {
2524  sibfull_2 = partial_2->m_sibRight;
2525  } else if (clientSibRight(partial_2)->status() == PQNodeRoot::PQNodeStatus::Empty) {
2526  sibempty_2 = partial_2->m_sibRight;
2527  } else if (clientSibRight(partial_2)->status() == PQNodeRoot::PQNodeStatus::Partial) {
2528  sibpartial_2 = partial_2->m_sibRight;
2529  }
2530  } else {
2531  OGDF_ASSERT(nonstatussib_2 == nullptr);
2532  nonstatussib_2 = partial_2->m_sibRight;
2533  }
2534  }
2535 
2536 
2537  if (partial_1 != nullptr && partial_2 != nullptr)
2538 
2539  /*
2540  Connect the endmost
2541  children of the partial children [[partial_1]] and [[partial_2]] correctly
2542  with their new siblings. In doing this, all children of the partial
2543  children become children of [[nodePtr]]. The reader should observe that
2544  the parent pointers of the interior children of [[partial_1]] and
2545  [[partial_2]] are not updated in order to hit the linear time complexity.
2546 
2547  When including the children of the partial children to the children
2548  of [[nodePtr]], it is taken care that all full children
2549  form a consecutive sequence afterwards. If neccessary the pointers to the
2550  endmost children of [[nodePtr]] are updated.
2551  */
2552  {
2553  if (sibfull_1 != nullptr && sibfull_2 != nullptr)
2554  // There are full children between
2555  // the 2 partial nodes.
2556  // Connect the full children
2557  // between the 2 partial children
2558  // with the full endmost children
2559  // of the 2 partial nodes.
2560  {
2561  sibfull_1->changeSiblings(partial_1, endfull_1);
2562  endfull_1->putSibling(sibfull_1);
2563  sibfull_2->changeSiblings(partial_2, endfull_2);
2564  endfull_2->putSibling(sibfull_2);
2565  }
2566 
2567  else if (sibpartial_1 != nullptr && sibpartial_2 != nullptr)
2568  // There are no full children between
2569  // the 2 partial nodes. Connect the
2570  // full endmost children of the
2571  // partial nodes as siblings.
2572  {
2573  if (partial_1 == sibpartial_2 && partial_2 == sibpartial_1)
2574  // Regular Case.
2575  {
2576  endfull_1->putSibling(endfull_2);
2577  endfull_2->putSibling(endfull_1);
2578  }
2579  // Only ignored children between
2580  // partial_1 and partial_2.
2581  else {
2582  endfull_1->putSibling(sibpartial_1);
2583  sibpartial_1->changeSiblings(partial_1, endfull_1);
2584  endfull_2->putSibling(sibpartial_2);
2585  sibpartial_2->changeSiblings(partial_2, endfull_2);
2586  }
2587  }
2588  // Include the children of the
2589  // partial children with their
2590  // full nodes inbetween into
2591  // the sequence of the children of
2592  // Q-node nodePtr.
2593  if (sibempty_1 == nullptr)
2594  // partial_1 is endmost child of
2595  // nodePtr. Make the empty endmost
2596  // child of partial_1 be the new
2597  // endmost child of nodePtr.
2598  {
2599  if (nonstatussib_1 == nullptr)
2600  // Regular case.
2601  {
2602  nodePtr->changeEndmost(partial_1, endempty_1);
2603  } else
2604  // Only ignored children between
2605  // partial_1 and one end of nodePtr.
2606  {
2607  nonstatussib_1->changeSiblings(partial_1, endempty_1);
2608  endempty_1->putSibling(nonstatussib_1);
2609  }
2610  endempty_1->m_parent = nodePtr;
2611  realempty_1->m_parent = nodePtr;
2612  }
2613 
2614  else
2615  // partial_1 is not endmost child.
2616  {
2617  sibempty_1->changeSiblings(partial_1, endempty_1);
2618  endempty_1->putSibling(sibempty_1);
2619  }
2620 
2621 
2622  if (sibempty_2 == nullptr)
2623  // partial_2 is endmost child of
2624  // nodePtr. Make the empty endmost
2625  // child of partial_2 be the new
2626  // endmost child of nodePtr.
2627  {
2628  if (nonstatussib_2 == nullptr)
2629  // Regular case.
2630  {
2631  nodePtr->changeEndmost(partial_2, endempty_2);
2632  } else
2633  // Only ignored children between
2634  // partial_1 and one end of
2635  // nodePtr.
2636  {
2637  nonstatussib_2->changeSiblings(partial_2, endempty_2);
2638  endempty_2->putSibling(nonstatussib_2);
2639  }
2640  endempty_2->m_parent = nodePtr;
2641  realempty_2->m_parent = nodePtr;
2642  }
2643 
2644  else
2645  // partial_2 is not endmost child.
2646  {
2647  sibempty_2->changeSiblings(partial_2, endempty_2);
2648  endempty_2->putSibling(sibempty_2);
2649  }
2650 
2651  // Copy the full children of
2652  // partial_1 and partial_2 to
2653  // nodePtr.
2654  while (!partial_2->fullChildren->empty()) {
2655  helpptr = partial_2->fullChildren->popFrontRet();
2656  nodePtr->fullChildren->pushFront(helpptr);
2657  }
2658  nodePtr->m_childCount = nodePtr->m_childCount + partial_2->m_childCount - 1;
2659 
2660  destroyNode(partial_2);
2661 
2662  while (!partial_1->fullChildren->empty()) {
2663  helpptr = partial_1->fullChildren->popFrontRet();
2664  nodePtr->fullChildren->pushFront(helpptr);
2665  }
2666  nodePtr->m_childCount = nodePtr->m_childCount + partial_1->m_childCount - 1;
2667 
2668  destroyNode(partial_1);
2669  }
2670 
2671 
2672  else if (partial_1 != nullptr)
2673 
2674  /*
2675  Connect the endmost
2676  children of the partial child [[partial_1]] correctly
2677  with their new siblings. In doing this, all children of the partial
2678  child become children of [[nodePtr]]. The reader should observe that
2679  the parent pointers of the interior children of [[partial_1]]
2680  are not updated in order to hit the linear time complexity.
2681 
2682  When including the children of [[partial_1]] to the children
2683  of [[nodePtr]], it is taken care that all full children
2684  form a consecutive sequence afterwards. If necessary the pointers to the
2685  endmost children of [[nodePtr]] are updated.
2686  */
2687  {
2688  if ((clientLeftEndmost(nodePtr) == partial_1) || (clientRightEndmost(nodePtr) == partial_1)) {
2689  // partial_1 is endmost child.
2690  endmostcheck = 1;
2691  }
2692 
2693  if (sibfull_1 != nullptr)
2694  // There are full children on one
2695  // side of the partial node.
2696  // Connect the full children with
2697  // the full endmost child of
2698  // partial_1.
2699  {
2700  sibfull_1->changeSiblings(partial_1, endfull_1);
2701  endfull_1->putSibling(sibfull_1);
2702  }
2703 
2704  else if (!endmostcheck)
2705  // There are not any full children
2706  // and partial_1 is not endmost.
2707  // So get the 2nd empty sibling
2708  // of partial_1 and connect it
2709  // to the full endmost child
2710  // of partial_1.
2711  {
2712  if (partial_1->m_sibLeft != sibempty_1) {
2713  sibempty_2 = partial_1->m_sibLeft;
2714  } else {
2715  sibempty_2 = partial_1->m_sibRight;
2716  }
2717 
2718  sibempty_2->changeSiblings(partial_1, endfull_1);
2719  endfull_1->putSibling(sibempty_2);
2720  }
2721 
2722  else
2723  // partial_1 is endmost child
2724  // and there are no full children.
2725  // Make the full endmost child of
2726  // partial_1 be the endmostchild
2727  // of nodePtr.
2728  {
2729  if (nonstatussib_1 == nullptr)
2730  // Regular case.
2731  {
2732  nodePtr->changeEndmost(partial_1, endfull_1);
2733  } else
2734  // Only ignored children between
2735  // partial_1 and one end of
2736  // nodePtr.
2737  {
2738  nonstatussib_1->changeSiblings(partial_1, endfull_1);
2739  endfull_1->putSibling(nonstatussib_1);
2740  }
2741  endfull_1->m_parent = nodePtr;
2742  realfull_1->m_parent = nodePtr;
2743  }
2744 
2745  if (sibempty_1 == nullptr)
2746  // There are no empty children.
2747  // partial_1 is endmost child of
2748  // nodePtr. Make the empty endmost
2749  // child of partial_1 be the new
2750  // endmost child of nodePtr.
2751  {
2752  if (nonstatussib_1 == nullptr)
2753  // Regular case.
2754  {
2755  nodePtr->changeEndmost(partial_1, endempty_1);
2756  } else
2757  // Only ignored children between
2758  // partial_1 and one end of
2759  // nodePtr.
2760  {
2761  nonstatussib_1->changeSiblings(partial_1, endempty_1);
2762  endempty_1->putSibling(nonstatussib_1);
2763  }
2764  endempty_1->m_parent = nodePtr;
2765  realempty_1->m_parent = nodePtr;
2766  }
2767 
2768  else
2769  // There are empty children. So
2770  // connect the empty endmost child
2771  // of partial_1 with sibempty_1.
2772  {
2773  sibempty_1->changeSiblings(partial_1, endempty_1);
2774  endempty_1->putSibling(sibempty_1);
2775  }
2776 
2777  while (!partial_1->fullChildren->empty()) {
2778  helpptr = partial_1->fullChildren->popFrontRet();
2779  nodePtr->fullChildren->pushFront(helpptr);
2780  }
2781 
2782  nodePtr->m_childCount = nodePtr->m_childCount + partial_1->m_childCount - 1;
2783  destroyNode(partial_1);
2784  }
2785  // else nodePtr does not have partial children. Then nothing is to do.
2786 }
2787 
2788 template<class T, class X, class Y>
2790  if (nodePtr->m_referenceParent != nullptr) {
2791  /*
2792  Checksif [[nodePtr]] is connected with its parent via the reference
2793  pointers (see \ref{PQNode}). If so, the next sibling of [[nodePtr]]
2794  will be the the new reference child.
2795  */
2796  nodePtr->m_referenceParent->m_referenceChild = nodePtr->m_sibRight;
2797  nodePtr->m_sibRight->m_referenceParent = nodePtr->m_referenceParent;
2798  if (nodePtr->m_referenceParent->m_referenceChild == nodePtr) {
2799  nodePtr->m_referenceParent->m_referenceChild = nullptr;
2800  }
2801  nodePtr->m_referenceParent = nullptr;
2802  } else if (nodePtr->endmostChild()) {
2803  /*
2804  Check if [[nodePtr]] is the endmost child of a $Q$-node.
2805  If so, the next sibling of [[nodePtr]] will be the the new endmost
2806  child of the $Q$-node. Observe that the sibling then gets a valid
2807  pointer to its parent.
2808  */
2809  PQNode<T, X, Y>* sibling = nodePtr->getNextSib(nullptr);
2810  if (nodePtr->m_parent->m_leftEndmost == nodePtr) {
2811  nodePtr->m_parent->m_leftEndmost = sibling;
2812  } else if (nodePtr->m_parent->m_rightEndmost == nodePtr) {
2813  nodePtr->m_parent->m_rightEndmost = sibling;
2814  }
2815  if (sibling != nullptr) {
2816  sibling->m_parent = nodePtr->m_parent;
2817  }
2818  }
2819 
2820  /*
2821  Remove [[nodePtr]] from its immediate siblings and links the
2822  siblings via the [[sibRight]] and [[sibLeft]] pointers.
2823  */
2824  if (nodePtr->m_sibRight != nullptr && nodePtr->m_sibRight != nodePtr) {
2825  if (nodePtr->m_sibRight->m_sibLeft == nodePtr) {
2826  nodePtr->m_sibRight->m_sibLeft = nodePtr->m_sibLeft;
2827  } else {
2828  // Sibling was not connected to child?
2829  OGDF_ASSERT(nodePtr->m_sibRight->m_sibRight == nodePtr);
2830  nodePtr->m_sibRight->m_sibRight = nodePtr->m_sibLeft;
2831  }
2832  }
2833  if (nodePtr->m_sibLeft != nullptr && nodePtr->m_sibLeft != nodePtr) {
2834  if (nodePtr->m_sibLeft->m_sibRight == nodePtr) {
2835  nodePtr->m_sibLeft->m_sibRight = nodePtr->m_sibRight;
2836  } else {
2837  // Sibling was not connected to child?
2838  OGDF_ASSERT(nodePtr->m_sibLeft->m_sibLeft == nodePtr);
2839  nodePtr->m_sibLeft->m_sibLeft = nodePtr->m_sibRight;
2840  }
2841  }
2842 
2843  nodePtr->m_sibRight = nullptr;
2844  nodePtr->m_sibLeft = nullptr;
2845 }
2846 
2847 template<class T, class X, class Y>
2849  if (parent != nullptr) {
2850  removeChildFromSiblings(child);
2851  parent->m_childCount--;
2852  if (child->status() == PQNodeRoot::PQNodeStatus::Full
2853  || child->status() == PQNodeRoot::PQNodeStatus::Partial) {
2854  parent->m_pertChildCount--;
2855  }
2856  return parent->m_childCount;
2857  } else {
2858  //parent is invalid 0-pointer.
2859  return -1;
2860  }
2861 }
2862 
2863 template<class T, class X, class Y>
2864 void PQTree<T, X, Y>::sortExceptions(int Exceptions[], int arraySize) {
2865  bool changed = true;
2866  while (changed) {
2867  changed = false;
2868  for (int i = 0; i < (arraySize - 1); i++) {
2869  if (Exceptions[i] > Exceptions[i + 1]) {
2870  std::swap(Exceptions[i], Exceptions[i + 1]);
2871  changed = true;
2872  }
2873  }
2874  }
2875 }
2876 
2877 template<class T, class X, class Y>
2878 bool PQTree<T, X, Y>::templateL1(PQNode<T, X, Y>* nodePtr, bool isRoot) {
2879  if (nodePtr->type() == PQNodeRoot::PQNodeType::Leaf
2880  && nodePtr->status() == PQNodeRoot::PQNodeStatus::Full) {
2881  if (!isRoot) {
2882  nodePtr->m_parent->fullChildren->pushFront(nodePtr);
2883  }
2884  return true;
2885  }
2886 
2887  return false;
2888 }
2889 
2890 template<class T, class X, class Y>
2891 bool PQTree<T, X, Y>::templateP1(PQNode<T, X, Y>* nodePtr, bool isRoot) {
2892  if (nodePtr->type() != PQNodeRoot::PQNodeType::PNode
2893  || nodePtr->fullChildren->size() != nodePtr->m_childCount) {
2894  return false;
2895  } else {
2897  if (!isRoot) {
2898  nodePtr->m_parent->fullChildren->pushFront(nodePtr);
2899  }
2900 
2901  return true;
2902  }
2903 }
2904 
2905 template<class T, class X, class Y>
2907  if ((*nodePtr)->type() != PQNodeRoot::PQNodeType::PNode
2908  || (*nodePtr)->partialChildren->size() > 0) {
2909  return false;
2910  }
2911 
2912  (*nodePtr)->m_childCount = (*nodePtr)->m_childCount - (*nodePtr)->fullChildren->size() + 1;
2913  // Gather all full children of nodePtr
2914  // as children of the new P-node.
2915  // Delete them from nodePtr.
2916 
2917  PQNode<T, X, Y>* newNode = createNodeAndCopyFullChildren((*nodePtr)->fullChildren);
2918  // Correct parent-pointer and
2919  // sibling-pointers of the new P-node.
2920 
2921  newNode->m_parent = (*nodePtr);
2922  newNode->m_sibRight = (*nodePtr)->m_referenceChild->m_sibRight;
2923  newNode->m_sibLeft = newNode->m_sibRight->m_sibLeft;
2924  newNode->m_sibLeft->m_sibRight = newNode;
2925  newNode->m_sibRight->m_sibLeft = newNode;
2927  // The new P-node now is the root of
2928  // the pertinent subtree.
2929  (*nodePtr) = newNode;
2930 
2931  return true;
2932 }
2933 
2934 template<class T, class X, class Y>
2936  /* Variables:
2937  * - \p newPnode is the pointer to the new P-node, or, in case
2938  * that \p nodePtr has only one full child, is the pointer of this child.
2939  * - \p newQnode is the pointer to the new Q-node.
2940  * - \p newNode is used for the proper allocation of the new
2941  * Q-node.
2942  * - \p emptyNode is a pointer to any empty child of \p nodePtr.
2943  */
2944  if (nodePtr->type() != PQNodeRoot::PQNodeType::PNode || nodePtr->partialChildren->size() > 0) {
2945  return false;
2946  }
2947 
2948  /*
2949  Create a new partial $Q$-node stored in [[newQnode]].
2950  It replaces [[nodePtr]] by the Q-node [[newQnode]] in the $PQ$-tree
2951  and makes [[nodePtr]] endmost child of [[newQnode]].
2952  This is done by updating parent-pointers and sibling-pointers.
2953  */
2954  PQInternalNode<T, X, Y>* newNode = new PQInternalNode<T, X, Y>(m_identificationNumber++,
2956  PQNode<T, X, Y>* newQnode = newNode;
2957  m_pertinentNodes->pushFront(newQnode);
2958 
2959  exchangeNodes(nodePtr, newQnode);
2960  nodePtr->m_parent = newQnode;
2962 
2963  newQnode->m_leftEndmost = (nodePtr);
2964  newQnode->m_childCount = 1;
2965 
2966  /*
2967  Create a new full $P$-node stored in [[newPnode]].
2968  It copies the full children of [[nodePtr]] to [[newPnode]].
2969  The new $P$-node will then be included into the tree as child of
2970  the new $Q$-node [[newQnode]].
2971  */
2972  if (nodePtr->fullChildren->size() > 0) {
2973  nodePtr->m_childCount = nodePtr->m_childCount - nodePtr->fullChildren->size();
2974 
2975  PQNode<T, X, Y>* newPnode = createNodeAndCopyFullChildren(nodePtr->fullChildren);
2977 
2978  // Update newQnode.
2979  newQnode->m_childCount++;
2980  newQnode->fullChildren->pushFront(newPnode);
2981  // Update sibling pointers.
2982  nodePtr->m_sibRight = newPnode;
2983  newPnode->m_sibLeft = nodePtr;
2984  newQnode->m_rightEndmost = newPnode;
2985  newPnode->m_parent = newQnode;
2986  }
2987 
2988  // Check if nodePtr contains
2989  // only one son. If so, nodePtr
2990  // will be deleted from the tree.
2991  PQNode<T, X, Y>* emptyNode = nodePtr->m_referenceChild;
2992  checkIfOnlyChild(emptyNode, nodePtr);
2993  // Update partialchildren stack of
2994  // the parent of the new Q-node.
2995  newQnode->m_parent->partialChildren->pushFront(newQnode);
2996 
2997  return true;
2998 }
2999 
3000 template<class T, class X, class Y>
3002  if ((*nodePtr)->type() != PQNodeRoot::PQNodeType::PNode
3003  || (*nodePtr)->partialChildren->size() != 1) {
3004  return false;
3005  }
3006 
3007  PQNode<T, X, Y>* partialChild = (*nodePtr)->partialChildren->popFrontRet();
3008  copyFullChildrenToPartial(*nodePtr, partialChild);
3009  // If nodePtr does not have any
3010  // empty children, then it has to
3011  // be deleted and the partial node
3012  // is occupying its place in the tree.
3013  checkIfOnlyChild(partialChild, *nodePtr);
3014  // The partial child now is
3015  // root of the pertinent subtree.
3016  *nodePtr = partialChild;
3017 
3018  return true;
3019 }
3020 
3021 template<class T, class X, class Y>
3023  /* Variables:
3024  * - \a partialChild is a pointer to the partial child of
3025  * \a nodePtr.
3026  * - \a checkNode is a pointer to the endmost empty child of
3027  * \a partialChild.
3028  * - \a emptyNode is a pointer to the empty node that is copied as
3029  * endmost child to \a partialChild.
3030  * - \a emptyChildCount stores the number of empty children of
3031  * \a nodePtr.
3032  *
3033  * If neccessary, the function templateP5() creates a new full P-node
3034  * and copies all full children of \p nodePtr to this new full P-node.
3035  * All empty children of \p nodePtr stay empty children of \p nodePtr.
3036  *
3037  * The new full P-node and \p nodePtr will be the new endmost children of
3038  * \a partialChild. The \a partialChild then occupies the position
3039  * of \p nodePtr in the PQ-tree.
3040  */
3041  if ((nodePtr->type() != PQNodeRoot::PQNodeType::PNode)
3042  || (nodePtr->partialChildren->size() != 1)) {
3043  return false;
3044  }
3045 
3046  /*
3047  Remove [[partialChild]] from the children of [[nodePtr]]. The node
3048  [[partialChild]] then occupies the position of [[nodePtr]] in the
3049  $PQ$-tree which is done in the function call [[exchangeNodes]]
3050  (\ref{exchangeNodes}). The chunk then removes all full children from
3051  [[nodePtr]] and adds them as children of a new $P$-node as endmost
3052  child of [[partialChild]]. This is done in the function call
3053  [[copyFullChildrenToPartial]] (\ref{copyFullChildrenToPartial}).
3054  When this chunk has finished, [[nodePtr]] has only empty children.
3055  */
3056  int emptyChildCount = nodePtr->m_childCount - nodePtr->fullChildren->size() - 1;
3057  PQNode<T, X, Y>* partialChild = nodePtr->partialChildren->popFrontRet();
3058  nodePtr->m_parent->partialChildren->pushFront(partialChild);
3059  removeChildFromSiblings(partialChild);
3060  exchangeNodes(nodePtr, partialChild);
3061  copyFullChildrenToPartial(nodePtr, partialChild);
3062 
3063  if (emptyChildCount > 0) {
3064  /*
3065  Check if [[nodePtr]] has just one empty child. If so, the child
3066  is stored in [[emptyNode]] in order to be added to the empty
3067  side of the partial $Q$-node [[partialChild]]. If [[nodePtr]]
3068  has more than one empty child, [[nodePtr]] is stored in
3069  [[emptyNode]] in order to be added to the empty
3070  side of the partial $Q$-node [[partialChild]].
3071  */
3072  PQNode<T, X, Y>* emptyNode;
3073  if (emptyChildCount == 1) {
3074  emptyNode = nodePtr->m_referenceChild;
3075  removeChildFromSiblings(emptyNode);
3076 
3077  } else {
3078  emptyNode = nodePtr;
3079  emptyNode->m_childCount = emptyChildCount;
3080  }
3081 
3082  /*
3083  Check at which side of [[partialChild]]
3084  the empty children hide. [[emptyNode]] stores the empty node
3085  that is added to the empty side of [[partialChild]].
3086  */
3087  PQNode<T, X, Y>* checkNode;
3088  if (clientLeftEndmost(partialChild)->status() == PQNodeRoot::PQNodeStatus::Empty) {
3089  checkNode = partialChild->m_leftEndmost;
3090  partialChild->m_leftEndmost = emptyNode;
3091  } else {
3092  // Endmostchild not found?
3093  OGDF_ASSERT(
3094  clientRightEndmost(partialChild)->status() == PQNodeRoot::PQNodeStatus::Empty);
3095 
3096  checkNode = partialChild->m_rightEndmost;
3097  partialChild->m_rightEndmost = emptyNode;
3098  }
3099 
3100  linkChildrenOfQnode(checkNode, emptyNode);
3101  emptyNode->m_parent = partialChild;
3103  partialChild->m_childCount++;
3104  }
3105  // If nodePtr did not have any empty
3106  // children it has to be deleted.
3107  if (emptyChildCount <= 1) {
3108  destroyNode(nodePtr);
3109  }
3110 
3111  return true;
3112 }
3113 
3114 template<class T, class X, class Y>
3116  /* Variables:
3117  * - \a partial_1 is a pointer to the first partial child of
3118  * \p nodePtr.
3119  * - \a partial_2 is a pointer to the second partial child of
3120  * \p nodePtr.
3121  * - \a fullEnd_1 is a pointer to a full endmost child of \a partial_1.
3122  * - \a fullEnd_2 is a pointer to a full endmost child of \a partial_2.
3123  * - \a emptyEnd_2 is a pointer to the empty endmost child (more
3124  * precisely: to the endmost child appearing on the empty side) of
3125  * \a partial_2. In case that <em>ignored nodes</em> are used, this
3126  * \a emptyEnd_2 may store the adress of an ignored node.
3127  * - \a realEmptyEnd_2 is a pointer to the first <em>non ignored</em>
3128  * node with empty status on the empty side of \a partial_2. In case
3129  * that no ignored nodes are used, \a realEmpty_2 is identical to
3130  * \a endEmpty_2.
3131  */
3132 #if 0
3133  PQNode<T,X,Y> *partial_1 = 0;
3134  PQNode<T,X,Y> *partial_2 = 0;
3135  PQNode<T,X,Y> *fullEnd_1 = 0;
3136  PQNode<T,X,Y> *fullEnd_2 = 0;
3137  PQNode<T,X,Y> *emptyEnd_2 = 0;
3138  PQNode<T,X,Y> *realEmptyEnd_2 = 0;
3139 #endif
3140 
3141  if ((*nodePtr)->type() != PQNodeRoot::PQNodeType::PNode
3142  || (*nodePtr)->partialChildren->size() != 2) {
3143  return false;
3144  }
3145 
3146  /*
3147  Get the partial children of [[nodePtr]] and removes the second
3148  partial child stored in [[partial_2]] from the children of
3149  [[nodePtr]]. If there are any full children of [[nodePtr]], the
3150  chunk removes them from the children of [[nodePtr]] and copies them
3151  as children to a new $P$-node. This new $P$-node is then made
3152  endmost child of [[partial_1]].
3153  */
3154  PQNode<T, X, Y>* partial_1 = (*nodePtr)->partialChildren->popFrontRet();
3155  PQNode<T, X, Y>* partial_2 = (*nodePtr)->partialChildren->popFrontRet();
3156 
3157  removeChildFromSiblings(partial_2);
3158  (*nodePtr)->m_childCount--;
3159  copyFullChildrenToPartial(*nodePtr, partial_1);
3160 
3161  /*
3162  Check the endmost children of the two partial children of [[nodePtr]]
3163  and stores them at approriate places, remembering what kind of type
3164  the endmost children are.
3165  */
3166  PQNode<T, X, Y>* fullEnd_1;
3167  if (clientLeftEndmost(partial_1)->status() == PQNodeRoot::PQNodeStatus::Full) {
3168  fullEnd_1 = partial_1->m_leftEndmost;
3169  } else {
3170  // partial child with no Full endmost child detected?
3171  OGDF_ASSERT(clientRightEndmost(partial_1)->status() == PQNodeRoot::PQNodeStatus::Full);
3172  fullEnd_1 = partial_1->m_rightEndmost;
3173  }
3174 
3175  PQNode<T, X, Y>* fullEnd_2 = nullptr;
3176  PQNode<T, X, Y>* emptyEnd_2 = nullptr;
3177  PQNode<T, X, Y>* realEmptyEnd_2 = nullptr;
3178  if (clientLeftEndmost(partial_2)->status() == PQNodeRoot::PQNodeStatus::Full) {
3179  fullEnd_2 = partial_2->m_leftEndmost;
3180  } else {
3181  // partial child with no Full or Empty endmost child detected?
3182  OGDF_ASSERT(clientLeftEndmost(partial_2)->status() == PQNodeRoot::PQNodeStatus::Empty);
3183 
3184  emptyEnd_2 = partial_2->m_leftEndmost;
3185  realEmptyEnd_2 = clientLeftEndmost(partial_2);
3186  }
3187 
3188  if (clientRightEndmost(partial_2)->status() == PQNodeRoot::PQNodeStatus::Full) {
3189  fullEnd_2 = partial_2->m_rightEndmost;
3190  } else {
3191  // partial child with no Full or Empty endmost child detected?
3192  OGDF_ASSERT(clientRightEndmost(partial_2)->status() == PQNodeRoot::PQNodeStatus::Empty);
3193 
3194  emptyEnd_2 = partial_2->m_rightEndmost;
3195  realEmptyEnd_2 = clientRightEndmost(partial_2);
3196  }
3197 
3198  OGDF_ASSERT(emptyEnd_2 != nullptr);
3199  OGDF_ASSERT(fullEnd_2 != emptyEnd_2);
3200  //partial child with same type of endmost child detected
3201 
3202  /*
3203  The children of [[partial_2]] are removed from their parent and
3204  added as children to [[partial_1]]. This is done by resetting the
3205  sibling pointers of the two endmost children of [[partial_1]] and
3206  [[partial_2]] and the endmost child pointers of [[partial_1]].
3207  Observe that the parent pointers are not updated. The node
3208  [[partial_2]] is deleted.
3209  */
3210  while (!partial_2->fullChildren->empty()) {
3211  partial_1->fullChildren->pushFront(partial_2->fullChildren->popFrontRet());
3212  }
3213  linkChildrenOfQnode(fullEnd_1, fullEnd_2);
3214  if (partial_1->m_leftEndmost == fullEnd_1) {
3215  partial_1->m_leftEndmost = emptyEnd_2;
3216  } else {
3217  partial_1->m_rightEndmost = emptyEnd_2;
3218  }
3219 
3220  emptyEnd_2->m_parent = partial_1;
3222 
3223  realEmptyEnd_2->m_parent = partial_1;
3224  realEmptyEnd_2->m_parentType = PQNodeRoot::PQNodeType::QNode;
3225 
3226  partial_1->m_childCount = partial_1->m_childCount + partial_2->m_childCount;
3227  destroyNode(partial_2);
3228 
3229  // If nodePtr does not have any
3230  // empty children, then it has to
3231  // be deleted and the partial node
3232  // is occupying its place in the tree.
3233  checkIfOnlyChild(partial_1, *nodePtr);
3234  // partial_1 is now root of the
3235  // pertinent subtree.
3236  *nodePtr = partial_1;
3237 
3238  return true;
3239 }
3240 
3241 template<class T, class X, class Y>
3242 bool PQTree<T, X, Y>::templateQ1(PQNode<T, X, Y>* nodePtr, bool isRoot) {
3243  if (nodePtr->type() == PQNodeRoot::PQNodeType::QNode && nodePtr != m_pseudoRoot
3244  && clientLeftEndmost(nodePtr)->status() == PQNodeRoot::PQNodeStatus::Full
3245  && clientRightEndmost(nodePtr)->status() == PQNodeRoot::PQNodeStatus::Full) {
3246  PQNode<T, X, Y>* seqStart = nullptr;
3247  PQNode<T, X, Y>* seqEnd = nullptr;
3248  if (checkChain(nodePtr, clientLeftEndmost(nodePtr), &seqStart, &seqEnd)) {
3250  if (!isRoot) {
3251  nodePtr->m_parent->fullChildren->pushFront(nodePtr);
3252  }
3253  return true;
3254  }
3255  }
3256 
3257  return false;
3258 }
3259 
3260 template<class T, class X, class Y>
3261 bool PQTree<T, X, Y>::templateQ2(PQNode<T, X, Y>* nodePtr, bool isRoot) {
3262  /* Variables:
3263  * - \a fullNode is a pointer to the full endmost child of \p nodePtr.
3264  * - \a sequenceBegin is a pointer to the first node of the
3265  * sequence of full children. Identical to the node fullNode and
3266  * mainly needed by the function checkChain().
3267  * - \a sequenceEnd is a pointer to the last node of the sequence
3268  * of full children. Is set by the function checkChain().
3269  * - \a partialChild is a pointer to the partial child of \p nodePtr.
3270  * - \a sequenceCons is 1 if all full children of
3271  * \p nodePtr form a consecutive sequence with one full child beeing
3272  * an endmost child of \p nodePtr \b and the partial child is
3273  * adjacent to the sequence.
3274  *
3275  * templateQ2() first checks if one of the above mentioned cases
3276  * occures and
3277  * then applies the necessary template matching.
3278  * No special action has to be performed for the full nodes. If there exists
3279  * a partial child that will be stored in \a partialChild, its children
3280  * are made children of \p nodePtr. So to say, \a partialChild is lifted
3281  * up to the Q-node \p nodePtr and the occurance of the children
3282  * of \a partialChild is fixed within the children of \p nodePtr.
3283  * (Remember that a partial child is also a Q-node).
3284  */
3285  if (nodePtr->type() != PQNodeRoot::PQNodeType::QNode || nodePtr->partialChildren->size() > 1) {
3286  return false;
3287  }
3288 
3289  bool sequenceCons = false;
3290  if (nodePtr->fullChildren->size() > 0) {
3291  /*
3292  Get a full endmost child of
3293  the $Q$-node [[nodePtr]] if there exists one.
3294  */
3295  PQNode<T, X, Y>* fullNode = nullptr;
3296  if (nodePtr->m_leftEndmost != nullptr) {
3297  fullNode = clientLeftEndmost(nodePtr);
3298  if (fullNode->status() != PQNodeRoot::PQNodeStatus::Full) {
3299  fullNode = nullptr;
3300  }
3301  }
3302  if (nodePtr->m_rightEndmost != nullptr && fullNode == nullptr) {
3303  fullNode = clientRightEndmost(nodePtr);
3304  if (fullNode->status() != PQNodeRoot::PQNodeStatus::Full) {
3305  fullNode = nullptr;
3306  }
3307  }
3308 
3309  /*
3310  In case that a full endmost child of [[nodePtr]] exists, this
3311  child has been stored in [[fullNode]] and the chunk checks by
3312  calling the function [[checkChain]] (\ref{checkChain}), if all
3313  full children of [[nodePtr]] form a consecutive sequence.
3314  In case that the full children
3315  of [[nodePtr]] form a consecutive sequence the
3316  return value of [[checkChain]] is [[1]]. If a partial child
3317  stored in [[partialChild]] exists, the chunk checks if
3318  [[partialChild]] is adjacent to the sequence of full children.
3319  If the latter case is [[1]], the flag [[sequenceCons]] is
3320  set to [[1]] and the function [[templateQ2]] is allowed to
3321  reduce the pertient children of [[nodePtr]].
3322  */
3323  PQNode<T, X, Y>* sequenceBegin = nullptr;
3324  PQNode<T, X, Y>* sequenceEnd = nullptr;
3325  if (fullNode != nullptr) {
3326  sequenceCons = checkChain(nodePtr, fullNode, &sequenceBegin, &sequenceEnd);
3327  }
3328 
3329  if (sequenceCons && nodePtr->partialChildren->size() == 1) {
3330  PQNode<T, X, Y>* partialChild = nodePtr->partialChildren->front();
3331  sequenceCons = false;
3332 
3333  if (clientSibLeft(sequenceEnd) == partialChild
3334  || clientSibRight(sequenceEnd) == partialChild) {
3335  sequenceCons = true;
3336  }
3337  }
3338  } else {
3339  if (!nodePtr->partialChildren->empty()) {
3340  /*
3341  If the $Q$-node [[nodePtr]] has no full children but one
3342  partial child this chunk checks, if the partial child is
3343  endmost child of the [[nodePtr]]. If this is not the case,
3344  [[nodePtr]] cannot be reduced by the template matching
3345  <b>Q2</b>.
3346  */
3347 #if 0
3348  nodePtr->partialChildren->startAtBottom();
3349  partialChild = nodePtr->partialChildren->readNext();
3350 #endif
3351  PQNode<T, X, Y>* partialChild = nodePtr->partialChildren->front();
3352  if ((clientLeftEndmost(nodePtr) == partialChild)
3353  || (clientRightEndmost(nodePtr) == partialChild)) {
3354  sequenceCons = true;
3355  }
3356  }
3357  }
3358 
3359  if (sequenceCons) {
3360  removeBlock(nodePtr, isRoot);
3361  }
3362 
3363  return sequenceCons;
3364 }
3365 
3366 template<class T, class X, class Y>
3368  /* Variables:
3369  * - \a fullChild is a pointer to an arbitrary full child of \p nodePtr.
3370  * - \a fullStart is a pointer to the first full child of a
3371  * consecutive sequence of full children.
3372  * - \a fullEnd is a pointer to the last full child of a
3373  * consecutive sequence of full children.
3374  * - \a partial_1 is a pointer to the first partial child of \p nodePtr.
3375  * - \a partial_2 is a pointer to the second partial child of \p nodePtr.
3376  * - \a conssequence is 1 if the pertinent children of
3377  * \p nodePtr form a consecutive sequence with at most one partial
3378  * child at every end of the sequence.
3379  * - \a found is a help variable.
3380  *
3381  * templateQ3() first checks if one of the above mentioned cases
3382  * occures and then applies the neccessary template matching.
3383  * No special action has to be performed for the full nodes. If there exist
3384  * one or two partial children which will be stored in \a partial_1
3385  * or \a partial_2, their children
3386  * are made children of \p nodePtr. So to say, \a partial_1 and
3387  * partial_2 are lifted up to the Q-node \p nodePtr
3388  * and the occurance of their children
3389  * is fixed within the children of \p nodePtr.
3390  */
3391  if (nodePtr->type() != PQNodeRoot::PQNodeType::QNode || nodePtr->partialChildren->size() >= 3) {
3392  return false;
3393  }
3394 
3395  bool conssequence = false;
3396  bool found = false;
3397 
3398  /*
3399  Check ifthe
3400  pertinent children of [[nodePtr]] form a consecutive sequence. We
3401  differ between two cases:
3402  \begin{enumerate}
3403  \item There exist full children of [[nodePtr]]. First check with
3404  the function [[checkChain]] (\ref{checkChain}) if the full children
3405  form a consecutive sequence. In case that the check was
3406  successful, check if each partial child is adjacent to a full child.
3407  If both checks were successful, the pertient children form a
3408  consecutive sequence.
3409  \item There do not exist full children. Check if the partial
3410  children (there are at most two of them) form a consecutive sequence.
3411  If the test was successful, the pertinent children form a
3412  consecutive sequence.
3413  */
3414  if (!nodePtr->fullChildren->empty()) {
3415  /*
3416  A consecutive
3417  sequence of full children has been detected, containing all full
3418  children of [[nodePtr]]. The chunk checks if each partial child
3419  of [[nodePtr]] is adjacent to a full child. Observe that the
3420  function [[templateQ3]] only reaches this chunk when [[nodePtr]]
3421  has less than three partial children.
3422  */
3423  PQNode<T, X, Y>* fullChild = nodePtr->fullChildren->front();
3424  PQNode<T, X, Y>* fullStart = nullptr;
3425  PQNode<T, X, Y>* fullEnd = nullptr;
3426  conssequence = checkChain(nodePtr, fullChild, &fullStart, &fullEnd);
3427  if (conssequence) {
3429  for (it = nodePtr->partialChildren->begin(); it.valid(); ++it) {
3430  PQNode<T, X, Y>* partial_1 = *it;
3431  found = false;
3432  if ((clientSibLeft(fullStart) == partial_1)
3433  || (clientSibRight(fullStart) == partial_1)
3434  || (clientSibLeft(fullEnd) == partial_1)
3435  || (clientSibRight(fullEnd) == partial_1)) {
3436  found = true;
3437  }
3438  if (!found) {
3439  conssequence = found;
3440  }
3441  }
3442  }
3443  }
3444 
3445  else if (nodePtr->partialChildren->size() == 2) {
3446  /*
3447  In case that the node [[nodePtr]] does not have any full children,
3448  this chunk checks if the partial children are adjacent.
3449  */
3450  PQNode<T, X, Y>* partial_1 = nodePtr->partialChildren->front();
3451  PQNode<T, X, Y>* partial_2 = nodePtr->partialChildren->back();
3452  if ((clientSibLeft(partial_1) == partial_2) || (clientSibRight(partial_1) == partial_2)) {
3453  found = true;
3454  }
3455  conssequence = found;
3456  }
3457 
3458  if (conssequence) {
3459  removeBlock(nodePtr, true);
3460  }
3461 
3462  return conssequence;
3463 }
3464 
3465 }
ogdf::ArrayBuffer
An array that keeps track of the number of inserted elements; also usable as an efficient stack.
Definition: Array.h:53
ogdf::PQTree::removeNodeFromTree
virtual int removeNodeFromTree(PQNode< T, X, Y > *parent, PQNode< T, X, Y > *child)
The objective is to remove a node child from the PQ-tree.
Definition: PQTree.h:2848
ogdf::PQInternalNode
The class template PQInternalNode is used to present P-nodes and Q-nodes in the PQ-Tree.
Definition: PQInternalNode.h:82
ogdf
The namespace for all OGDF objects.
Definition: multilevelmixer.cpp:39
ogdf::PQTree::addNodeToNewParent
virtual bool addNodeToNewParent(PQNode< T, X, Y > *parent, PQNode< T, X, Y > *child)
Adds a node child as a child to another node specified in parent.
Definition: PQTree.h:842
ArrayBuffer.h
Declaration and implementation of ArrayBuffer class.
ogdf::Queue::append
iterator append(const E &x)
Adds x at the end of queue.
Definition: Queue.h:324
ogdf::PQTree::writeGML
void writeGML(const char *fileName)
The function writeGML() prints the PQ-tree in the GML fileformat.
Definition: PQTree.h:1969
ogdf::PQTree::templateP4
virtual bool templateP4(PQNode< T, X, Y > **nodePtr)
Template matching for a P-node with full, empty and exactly one partial children.
Definition: PQTree.h:3001
ogdf::PQNode::m_identificationNumber
int m_identificationNumber
Each node that has been introduced once into the tree gets a unique number.
Definition: PQNode.h:433
ogdf::PQNodeRoot::PQNodeType::PNode
@ PNode
PQNode.h
Declaration and implementation of the class PQNode.
ogdf::PQNode::m_referenceChild
PQNode< T, X, Y > * m_referenceChild
Stores a pointer to one child, the reference child of the doubly linked cirkular list of children of ...
Definition: PQNode.h:462
ogdf::PQTree::partialChildren
List< PQNode< T, X, Y > * > * partialChildren(PQNode< T, X, Y > *nodePtr)
Definition: PQTree.h:660
ogdf::PQTree::destroyNode
virtual void destroyNode(PQNode< T, X, Y > *nodePtr)
Marks a node as PQNodeRoot::PQNodeStatus::ToBeDeleted.
Definition: PQTree.h:567
ogdf::PQTree::templateP1
virtual bool templateP1(PQNode< T, X, Y > *nodePtr, bool isRoot)
Template matching for P-nodes with only full children.
Definition: PQTree.h:2891
OGDF_ASSERT
#define OGDF_ASSERT(expr)
Assert condition expr. See doc/build.md for more information.
Definition: basic.h:66
ogdf::ArrayBuffer::empty
bool empty() const
Returns true if the buffer is empty, false otherwise.
Definition: ArrayBuffer.h:238
ogdf::PQTree::m_numberOfLeaves
int m_numberOfLeaves
Stores the number of leaves.
Definition: PQTree.h:195
ogdf::PQTree::fullChildren
List< PQNode< T, X, Y > * > * fullChildren(PQNode< T, X, Y > *nodePtr)
Definition: PQTree.h:658
ogdf::PQTree::sortExceptions
void sortExceptions(int Exceptions[], int arraySize)
Sorts the exceptions before frontExcept() scans the frontier.
Definition: PQTree.h:2864
ogdf::PQNode::fullChildren
List< PQNode< T, X, Y > * > * fullChildren
Stores all full children of a node during a reduction.
Definition: PQNode.h:498
ogdf::PQLeafKey
The class template PQLeafKey is a derived class of class template PQBasicKey.
Definition: PQInternalNode.h:40
ogdf::SListIteratorBase
Encapsulates a pointer to an ogdf::SList element.
Definition: SList.h:50
ogdf::PQTree::clientNextSib
virtual PQNode< T, X, Y > * clientNextSib(PQNode< T, X, Y > *nodePtr, PQNode< T, X, Y > *other) const
Definition: PQTree.h:672
ogdf::PQNode::m_referenceParent
PQNode< T, X, Y > * m_referenceParent
Is a pointer to the parent, in case that the parent is a P-node and the node itself is its reference ...
Definition: PQNode.h:470
ogdf::PQTree::templateQ2
virtual bool templateQ2(PQNode< T, X, Y > *nodePtr, bool isRoot)
Template matching for Q-nodes with a pertinent sequence of children on one side of the Q-node.
Definition: PQTree.h:3261
ogdf::ListIteratorBase::valid
bool valid() const
Returns true iff the iterator points to an element.
Definition: List.h:153
ogdf::Queue::top
const_reference top() const
Returns a reference to the front element.
Definition: Queue.h:249
ogdf::PQTree::clientDefinedEmptyNode
virtual void clientDefinedEmptyNode(PQNode< T, X, Y > *nodePtr)
If the user wishes to use different flags in a derived class of PQTree that are not available in this...
Definition: PQTree.h:124
Queue.h
Declaration and implementation of list-based queues (classes QueuePure<E> and Queue<E>).
ogdf::PQTree::templateL1
virtual bool templateL1(PQNode< T, X, Y > *nodePtr, bool isRoot)
Template matching for leaves.
Definition: PQTree.h:2878
ogdf::PQTree::templateP6
virtual bool templateP6(PQNode< T, X, Y > **nodePtr)
Template matching for a P-node with full, empty and exactly two partial children.
Definition: PQTree.h:3115
ogdf::PQNode::mark
virtual PQNodeMark mark() const =0
mark() returns the variable PQLeaf::m_mark in the derived class PQLeaf and PQInternalNode.
ogdf::PQNodeRoot::PQNodeMark::Unmarked
@ Unmarked
ogdf::PQTree::clientPrintType
virtual const char * clientPrintType(PQNode< T, X, Y > *nodePtr)
If the user wishes to use different types in a derived class of PQTree that are not available in this...
Definition: PQTree.h:1612
ogdf::PQTree::clientLeftEndmost
virtual PQNode< T, X, Y > * clientLeftEndmost(PQNode< T, X, Y > *nodePtr) const
Definition: PQTree.h:664
ogdf::ArrayBuffer::popRet
E popRet()
Removes the newest element from the buffer and returns it.
Definition: ArrayBuffer.h:232
PQNodeRoot.h
Declaration and implementation of the class PQNodeRoot.
ogdf::PQTree::templateP3
virtual bool templateP3(PQNode< T, X, Y > *nodePtr)
Template matching for a P-node with full and empty children that is not the root of the pertinent sub...
Definition: PQTree.h:2935
ogdf::PQTree::Cleanup
virtual void Cleanup()
Removes the entire PQ-tree.
Definition: PQTree.h:1474
ogdf::SListIteratorBase::valid
bool valid() const
Returns true iff the iterator points to an element.
Definition: SList.h:134
ogdf::PQTree::clientSibLeft
virtual PQNode< T, X, Y > * clientSibLeft(PQNode< T, X, Y > *nodePtr) const
Definition: PQTree.h:676
ogdf::PQTree::templateQ3
virtual bool templateQ3(PQNode< T, X, Y > *nodePtr)
Definition: PQTree.h:3367
ogdf::PQNode::m_rightEndmost
PQNode< T, X, Y > * m_rightEndmost
Stores the right endmost child of a Q-node.
Definition: PQNode.h:473
ogdf::PQNodeRoot::PQNodeStatus::Pertinent
@ Pertinent
ogdf::PQTree::emptyAllPertinentNodes
virtual void emptyAllPertinentNodes()
Cleans up all flags that have been set in the pertinent nodes during the reduction process.
Definition: PQTree.h:1744
ogdf::SListPure::begin
iterator begin()
Returns an iterator to the first element of the list.
Definition: SList.h:344
ogdf::PQTree::m_pseudoRoot
PQNode< T, X, Y > * m_pseudoRoot
a pointer to the virtual root of the pertinent subtree, in case that the pertinent root cannot be det...
Definition: PQTree.h:185
ogdf::PQNode::m_sibLeft
PQNode< T, X, Y > * m_sibLeft
Stores a pointer ot the left sibling of PQNode.
Definition: PQNode.h:482
ogdf::PQNodeRoot::PQNodeType::Leaf
@ Leaf
ogdf::PQTree::templateP2
virtual bool templateP2(PQNode< T, X, Y > **nodePtr)
Template matching for a P-node with full and empty children that is the root of the pertinent subtree...
Definition: PQTree.h:2906
ogdf::SListPure::empty
bool empty() const
Returns true iff the list is empty.
Definition: SList.h:238
ogdf::PQTree::~PQTree
virtual ~PQTree()
Destructor.
Definition: PQTree.h:66
ogdf::PQTree::clientPrintStatus
virtual const char * clientPrintStatus(PQNode< T, X, Y > *nodePtr)
If the user wishes to use different status in a derived class of PQTree that are not available in thi...
Definition: PQTree.h:1607
ogdf::PQNode::getKey
virtual PQLeafKey< T, X, Y > * getKey() const =0
getKey() returns a pointer to the PQLeafKeyof a node, in case that the node is supposed to have a key...
ogdf::PQTree::front
virtual void front(PQNode< T, X, Y > *nodePtr, SListPure< PQLeafKey< T, X, Y > * > &leafKeys)
Returns the keys stored in the leaves of the front of nodePtr.
Definition: PQTree.h:1880
ogdf::PQTree::copyFullChildrenToPartial
void copyFullChildrenToPartial(PQNode< T, X, Y > *nodePtr, PQNode< T, X, Y > *partialChild)
Copies all full children of nodePtr to a new P-node The node nodePtr has to be a P-node.
Definition: PQTree.h:1629
ogdf::PQNodeRoot::PQNodeType::QNode
@ QNode
ogdf::PQLeaf
The datastructure PQ-tree was designed to present a set of permutations on an arbitrary set of elemen...
Definition: PQLeaf.h:55
ogdf::PQNodeRoot::PQNodeStatus::Empty
@ Empty
ogdf::Queue::pop
E pop()
Removes front element and returns it.
Definition: Queue.h:336
SList.h
Declaration of singly linked lists and iterators.
ogdf::Array< int >
ogdf::PQNode::partialChildren
List< PQNode< T, X, Y > * > * partialChildren
Stores all partial children of a node during a reduction.
Definition: PQNode.h:501
ogdf::Queue::size
int size() const
Returns the number of elements in the queue.
Definition: Queue.h:246
ogdf::PQTree::clientRightEndmost
virtual PQNode< T, X, Y > * clientRightEndmost(PQNode< T, X, Y > *nodePtr) const
Definition: PQTree.h:668
ogdf::PQNodeRoot::PQNodeStatus::Partial
@ Partial
ogdf::PQNode::m_parentType
PQNodeType m_parentType
Stores the type of the parent which can be either a P- or Q-node.
Definition: PQNode.h:436
ogdf::PQNodeRoot::PQNodeMark::Unblocked
@ Unblocked
ogdf::PQTree::m_root
PQNode< T, X, Y > * m_root
a pointer to the root of the $PQ$-tree.
Definition: PQTree.h:179
ogdf::PQNode::status
virtual PQNodeStatus status() const =0
Returns the variable PQLeaf::m_status in the derived class PQLeaf and PQInternalNode.
ogdf::PQNodeRoot::PQNodeMark::Blocked
@ Blocked
ogdf::PQNode::getNextSib
PQNode< T, X, Y > * getNextSib(PQNode< T, X, Y > *other) const
The function getNextSib() returns one of the siblings of the node.
Definition: PQNode.h:187
ogdf::ArrayBuffer::push
void push(E e)
Puts a new element in the buffer.
Definition: ArrayBuffer.h:217
ogdf::SListPure
Singly linked lists.
Definition: SList.h:52
ogdf::PQTree::clientSibRight
virtual PQNode< T, X, Y > * clientSibRight(PQNode< T, X, Y > *nodePtr) const
Definition: PQTree.h:680
ogdf::PQTree::Initialize
virtual int Initialize(SListPure< PQLeafKey< T, X, Y > * > &leafKeys)
Initializes the PQ-tree with a set of elements.
Definition: PQTree.h:1916
ogdf::PQNode::changeSiblings
bool changeSiblings(PQNode< T, X, Y > *oldSib, PQNode< T, X, Y > *newSib)
The function changeSiblings() replaces the old sibling oldSib of the node by a new sibling newSib.
Definition: PQNode.h:539
config_autogen.h
ogdf::PQTree::CleanNode
virtual void CleanNode(PQNode< T, X, Y > *)
Definition: PQTree.h:103
ogdf::List
Doubly linked lists (maintaining the length of the list).
Definition: DfsMakeBiconnected.h:40
ogdf::PQNode::putSibling
SibDirection putSibling(PQNode< T, X, Y > *newSib)
The default function putSibling() stores a new sibling at a free sibling pointer of the node.
Definition: PQNode.h:252
ogdf::Queue
The parameterized class Queue<E> implements list-based queues.
Definition: Queue.h:205
PQLeafKey.h
Declaration and implementation of the class PQLeafKey.
ogdf::PQTree::m_identificationNumber
int m_identificationNumber
Stores the total number of nodes that have been allocated.
Definition: PQTree.h:192
ogdf::PQNode::type
virtual PQNodeType type() const =0
Returns the variable PQInternalNode::m_type in the derived class PQLeaf and PQInternalNode.
ogdf::PQNodeRoot::PQNodeStatus::Full
@ Full
ogdf::PQTree::exchangeNodes
virtual void exchangeNodes(PQNode< T, X, Y > *oldNode, PQNode< T, X, Y > *newNode)
Replaces the oldNode by the newNode in the tree.
Definition: PQTree.h:1789
ogdf::PQTree::templateQ1
virtual bool templateQ1(PQNode< T, X, Y > *nodePtr, bool isRoot)
Template matching for Q-nodes with only full children.
Definition: PQTree.h:3242
ogdf::PQTree::addNewLeavesToTree
bool addNewLeavesToTree(PQInternalNode< T, X, Y > *father, SListPure< PQLeafKey< T, X, Y > * > &leafKeys)
Adds a set of elements to the already existing set of elements of a PQ-tree.
Definition: PQTree.h:792
ogdf::Queue::empty
bool empty() const
Returns true iff the queue is empty.
Definition: Queue.h:243
ogdf::SListPure::popFrontRet
E popFrontRet()
Removes the first element from the list and returns it.
Definition: SList.h:544
ogdf::PQInternalNode::type
virtual PQNodeRoot::PQNodeType type() const
Returns the variable m_type in the derived class PQInternalNode.
Definition: PQInternalNode.h:208
ogdf::PQNodeRoot::SibDirection::Right
@ Right
ogdf::PQTree::m_pertinentRoot
PQNode< T, X, Y > * m_pertinentRoot
a pointer to the root of the pertinent subtree.
Definition: PQTree.h:182
ogdf::PQTree::emptyNode
void emptyNode(PQNode< T, X, Y > *nodePtr)
Cleans up all stacks, flags and pointers of a pertinent node that has been visited during the reducti...
Definition: PQTree.h:1779
ogdf::PQTree::templateP5
virtual bool templateP5(PQNode< T, X, Y > *nodePtr)
Template matching for a P-node with full, empty children and exactly one partial child.
Definition: PQTree.h:3022
ogdf::PQNode::m_pertChildCount
int m_pertChildCount
Stores the number of pertinent children of the node.
Definition: PQNode.h:439
ogdf::PQTree::checkIfOnlyChild
virtual bool checkIfOnlyChild(PQNode< T, X, Y > *child, PQNode< T, X, Y > *parent)
Checks if child is the only child of parent.
Definition: PQTree.h:1454
basic.h
Basic declarations, included by all source files.
ogdf::PQNode::m_pertLeafCount
int m_pertLeafCount
Stores the number of pertinent leaves in the frontier of the node.
Definition: PQNode.h:442
ogdf::PQNode::m_childCount
int m_childCount
Definition: PQNode.h:412
ogdf::PQNodeRoot::SibDirection::Left
@ Left
ogdf::PQNodeRoot::PQNodeMark::Queued
@ Queued
Array.h
Declaration and implementation of Array class and Array algorithms.
PQLeaf.h
Declaration and implementation of the class PQleaf.
ogdf::PQTree::root
PQNode< T, X, Y > * root() const
Returns a pointer of the root node of the PQTree.
Definition: PQTree.h:169
List.h
Declaration of doubly linked lists and iterators.
ogdf::PQTree::m_pertinentNodes
List< PQNode< T, X, Y > * > * m_pertinentNodes
Stores all nodes that have been marked PQNodeRoot::PQNodeStatus::Full or PQNodeRoot::PQNodeStatus::Pa...
Definition: PQTree.h:205
ogdf::PQTree::Reduction
virtual bool Reduction(SListPure< PQLeafKey< T, X, Y > * > &leafKeys)
Tests whether permissible permutations of the elements of U exist such that the elements of a subset ...
Definition: PQTree.h:2237
ogdf::PQNode::m_leftEndmost
PQNode< T, X, Y > * m_leftEndmost
Definition: PQNode.h:447
ogdf::PQTree::Reduce
virtual bool Reduce(SListPure< PQLeafKey< T, X, Y > * > &leafKeys)
Performs the reduction of the pertinent leaves with the help of the template matchings,...
Definition: PQTree.h:2151
ogdf::PQTree::removeBlock
void removeBlock(PQNode< T, X, Y > *nodePtr, bool isRoot)
Of every partial node that is found in the sequence of children of nodePtr, all children are removed ...
Definition: PQTree.h:2251
ogdf::SListPure::pushBack
iterator pushBack(const E &x)
Adds element x at the end of the list.
Definition: SList.h:481
ogdf::PQNode::endmostChild
bool endmostChild() const
The function endmostChild() checks if a node is endmost child of a Q-node.
Definition: PQNode.h:124
ogdf::PQTree::Bubble
virtual bool Bubble(SListPure< PQLeafKey< T, X, Y > * > &leafKeys)
Realizes a function described in [Booth].
Definition: PQTree.h:1045
PQInternalNode.h
Declaration and implementation of the class PQInternalNode.
ogdf::ListIteratorBase
Encapsulates a pointer to a list element.
Definition: List.h:51
ogdf::PQTree::linkChildrenOfQnode
virtual void linkChildrenOfQnode(PQNode< T, X, Y > *installed, PQNode< T, X, Y > *newChild)
Links the two endmost children of two different Q-nodes via their sibling pointers together.
Definition: PQTree.h:1945
ogdf::PQTree::checkChain
bool checkChain(PQNode< T, X, Y > *nodePtr, PQNode< T, X, Y > *firstFull, PQNode< T, X, Y > **seqStart, PQNode< T, X, Y > **seqEnd)
Checks whether all full children of a Q-node nodePtr form a consecutive sequence.
Definition: PQTree.h:1322
ogdf::PQTree::createNodeAndCopyFullChildren
PQNode< T, X, Y > * createNodeAndCopyFullChildren(List< PQNode< T, X, Y > * > *fullNodes)
Copies the full children of a P-node that are stored in the stack fullNodes to a new P-node.
Definition: PQTree.h:1664
ogdf::PQTree::removeChildFromSiblings
virtual void removeChildFromSiblings(PQNode< T, X, Y > *nodePtr)
Removes the node nodePtr from the doubly linked list of its parent.
Definition: PQTree.h:2789
ogdf::PQNode::m_sibRight
PQNode< T, X, Y > * m_sibRight
Stores a pointer ot the right sibling of PQNode.
Definition: PQNode.h:491
ogdf::PQNode::m_parent
PQNode< T, X, Y > * m_parent
Is a pointer to the parent.
Definition: PQNode.h:454
ogdf::PQTree::PQTree
PQTree()
Definition: PQTree.h:1617
ogdf::PQNode::changeEndmost
bool changeEndmost(PQNode< T, X, Y > *oldEnd, PQNode< T, X, Y > *newEnd)
The function changeEndmost() replaces the old endmost child oldEnd of the node by a new child newEnd.
Definition: PQNode.h:515
ogdf::PQNodeRoot::PQNodeStatus::ToBeDeleted
@ ToBeDeleted
ogdf::PQTree::clientPrintNodeCategorie
virtual int clientPrintNodeCategorie(PQNode< T, X, Y > *nodePtr)
If the user wishes to use different flags in a derived class of PQTree that are not available in this...
Definition: PQTree.h:1601
ogdf::PQNode
The class template PQBasicKey is an abstract base class.
Definition: PQBasicKey.h:111