|
Graphviz
2.29.20120523.0446
|
00001 /* $Id$ $Revision$ */ 00002 /* vim:set shiftwidth=4 ts=8: */ 00003 00004 /************************************************************************* 00005 * Copyright (c) 2011 AT&T Intellectual Property 00006 * All rights reserved. This program and the accompanying materials 00007 * are made available under the terms of the Eclipse Public License v1.0 00008 * which accompanies this distribution, and is available at 00009 * http://www.eclipse.org/legal/epl-v10.html 00010 * 00011 * Contributors: See CVS logs. Details at http://www.graphviz.org/ 00012 *************************************************************************/ 00013 00014 00015 /* 00016 * Decompose finds the connected components of a graph. 00017 * It searches the temporary edges and ignores non-root nodes. 00018 * The roots of the search are the real nodes of the graph, 00019 * but any virtual nodes discovered are also included in the 00020 * component. 00021 */ 00022 00023 #include "dot.h" 00024 00025 00026 static graph_t *G; 00027 static node_t *Last_node; 00028 static char Cmark; 00029 00030 static void 00031 begin_component(void) 00032 { 00033 Last_node = GD_nlist(G) = NULL; 00034 } 00035 00036 static void 00037 add_to_component(node_t * n) 00038 { 00039 GD_n_nodes(G)++; 00040 ND_mark(n) = Cmark; 00041 if (Last_node) { 00042 ND_prev(n) = Last_node; 00043 ND_next(Last_node) = n; 00044 } else { 00045 ND_prev(n) = NULL; 00046 GD_nlist(G) = n; 00047 } 00048 Last_node = n; 00049 ND_next(n) = NULL; 00050 } 00051 00052 static void 00053 end_component(void) 00054 { 00055 int i; 00056 00057 i = GD_comp(G).size++; 00058 GD_comp(G).list = ALLOC(GD_comp(G).size, GD_comp(G).list, node_t *); 00059 GD_comp(G).list[i] = GD_nlist(G); 00060 } 00061 00062 static void 00063 search_component(graph_t * g, node_t * n) 00064 { 00065 int c, i; 00066 elist vec[4]; 00067 node_t *other; 00068 edge_t *e; 00069 00070 add_to_component(n); 00071 vec[0] = ND_out(n); 00072 vec[1] = ND_in(n); 00073 vec[2] = ND_flat_out(n); 00074 vec[3] = ND_flat_in(n); 00075 00076 for (c = 0; c <= 3; c++) { 00077 if (vec[c].list) 00078 for (i = 0; (e = vec[c].list[i]); i++) { 00079 if ((other = aghead(e)) == n) 00080 other = agtail(e); 00081 if ((ND_mark(other) != Cmark) && (other == UF_find(other))) 00082 search_component(g, other); 00083 } 00084 } 00085 } 00086 00087 void decompose(graph_t * g, int pass) 00088 { 00089 graph_t *subg; 00090 node_t *n, *v; 00091 00092 G = g; 00093 if (++Cmark == 0) 00094 Cmark = 1; 00095 GD_n_nodes(g) = GD_comp(g).size = 0; 00096 for (n = agfstnode(g); n; n = agnxtnode(g, n)) { 00097 v = n; 00098 if ((pass > 0) && (subg = ND_clust(v))) 00099 v = GD_rankleader(subg)[ND_rank(v)]; 00100 else if (v != UF_find(v)) 00101 continue; 00102 if (ND_mark(v) != Cmark) { 00103 begin_component(); 00104 search_component(g, v); 00105 end_component(); 00106 } 00107 } 00108 }
1.7.5