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