Graphviz 13.0.0~dev.20250308.2027
Loading...
Searching...
No Matches
rawgraph.c
Go to the documentation of this file.
1/*************************************************************************
2 * Copyright (c) 2011 AT&T Intellectual Property
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * https://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors: Details at https://graphviz.org
9 *************************************************************************/
10
11#include <ortho/rawgraph.h>
12#include <stdbool.h>
13#include <stddef.h>
14#include <util/alloc.h>
15#include <util/list.h>
16
17#define UNSCANNED 0
18#define SCANNING 1
19#define SCANNED 2
20
21rawgraph *make_graph(size_t n) {
22 rawgraph* g = gv_alloc(sizeof(rawgraph));
23 g->nvs = n;
24 g->vertices = gv_calloc(n, sizeof(vertex));
25 for(size_t i = 0; i < n; ++i) {
26 g->vertices[i].color = UNSCANNED;
27 }
28 return g;
29}
30
31void
33{
34 for(size_t i = 0; i < g->nvs; ++i)
35 adj_list_free(&g->vertices[i].adj_list);
36 free (g->vertices);
37 free (g);
38}
39
40void insert_edge(rawgraph *g, size_t v1, size_t v2) {
41 if (!edge_exists(g, v1, v2)) {
42 adj_list_append(&g->vertices[v1].adj_list, v2);
43 }
44}
45
46void remove_redge(rawgraph *g, size_t v1, size_t v2) {
47 adj_list_remove(&g->vertices[v1].adj_list, v2);
48 adj_list_remove(&g->vertices[v2].adj_list, v1);
49}
50
51static bool zeq(size_t a, size_t b) {
52 return a == b;
53}
54
55bool edge_exists(rawgraph *g, size_t v1, size_t v2) {
56 return adj_list_contains(&g->vertices[v1].adj_list, v2, zeq);
57}
58
59DEFINE_LIST(int_stack, size_t)
60
61static int DFS_visit(rawgraph *g, size_t v, int time, int_stack_t *sp) {
62 vertex* vp;
63
64 vp = g->vertices + v;
65 vp->color = SCANNING;
66 const adj_list_t adj = vp->adj_list;
67 time = time + 1;
68
69 for (size_t i = 0; i < adj_list_size(&adj); ++i) {
70 const size_t id = adj_list_get(&adj, i);
71 if(g->vertices[id].color == UNSCANNED)
72 time = DFS_visit(g, id, time, sp);
73 }
74 vp->color = SCANNED;
75 int_stack_push_back(sp, v);
76 return time + 1;
77}
78
79void
81{
82 int time = 0;
83 int count = 0;
84
85 if (g->nvs == 0) return;
86 if (g->nvs == 1) {
87 g->vertices[0].topsort_order = count;
88 return;
89 }
90
91 int_stack_t sp = {0};
92 int_stack_reserve(&sp, g->nvs);
93 for(size_t i = 0; i < g->nvs; ++i) {
94 if(g->vertices[i].color == UNSCANNED)
95 time = DFS_visit(g, i, time, &sp);
96 }
97 while (!int_stack_is_empty(&sp)) {
98 const size_t v = int_stack_pop_back(&sp);
99 g->vertices[v].topsort_order = count;
100 count++;
101 }
102 int_stack_free(&sp);
103}
Memory allocation wrappers that exit on failure.
static void * gv_calloc(size_t nmemb, size_t size)
Definition alloc.h:26
static void * gv_alloc(size_t size)
Definition alloc.h:47
void free(void *)
#define DEFINE_LIST(name, type)
Definition list.h:22
rawgraph * make_graph(size_t n)
makes a graph with n vertices, 0 edges
Definition rawgraph.c:21
#define SCANNING
Definition rawgraph.c:18
static int DFS_visit(rawgraph *g, size_t v, int time, int_stack_t *sp)
Definition rawgraph.c:61
void insert_edge(rawgraph *g, size_t v1, size_t v2)
inserts edge FROM v1 to v2
Definition rawgraph.c:40
#define SCANNED
Definition rawgraph.c:19
void remove_redge(rawgraph *g, size_t v1, size_t v2)
removes any edge between v1 to v2 – irrespective of direction
Definition rawgraph.c:46
static bool zeq(size_t a, size_t b)
Definition rawgraph.c:51
void top_sort(rawgraph *g)
Definition rawgraph.c:80
bool edge_exists(rawgraph *g, size_t v1, size_t v2)
tests if there is an edge FROM v1 TO v2
Definition rawgraph.c:55
void free_graph(rawgraph *g)
Definition rawgraph.c:32
#define UNSCANNED
Definition rawgraph.c:17
size_t nvs
Definition rawgraph.h:26
vertex * vertices
Definition rawgraph.h:27
Definition legal.c:31
int topsort_order
Definition rawgraph.h:21
adj_list_t adj_list
adjacency list
Definition rawgraph.h:22
int color
Definition rawgraph.h:20