add bfs traversal.
F_set "aset" FUNCTION I|A(1,O)|A(2,S)|A(3,S)
C_flat "TV_flat" CONSTANT T_tvtyp
C_dfs "TV_dfs" CONSTANT T_tvtyp
+C_bfs "TV_bfs" CONSTANT T_tvtyp
C_fwd "TV_fwd" CONSTANT T_tvtyp
C_rev "TV_rev" CONSTANT T_tvtyp
C_ne "TV_ne" CONSTANT T_tvtyp
#include <ast.h>
#include <vmalloc.h>
- typedef enum { TV_flat, TV_dfs, TV_fwd, TV_rev, TV_ne,
+ typedef enum { TV_flat, TV_bfs, TV_dfs, TV_fwd, TV_rev, TV_ne,
TV_en } trav_type;
typedef struct {
\fB$tvtype\fP : \fBtvtype_t\fP
indicates how \fBgvpr\fP traverses a graph. At present, it can only take
one of six values: \fBTV_flat\fP, \fBTV_dfs\fP, \fBTV_fwd\fP,
-\fBTV_ref\fP, \fBTV_ne\fP, and \fBTV_en\fP. \fBTV_flat\fP is the default.
+\fBTV_ref\fP, \fBTV_bfs\fP, \fBTV_ne\fP, and \fBTV_en\fP.
+\fBTV_flat\fP is the default.
The meaning of these values is discussed below.
.TP
\fBARGC\fP : \fBint\fP
\fBTV_fwd\fR : \fItvtype_t\fR
a traversal of the graph using a depth-first search on the
graph following only forward arcs. In
+.TP
+\fBTV_bfs\fR : \fItvtype_t\fR
+a traversal of the graph using a bread-first search on the
+graph ignoring edge directions. See the item on \fBTV_dfs\fR above
+for the role of \fB$tvroot\fP.
.IR libagraph (3),
edges in undirected graphs are given an arbitrary direction, which is
used for this traversal. The choice of roots for the traversal is the
static trav_fns FWDfns = { agfstout, (nxttedgefn_t) agnxtout };
static trav_fns REVfns = { agfstin, (nxttedgefn_t) agnxtin };
+static void travBFS(Gpr_t * state, comp_prog * xprog)
+{
+ nodestream nodes;
+ queue *q;
+ ndata *nd;
+ Agnode_t *n;
+ Agedge_t *cure;
+
+ q = mkQueue();
+ nodes.oldroot = 0;
+ nodes.prev = 0;
+ while ((n = nextNode(state, &nodes))) {
+ nd = nData(n);
+ if (MARKED(nd))
+ continue;
+ PUSH(nd);
+ push (q,n);
+ while ((n = pull(q))) {
+ nd = nData(n);
+ MARK(nd);
+ POP(nd);
+ evalNode(state, xprog, n);
+ for (cure = agfstedge(n); cure; cure = agnxtedge(cure, n)) {
+ nd = nData(cure->node);
+ if (MARKED(nd)) continue;
+ evalEdge(state, xprog, cure);
+ if (!ONSTACK(nd)) {
+ push(q, cure->node);
+ PUSH(nd);
+ }
+ }
+ }
+ }
+ freeQ (q);
+}
+
static void travDFS(Gpr_t * state, comp_prog * xprog, trav_fns * fns)
{
Agnode_t *n;
queue *stk;
- Agedgepair_t seed;
Agnode_t *curn;
Agedge_t *cure;
Agedge_t *entry;
int more;
ndata *nd;
nodestream nodes;
+ Agedgepair_t seed;
stk = mkStack();
nodes.oldroot = 0;
}
}
}
+ freeQ (stk);
}
static void travNodes(Gpr_t * state, comp_prog * xprog)
case TV_flat:
travFlat(state, xprog);
break;
+ case TV_bfs:
+ travBFS(state, xprog);
+ break;
case TV_dfs:
travDFS(state, xprog, &DFSfns);
break;