Aleph-w  1.9
General library for algorithms and data structures
graph_to_tree.H
1 
2 /* Aleph-w
3 
4  / \ | | ___ _ __ | |__ __ __
5  / _ \ | |/ _ \ '_ \| '_ \ ____\ \ /\ / / Data structures & Algorithms
6  / ___ \| | __/ |_) | | | |_____\ V V / version 1.9b
7  /_/ \_\_|\___| .__/|_| |_| \_/\_/ https://github.com/lrleon/Aleph-w
8  |_|
9 
10  This file is part of Aleph-w library
11 
12  Copyright (c) 2002-2018 Leandro Rabindranath Leon & Alejandro Mujica
13 
14  This program is free software: you can redistribute it and/or modify
15  it under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  This program is distributed in the hope that it will be useful, but
20  WITHOUT ANY WARRANTY; without even the implied warranty of
21  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22  General Public License for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with this program. If not, see <https://www.gnu.org/licenses/>.
26 */
27 # ifndef GRAPH_TO_TREE_H
28 # define GRAPH_TO_TREE_H
29 
30 # include <tpl_tree_node.H>
31 # include <tpl_graph.H>
32 # include <tpl_graph_utils.H>
33 
34 namespace Aleph {
35 
36  template <class GT, typename Key, class Convert> static
37 Tree_Node<Key> * graph_to_tree_node(GT & g, typename GT::Node * groot);
38  template <class GT, typename Key, class Convert> static void
39 __graph_to_tree_node(GT & g, typename GT::Node * groot,
40  Tree_Node<Key> * troot);
41 
42  template <class GT, typename Key, typename Convert, class SA> static inline
43 void __graph_to_tree_node(GT & g, typename GT::Node * groot,
44  Tree_Node<Key> * troot);
45 
115  template <class GT, typename Key,
116  class Convert, class SA = Dft_Show_Arc<GT>> inline
117 Tree_Node<Key> * graph_to_tree_node(GT & g, typename GT::Node * groot)
118 {
119  if (not is_graph_acyclique<GT>(g))
120  throw std::domain_error("Graph is not a tree (not acyclique)");
121 
122  Tree_Node<Key> * troot = new Tree_Node<Key>; // apartar memoria raíz
123 
124  Convert () (groot, troot); //convertir de groot y copiar a troot
125 
126  __graph_to_tree_node <GT, Key, Convert, SA> (g, groot, troot);
127 
128  return troot;
129 }
130 
193  template <class GT, typename Key,
194  class Convert,
195  class SA = Dft_Show_Arc<GT> >
197 {
198  SA sa;
199  Convert * convert = nullptr;
200 
201  void graph_to_tree(typename GT::Node * groot, Tree_Node<Key> * troot)
202  {
203  typedef typename GT::Node Node;
204  typedef typename GT::Arc Arc;
205 
206  // recorrer arcos de groot y construir recursivamente
207  for (Node_Arc_Iterator<GT, SA> it(groot, sa); it.has_curr(); it.next_ne())
208  {
209  Arc * arc = it.get_current_arc_ne();
210  if (IS_ARC_VISITED(arc, Convert_Tree))
211  continue;
212 
213  ARC_BITS(arc).set_bit(Convert_Tree, true); // arc visitado
214  Node * gtgt = it.get_tgt_node();
215  Tree_Node<Key> * ttgt = new Tree_Node<Key>;
216 
217  (*convert) (gtgt, ttgt); // asignarle la clave
218 
219  troot->insert_rightmost_child(ttgt); // insertarlo como hijo
220 
221  graph_to_tree(gtgt, ttgt);
222  }
223  }
224 
225  Tree_Node<Key> * graph_to_tree(GT & g,
226  typename GT::Node * groot,
227  Convert & conv)
228  {
229  if (not is_graph_acyclique<GT>(g))
230  throw std::domain_error("Graph is not a tree (not acyclique)");
231 
232  Tree_Node<Key> * troot = new Tree_Node<Key>; // apartar memoria raíz
233 
234  convert = &conv;
235 
236  (*convert) (groot, troot); //convertir de groot y copiar a troot
237 
238  graph_to_tree(groot, troot);
239 
240  return troot;
241  }
242 
243 public:
244 
245  Graph_To_Tree_Node(SA __sa = SA()) : sa(__sa) { /* empty */ }
246 
258  Tree_Node<Key> *
259  operator () (GT & g, typename GT::Node * groot, Convert && conv = Convert())
260  {
261  return graph_to_tree(g, groot, conv);
262  }
263 
264  Tree_Node<Key> *
265  operator () (GT & g, typename GT::Node * groot, Convert & conv)
266  {
267  return graph_to_tree(g, groot, conv);
268  }
269 };
270 
271 
272  template <class GT, typename Key, typename Convert, class SA> static inline
273 void __graph_to_tree_node(GT & g, typename GT::Node * groot,
274  Tree_Node<Key> * troot)
275 {
276  typedef typename GT::Node Node;
277  typedef typename GT::Arc Arc;
278 
279  // recorrer arcos de groot y construir recursivamente
280  for (Node_Arc_Iterator<GT, SA> it(groot); it.has_curr(); it.next_ne())
281  {
282  Arc * arc = it.get_current_arc_ne();
283  if (IS_ARC_VISITED(arc, Convert_Tree))
284  continue;
285 
286  ARC_BITS(arc).set_bit(Convert_Tree, true); // arc visitado
287  Node * gtgt = it.get_tgt_node();
288  Tree_Node<Key> * ttgt = new Tree_Node<Key>;
289 
290  Convert () (gtgt, ttgt); // asignarle la clave
291 
292  troot->insert_rightmost_child(ttgt); // insertarlo como hijo
293 
294  __graph_to_tree_node <GT, Key, Convert, SA> (g, gtgt, ttgt);
295  }
296 }
297 
298 } // end namespace Aleph
299 
300 # endif // GRAPH_TO_TREE_H
Tree_Node< Key > * graph_to_tree_node(GT &g, typename GT::Node *groot)
Definition: graph_to_tree.H:117
void insert_rightmost_child(Tree_Node *p) noexcept
Definition: tpl_tree_node.H:373
Tree_Node< Key > * operator()(GT &g, typename GT::Node *groot, Convert &&conv=Convert())
Definition: graph_to_tree.H:259
Definition: tpl_tree_node.H:67
Definition: graph_to_tree.H:196
#define IS_ARC_VISITED(p, bit)
Definition: aleph-graph.H:360
Definition: ah-comb.H:35
Definition: tpl_graph.H:1063
#define ARC_BITS(p)
Definition: aleph-graph.H:351
Definition: tpl_graph.H:1177

Leandro Rabindranath León