6 * $Date: 2012-07-15 22:39:24 +0200 (So, 15. Jul 2012) $
7 ***************************************************************/
10 * \brief Implementation of the class PlanarPQTree.
12 * Implements a PQTree with added features for the planarity test.
13 * Used by BoothLueker.
15 * \author Sebastian Leipert
18 * This file is part of the Open Graph Drawing Framework (OGDF).
22 * See README.txt in the root directory of the OGDF installation for details.
25 * This program is free software; you can redistribute it and/or
26 * modify it under the terms of the GNU General Public License
27 * Version 2 or 3 as published by the Free Software Foundation;
28 * see the file LICENSE.txt included in the packaging of this file
32 * This program is distributed in the hope that it will be useful,
33 * but WITHOUT ANY WARRANTY; without even the implied warranty of
34 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
35 * GNU General Public License for more details.
38 * You should have received a copy of the GNU General Public
39 * License along with this program; if not, write to the Free
40 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
41 * Boston, MA 02110-1301, USA.
43 * \see http://www.gnu.org/copyleft/gpl.html
44 ***************************************************************/
47 #include <ogdf/internal/planarity/PlanarPQTree.h>
51 // Overriding the function doDestruction (see basic.h)
52 // Allows deallocation of lists of PlanarLeafKey<IndInfo*>
53 // and PQLeafKey<edge,IndInfo*,bool> in constant time using OGDF
56 typedef PlanarLeafKey
<IndInfo
*> *PtrPlanarLeafKeyI
;
59 inline bool doDestruction
<PtrPlanarLeafKeyI
>(const PtrPlanarLeafKeyI
*) { return false; }
62 typedef PQLeafKey
<edge
,IndInfo
*,bool> *PtrPQLeafKeyEIB
;
65 inline bool doDestruction
<PtrPQLeafKeyEIB
>(const PtrPQLeafKeyEIB
*) { return false; }
69 // Replaces the pertinent subtree by a P-node with leaves as children
70 // corresponding to the incoming edges of the node v. These edges
71 // are to be specified by their keys stored in leafKeys.
72 void PlanarPQTree::ReplaceRoot(SListPure
<PlanarLeafKey
<IndInfo
*>*> &leafKeys
)
74 if (m_pertinentRoot
->status() == PQNodeRoot::FULL
)
75 ReplaceFullRoot(leafKeys
);
77 ReplacePartialRoot(leafKeys
);
82 // The function [[emptyAllPertinentNodes]] has to be called after a reduction
83 // has been processed. This overloaded function first destroys all full nodes
84 // by marking them as TO_BE_DELETED and then calling the base class function
85 // [[emptyAllPertinentNodes]].
86 void PlanarPQTree::emptyAllPertinentNodes()
88 ListIterator
<PQNode
<edge
,IndInfo
*,bool>*> it
;
89 for (it
= m_pertinentNodes
->begin(); it
.valid(); it
++)
91 PQNode
<edge
,IndInfo
*,bool>* nodePtr
= (*it
);
92 if (nodePtr
->status() == PQNodeRoot::FULL
)
96 m_pertinentRoot
->status(PQNodeRoot::FULL
);
98 PQTree
<edge
,IndInfo
*,bool>::emptyAllPertinentNodes();
102 // Initializes a PQTree by a set of leaves that will korrespond to
103 // the set of Keys stored in leafKeys.
104 int PlanarPQTree::Initialize(SListPure
<PlanarLeafKey
<IndInfo
*>*> &leafKeys
)
106 SListIterator
<PlanarLeafKey
<IndInfo
*>* > it
;
107 SListPure
<PQLeafKey
<edge
,IndInfo
*,bool>*> castLeafKeys
;
108 for (it
= leafKeys
.begin(); it
.valid(); ++it
)
109 castLeafKeys
.pushBack((PQLeafKey
<edge
,IndInfo
*,bool>*) *it
);
111 return PQTree
<edge
,IndInfo
*,bool>::Initialize(castLeafKeys
);
115 // Reduction reduced a set of leaves determined by their keys stored
116 // in leafKeys. Integer redNumber is for debugging only.
117 bool PlanarPQTree::Reduction(SListPure
<PlanarLeafKey
<IndInfo
*>*> &leafKeys
)
119 SListIterator
<PlanarLeafKey
<IndInfo
*>* > it
;
120 SListPure
<PQLeafKey
<edge
,IndInfo
*,bool>*> castLeafKeys
;
121 for (it
= leafKeys
.begin(); it
.valid(); ++it
)
122 castLeafKeys
.pushBack((PQLeafKey
<edge
,IndInfo
*,bool>*) *it
);
124 return PQTree
<edge
,IndInfo
*,bool>::Reduction(castLeafKeys
);
128 // Function ReplaceFullRoot either replaces the full root
129 // or one full child of a partial root of a pertinent subtree
130 // by a single P-node with leaves corresponding the keys stored in leafKeys.
131 void PlanarPQTree::ReplaceFullRoot(SListPure
<PlanarLeafKey
<IndInfo
*>*> &leafKeys
)
133 if (!leafKeys
.empty() && leafKeys
.front() == leafKeys
.back())
135 //ReplaceFullRoot: replace pertinent root by a single leaf
136 PQLeaf
<edge
,IndInfo
*,bool> *leafPtr
=
137 OGDF_NEW PQLeaf
<edge
,IndInfo
*,bool>(m_identificationNumber
++,
138 PQNodeRoot::EMPTY
,(PQLeafKey
<edge
,IndInfo
*,bool>*)leafKeys
.front());
140 exchangeNodes(m_pertinentRoot
,(PQNode
<edge
,IndInfo
*,bool>*) leafPtr
);
141 if (m_pertinentRoot
== m_root
)
142 m_root
= (PQNode
<edge
,IndInfo
*,bool>*) leafPtr
;
143 m_pertinentRoot
= 0; // check for this emptyAllPertinentNodes
146 else if (!leafKeys
.empty()) // at least two leaves
148 PQInternalNode
<edge
,IndInfo
*,bool> *nodePtr
= 0; // dummy
149 //replace pertinent root by a $P$-node
150 if ((m_pertinentRoot
->type() == PQNodeRoot::PNode
) ||
151 (m_pertinentRoot
->type() == PQNodeRoot::QNode
))
153 nodePtr
= (PQInternalNode
<edge
,IndInfo
*,bool>*)m_pertinentRoot
;
154 nodePtr
->type(PQNodeRoot::PNode
);
155 nodePtr
->childCount(0);
156 while (!fullChildren(m_pertinentRoot
)->empty())
157 removeChildFromSiblings(fullChildren(m_pertinentRoot
)->popFrontRet());
159 else if (m_pertinentRoot
->type() == PQNodeRoot::leaf
)
161 nodePtr
= OGDF_NEW PQInternalNode
<edge
,IndInfo
*,bool>(m_identificationNumber
++,
162 PQNodeRoot::PNode
,PQNodeRoot::EMPTY
);
163 exchangeNodes(m_pertinentRoot
,nodePtr
);
164 m_pertinentRoot
= 0; // check for this emptyAllPertinentNodes
167 SListPure
<PQLeafKey
<edge
,IndInfo
*,bool>*> castLeafKeys
;
168 SListIterator
<PlanarLeafKey
<IndInfo
*>* > it
;
169 for (it
= leafKeys
.begin(); it
.valid(); ++it
)
170 castLeafKeys
.pushBack((PQLeafKey
<edge
,IndInfo
*,bool>*) *it
);
171 addNewLeavesToTree(nodePtr
,castLeafKeys
);
176 // Function ReplacePartialRoot replaces all full nodes by a single P-node
177 // with leaves corresponding the keys stored in leafKeys.
178 void PlanarPQTree::ReplacePartialRoot(SListPure
<PlanarLeafKey
<IndInfo
*>*> &leafKeys
)
180 m_pertinentRoot
->childCount(m_pertinentRoot
->childCount() + 1 -
181 fullChildren(m_pertinentRoot
)->size());
183 while (fullChildren(m_pertinentRoot
)->size() > 1)
184 removeChildFromSiblings(fullChildren(m_pertinentRoot
)->popFrontRet());
186 PQNode
<edge
,IndInfo
*,bool> *currentNode
= fullChildren(m_pertinentRoot
)->popFrontRet();
188 currentNode
->parent(m_pertinentRoot
);
189 m_pertinentRoot
= currentNode
;
190 ReplaceFullRoot(leafKeys
);