A
G
B C
D
E
IRL B NL DK S SF
F D CZ SK RO BG
A H GR
P E I SL HR MLT CYP
A.A. 2020/21 15 L'ADT grafo 8
Colorabilità: k=4 01map_coloring.c
F D CZ SK RO BG
A H GR
P E I SL HR MLT CYP
A.A. 2020/21 15 L'ADT grafo 9
L’ADT grafo
Ipotesi
Interfaccia
Lettura da file
Rappresentazione:
matrice delle adiacenze
lista delle adiacenze
(elenco di archi)
a = malloc(G->E * sizeof(Edge));
GRAPHedges(G, a);
grafi pesati
A.A. 2020/21 15 L'ADT grafo 24
Inserzione/Rimozione di archi
grafi pesati
dipende dalla rappresentazione
1 se (i, j) E
adj[i,j] =
0 se (i, j) E
grafi non orientati: adj simmetrica
0 1 DE 3 D
EB 4 E
A B EA
G->adj
2 C 0 1 2 3 4
0 0 1 0 0 0
E D 1 0 0 1 1 0
2 0 0 1 0 0
4 3
3 0 0 0 0 1
4 1 1 0 0 0
A.A. 2020/21 15 L'ADT grafo 28
Lista archi ST
AB3 0 A
Non orientato pesato BC5
1 B
BD4
AE5 2 C
0 1 CD7 3 D
3 BE6 4 E
A B 5 DE1
G->adj
6
5 4 2 C 0 1 2 3 4
0 0 3 0 0 5
1 7 0 4 6
E D 1 3 5
4 3 2 0 5 0 7 0
3 0 4 7 0 1
4 5 6 0 1 0
A.A. 2020/21 15 L'ADT grafo 29
Lista archi ST
AB3 A
0
Orientato pesato BC5
1 B
BD4
EA5 2 C
EB6 3 D
0 1 CC7
3 4 E
A B 5 DE1
G->adj
6
5 2 C 0 1 2 3 4
4
7 0 0 3 0 0 0
E
1 D 1 0 0 5 4 0
2 0 0 7 0 0
4 3
3 0 0 0 0 1
4 5 6 0 0 0
A.A. 2020/21 15 L'ADT grafo 30
numero
di vertici numero
di archi matrice di adiacenza
Graph.c
... tabella di simboli
struct graph {int V; int E; int **madj; ST tab;};
void GRAPHfree(Graph G) {
int i;
for (i=0; i<G->V; i++)
free(G->madj[i]);
free(G->madj);
STfree(G->tab);
free(G);
}
0 3
1
A.A. 2020/21 15 L'ADT grafo 33
1
1 2 4
3
Kneiphof
2 4
3
I ponti di Königsberg
(Eulero, 1736)
A.A. 2020/21 15 L'ADT grafo 34
Attenzione: si possono
generare cappi!
grafi pesati
grafi non orientati
static void insertE(Graph G, Edge e) {
int v = e.v, w = e.w, wt =e.wt;
if (G->madj[v][w] == 0)
G->E++; grafi non orientati pesati
G->madj[v][w] = 1; G->madj[v][w] = wt;
G->madj[w][v] = 1; G->madj[w][v] = wt;
}
int GRAPHgetIndex(Graph G, char *label) {
int id;
id = STsearch(G->tab, label);
if (id == -1) {
id = STcount(G->tab);
Attenzione: non si
STinsert(G->tab, label, id); possono generare
}
return id; multigrafi!
}
}
G->madj[w][v] = 0;
grafi non orientati
Complessità spaziale
S(n) = (|V|2)
vantaggiosa SOLO per grafi densi
No costi aggiuntivi per i pesi di un grafo
pesato
Accesso efficiente (O(1)) alla topologia del
grafo (adiacenza di 2 vertici).
}
return x;
grafi pesati
static Edge EDGEcreate(int v, int w, int wt) {
Edge e;
e.v = v; e.w = w; e.wt = wt;
return e;
}
A.A. 2020/21 15 L'ADT grafo 43
Graph GRAPHinit(int V) {
int v;
Graph G = malloc(sizeof *G);
G->V = V;
G->E = 0;
G->z = NEW(-1, -1, NULL);
G->ladj = malloc(G->V*sizeof(link));
for (v = 0; v < G->V; v++)
G->ladj[v] = G->z;
G->tab = STinit(V);
return G;
}
grafi pesati
Attenzione: non si
possono generare
multigrafi!
A.A. 2020/21 15 L'ADT grafo 46
static void removeE(Graph G, Edge e) {
int v = e.v, w = e.w;
link x;
if (G->ladj[v]->v == w) {
G->ladj[v] = G->ladj[v]->next;
G->E--;
}
else
for (x = G->ladj[v]; x != G->z; x = x->next)
if (x->next->v == w) {
x->next = x->next->next;
G->E--;
} grafi non orientati
if (G->ladj[w]->v == v)
G->ladj[w] = G->ladj[w]->next;
else
for (x = G->ladj[w]; x != G->z; x = x->next)
if (x->next->v == v) x->next = x->next->next;
}
A.A. 2020/21 15 L'ADT grafo 47
Vantaggi/svantaggi
visitati
cammino visualizzato in ordine inverso
A A
G G
B C B C
D D
E E
F F
visited = malloc(G->V*sizeof(int));
for (t=0; t<G->V; t++)
visited[t]=0;
Attenzione: per
sinteticità si viola
if (id1 < 0 || id2 < 0)
return; la sintassi del C
found = pathR/pathRH(G, id1, id2, G->V-1, visited);
if (found == 0)
printf("\n Path not found!\n");
}
Kneiphof 0 3
0 3
1
1 Multigrafo: archi
multipli che
connettono la
né cammini, né cicli di Eulero stessa coppia di
vertici
A C 4
G D 2
E 4
B C
F 2
G 2
Ciclo di Eulero:
D (A, B), (B, C), (C, A), (A, G), (G, E)
E
(E, D), (D, C), (C, E), (E, F), (F, A)