void CconnectClusterPlanar::constructWheelGraph(ClusterGraph &C, Graph &G, cluster &parent, PlanarPQTree* T, EdgeArray<node> &outgoingTable) { const PQNode<edge,IndInfo*,bool>* root = T->root(); const PQNode<edge,IndInfo*,bool>* checkNode = nullptr; Queue<const PQNode<edge,IndInfo*,bool>*> treeNodes; treeNodes.append(root); node correspond = G.newNode(); // Corresponds to the root node. // root node is either a leaf or a P-node C.reassignNode(correspond,parent); Queue<node> graphNodes; graphNodes.append(correspond); node hub; node next = nullptr; node pre; node newNode; // corresponds to anchor of a hub or a cut node while (!treeNodes.empty()) { checkNode = treeNodes.pop(); correspond = graphNodes.pop(); PQNode<edge,IndInfo*,bool>* firstSon = nullptr; PQNode<edge,IndInfo*,bool>* nextSon = nullptr; PQNode<edge,IndInfo*,bool>* oldSib = nullptr; PQNode<edge,IndInfo*,bool>* holdSib = nullptr; if (checkNode->type() == PQNodeRoot::PNode) { // correspond is a cut node OGDF_ASSERT(checkNode->referenceChild()) firstSon = checkNode->referenceChild(); if (firstSon->type() != PQNodeRoot::leaf) { treeNodes.append(firstSon); newNode = G.newNode(); C.reassignNode(newNode,parent); graphNodes.append(newNode); G.newEdge(correspond,newNode); } else { // insert Edge to the outside PQLeaf<edge,IndInfo*,bool>* leaf = (PQLeaf<edge,IndInfo*,bool>*) firstSon; edge f = leaf->getKey()->m_userStructKey; //node x = outgoingTable[f]; G.newEdge(correspond,outgoingTable[f]); delete leaf->getKey(); } nextSon = firstSon->getNextSib(oldSib); oldSib = firstSon; pre = next; while (nextSon && nextSon != firstSon) { if (nextSon->type() != PQNodeRoot::leaf) { treeNodes.append(nextSon); newNode = G.newNode(); // new node corresponding to anchor // or cutnode C.reassignNode(newNode,parent); graphNodes.append(newNode); G.newEdge(correspond,newNode); } else { // insert Edge to the outside PQLeaf<edge,IndInfo*,bool>* leaf = (PQLeaf<edge,IndInfo*,bool>*) nextSon; edge f = leaf->getKey()->m_userStructKey; //node x = outgoingTable[f]; G.newEdge(correspond,outgoingTable[f]); delete leaf->getKey(); } holdSib = nextSon->getNextSib(oldSib); oldSib = nextSon; nextSon = holdSib; } } else if (checkNode->type() == PQNodeRoot::QNode) { // correspond is the anchor of a hub OGDF_ASSERT(checkNode->getEndmost(PQNodeRoot::LEFT)) firstSon = checkNode->getEndmost(PQNodeRoot::LEFT); hub = G.newNode(); C.reassignNode(hub,parent); G.newEdge(hub,correspond); // link anchor and hub next = G.newNode(); // for first son C.reassignNode(next,parent); G.newEdge(hub,next); G.newEdge(correspond,next); if (firstSon->type() != PQNodeRoot::leaf) { treeNodes.append(firstSon); newNode = G.newNode(); C.reassignNode(newNode,parent); graphNodes.append(newNode); G.newEdge(next,newNode); } else { // insert Edge to the outside PQLeaf<edge,IndInfo*,bool>* leaf = (PQLeaf<edge,IndInfo*,bool>*) firstSon; edge f = leaf->getKey()->m_userStructKey; //node x = outgoingTable[f]; G.newEdge(next,outgoingTable[f]); delete leaf->getKey(); } nextSon = firstSon->getNextSib(oldSib); oldSib = firstSon; pre = next; while (nextSon) { next = G.newNode(); C.reassignNode(next,parent); G.newEdge(hub,next); G.newEdge(pre,next); if (nextSon->type() != PQNodeRoot::leaf) { treeNodes.append(nextSon); newNode = G.newNode(); // new node corresponding to anchor // or cutnode C.reassignNode(newNode,parent); graphNodes.append(newNode); G.newEdge(next,newNode); } else { // insert Edge to the outside PQLeaf<edge,IndInfo*,bool>* leaf = (PQLeaf<edge,IndInfo*,bool>*) nextSon; edge f = leaf->getKey()->m_userStructKey; G.newEdge(next,outgoingTable[f]); delete leaf->getKey(); } holdSib = nextSon->getNextSib(oldSib); oldSib = nextSon; nextSon = holdSib; pre = next; } G.newEdge(next,correspond); } } OGDF_ASSERT(C.consistencyCheck()); }
// The function front scans the frontier of nodePtr. It returns the keys // of the leaves found in the frontier of nodePtr in a SListPure. // These keys include keys of direction indicators detected in the frontier. // // CAREFUL: Funktion marks all full nodes for destruction. // Only to be used in connection with replaceRoot. // void EmbedPQTree::front( PQNode<edge,IndInfo*,bool>* nodePtr, SListPure<PQBasicKey<edge,IndInfo*,bool>*> &keys) { ArrayBuffer<PQNode<edge,IndInfo*,bool>*> S; S.push(nodePtr); while (!S.empty()) { PQNode<edge,IndInfo*,bool> *checkNode = S.popRet(); if (checkNode->type() == PQNodeRoot::PQNodeType::Leaf) keys.pushBack((PQBasicKey<edge,IndInfo*,bool>*) checkNode->getKey()); else { PQNode<edge,IndInfo*,bool>* firstSon = nullptr; if (checkNode->type() == PQNodeRoot::PQNodeType::PNode) { firstSon = checkNode->referenceChild(); } else if (checkNode->type() == PQNodeRoot::PQNodeType::QNode) { firstSon = checkNode->getEndmost(PQNodeRoot::SibDirection::Right); // By this, we make sure that we start on the left side // since the left endmost child will be on top of the stack } OGDF_ASSERT(firstSon != nullptr); if (firstSon->status() == PQNodeRoot::PQNodeStatus::Indicator) { keys.pushBack((PQBasicKey<edge,IndInfo*,bool>*) firstSon->getNodeInfo()); m_pertinentNodes->pushBack(firstSon); destroyNode(firstSon); } else S.push(firstSon); PQNode<edge,IndInfo*,bool> *nextSon = firstSon->getNextSib(nullptr); PQNode<edge,IndInfo*,bool> *oldSib = firstSon; while (nextSon && nextSon != firstSon) { if (nextSon->status() == PQNodeRoot::PQNodeStatus::Indicator) { // Direction indicators point with their left sibling pointer // in the direction of their sequence. If an indicator is scanned // from the opposite direction, coming from its right sibling // the corresponding sequence must be reversed. if (oldSib == nextSon->getSib(PQNodeRoot::SibDirection::Left)) //Direction changed nextSon->getNodeInfo()->userStructInfo()->changeDir = true; keys.pushBack((PQBasicKey<edge,IndInfo*,bool>*) nextSon->getNodeInfo()); m_pertinentNodes->pushBack(nextSon); } else S.push(nextSon); PQNode<edge,IndInfo*,bool> *holdSib = nextSon->getNextSib(oldSib); oldSib = nextSon; nextSon = holdSib; } } } }