feat: Initial commit
This commit is contained in:
316
Laboratorio 8/Esercizio 2/Graph.c
Normal file
316
Laboratorio 8/Esercizio 2/Graph.c
Normal file
@@ -0,0 +1,316 @@
|
||||
// Laboratorio 8 - Esercizio 2 - Graph.c
|
||||
// Matteo Schiff - s295565
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "Graph.h"
|
||||
#include "ST.h"
|
||||
|
||||
typedef struct node *link;
|
||||
struct node
|
||||
{
|
||||
int id;
|
||||
int wt;
|
||||
link next;
|
||||
};
|
||||
|
||||
struct graph
|
||||
{
|
||||
int V;
|
||||
int E;
|
||||
int **madj;
|
||||
link *ladj;
|
||||
link z;
|
||||
ST tab;
|
||||
};
|
||||
|
||||
static link newNode(int id, int wt, link next)
|
||||
{
|
||||
link t = (link)malloc(sizeof(*t));
|
||||
t->id = id;
|
||||
t->wt = wt;
|
||||
t->next = next;
|
||||
return t;
|
||||
}
|
||||
|
||||
static void freeList(link t, link z)
|
||||
{
|
||||
link q, x = t;
|
||||
if (t == z)
|
||||
return;
|
||||
|
||||
while (x != z)
|
||||
{
|
||||
q = x->next;
|
||||
free(x);
|
||||
x = q;
|
||||
}
|
||||
}
|
||||
|
||||
static int searchList(link t, link z, int id)
|
||||
{
|
||||
for (link x = t; x != z; x = x->next)
|
||||
{
|
||||
if (x->id == id)
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static Edge EDGEcreate(int v, int w, int wt)
|
||||
{
|
||||
Edge e;
|
||||
e.v = v;
|
||||
e.w = w;
|
||||
e.wt = wt;
|
||||
return e;
|
||||
}
|
||||
|
||||
// Questa variabile è usata dalla funzione `vertexCompare` che è chiamata da qsort
|
||||
Graph tmpG;
|
||||
|
||||
static int vertexCompare(const void *a, const void *b)
|
||||
{
|
||||
return (strcmp(STsearchByIndex(tmpG->tab, (*(Edge *)a).w).name, STsearchByIndex(tmpG->tab, (*(Edge *)b).w).name));
|
||||
}
|
||||
|
||||
static void EDGEsort(Edge *edges, int N, Graph G)
|
||||
{
|
||||
tmpG = G;
|
||||
qsort(edges, N, sizeof(Edge), vertexCompare);
|
||||
}
|
||||
|
||||
Graph GRAPHload(FILE *fin)
|
||||
{
|
||||
int lines = 0, wt;
|
||||
Graph G;
|
||||
|
||||
Item item1, item2;
|
||||
|
||||
for (char c = getc(fin); c != EOF; c = getc(fin))
|
||||
if (c == '\n') // Se leggo un newline aumento il numero delle linee
|
||||
lines = lines + 1;
|
||||
|
||||
fseek(fin, 0, SEEK_SET);
|
||||
|
||||
G = GRAPHinit(2 * lines); // Alloco sovrastimando il numero di vertici
|
||||
for (int i = 0; i < lines; i++)
|
||||
{
|
||||
item1 = ITEMread(fin);
|
||||
item2 = ITEMread(fin);
|
||||
fscanf(fin, " %d", &wt);
|
||||
|
||||
int id1 = GRAPHgetIndex(G, item1);
|
||||
int id2 = GRAPHgetIndex(G, item2);
|
||||
|
||||
GRAPHinsertE(G, id1, id2, wt);
|
||||
}
|
||||
|
||||
return G;
|
||||
}
|
||||
|
||||
void GRAPHinsertE(Graph G, int v, int w, int wt)
|
||||
{
|
||||
if (G->madj[v][w] == 0)
|
||||
G->E++;
|
||||
G->madj[v][w] = 1;
|
||||
G->madj[v][w] = wt;
|
||||
G->madj[w][v] = 1;
|
||||
G->madj[w][v] = wt;
|
||||
}
|
||||
|
||||
void GRAPHremoveE(Graph G, int v, int w)
|
||||
{
|
||||
if (G->madj[v][w] != 0)
|
||||
G->E--;
|
||||
G->madj[v][w] = 0;
|
||||
G->madj[w][v] = 0;
|
||||
}
|
||||
|
||||
static int **MATRIXinit(int r, int c, int val)
|
||||
{
|
||||
int i, j;
|
||||
int **t = malloc(r * sizeof(int *));
|
||||
for (i = 0; i < r; i++)
|
||||
t[i] = malloc(c * sizeof(int));
|
||||
for (i = 0; i < r; i++)
|
||||
for (j = 0; j < c; j++)
|
||||
t[i][j] = val;
|
||||
return t;
|
||||
}
|
||||
|
||||
static link *LISTinit(int V, link z)
|
||||
{
|
||||
link *list = (link *)malloc(V * sizeof(link));
|
||||
for (int v = 0; v < V; v++)
|
||||
list[v] = z;
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
Graph GRAPHinit(int V)
|
||||
{
|
||||
Graph G = malloc(sizeof *G);
|
||||
G->V = 0;
|
||||
G->E = 0;
|
||||
G->madj = MATRIXinit(V, V, 0);
|
||||
G->z = newNode(-1, -1, NULL);
|
||||
G->ladj = LISTinit(V, G->z);
|
||||
G->tab = STinit(V);
|
||||
return G;
|
||||
}
|
||||
|
||||
void GRAPHfree(Graph G)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < G->V; i++)
|
||||
free(G->madj[i]);
|
||||
free(G->madj);
|
||||
for (i = 0; i < G->V; i++)
|
||||
{
|
||||
freeList(G->ladj[i], G->z);
|
||||
}
|
||||
free(G->ladj);
|
||||
free(G->z);
|
||||
STfree(G->tab);
|
||||
free(G);
|
||||
}
|
||||
|
||||
int GRAPHgetIndex(Graph G, Item item)
|
||||
{
|
||||
int id = STsearch(G->tab, item);
|
||||
if (id == -1)
|
||||
{
|
||||
id = STinsert(G->tab, item);
|
||||
G->V++;
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
void GRAPHbuildLadj(Graph G)
|
||||
{
|
||||
link t;
|
||||
|
||||
for (int i = 0; i < G->V; i++)
|
||||
{
|
||||
freeList(G->ladj[i], G->z);
|
||||
G->ladj[i] = G->z;
|
||||
}
|
||||
|
||||
for (int i = 0; i < G->V; i++)
|
||||
{
|
||||
for (int j = 0; j < G->V; j++)
|
||||
{
|
||||
if (G->madj[i][j] != 0)
|
||||
G->ladj[i] = newNode(j, G->madj[i][j], G->ladj[i]);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < G->V; i++)
|
||||
{
|
||||
if (G->ladj[i] != G->z)
|
||||
{
|
||||
printf("%d", i);
|
||||
for (t = G->ladj[i]; t != G->z; t = t->next)
|
||||
{
|
||||
printf(" -> (%d,%d)", t->id, t->wt);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int checkAdjacencyM(Graph G, int id1, int id2, int id3)
|
||||
{
|
||||
if (!G->madj[id1][id2] || !G->madj[id1][id3])
|
||||
return 0;
|
||||
|
||||
if (!G->madj[id2][id1] || !G->madj[id2][id3])
|
||||
return 0;
|
||||
|
||||
if (!G->madj[id3][id1] || !G->madj[id3][id2])
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int checkAdjacencyL(Graph G, int id1, int id2, int id3)
|
||||
{
|
||||
if (!searchList(G->ladj[id1], G->z, id2) || !searchList(G->ladj[id1], G->z, id2))
|
||||
return 0;
|
||||
|
||||
if (!searchList(G->ladj[id2], G->z, id1) || !searchList(G->ladj[id2], G->z, id3))
|
||||
return 0;
|
||||
|
||||
if (!searchList(G->ladj[id3], G->z, id1) || !searchList(G->ladj[id3], G->z, id2))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void GRAPHCheckVertexAdiacency(Graph G)
|
||||
{
|
||||
puts("Inserisci i tre vertici specificando per ogni vertice \"<nome> <subnet>\"");
|
||||
Item i1 = ITEMread(stdin);
|
||||
Item i2 = ITEMread(stdin);
|
||||
Item i3 = ITEMread(stdin);
|
||||
|
||||
int id1 = STsearch(G->tab, i1);
|
||||
int id2 = STsearch(G->tab, i2);
|
||||
int id3 = STsearch(G->tab, i3);
|
||||
|
||||
if (id1 == -1 || id2 == -1 || id3 == -1)
|
||||
{
|
||||
puts("Attenzione: vertici non validi");
|
||||
return;
|
||||
}
|
||||
|
||||
if (checkAdjacencyM(G, id1, id2, id3))
|
||||
{
|
||||
puts("I vertici formano un sottografo completo");
|
||||
}
|
||||
else
|
||||
{
|
||||
puts("I vertici non formano un sottografo completo");
|
||||
}
|
||||
}
|
||||
|
||||
void GRAPHprintOrdered(Graph G)
|
||||
{
|
||||
Item *items = malloc(G->V * sizeof(Item));
|
||||
Edge *edges = malloc(G->V * sizeof(Edge));
|
||||
|
||||
for (int i = 0; i < G->V; i++)
|
||||
{
|
||||
items[i] = STsearchByIndex(G->tab, i);
|
||||
}
|
||||
|
||||
ITEMsort(items, G->V);
|
||||
|
||||
for (int i = 0; i < G->V; i++)
|
||||
{
|
||||
int id = GRAPHgetIndex(G, items[i]);
|
||||
printf("%s %s:\n", items[i].name, items[i].subnet);
|
||||
|
||||
// Crea lista di edges
|
||||
int N = 0;
|
||||
for (int j = 0; j < G->V; j++)
|
||||
{
|
||||
if (G->madj[id][j] != 0)
|
||||
edges[N++] = EDGEcreate(id, j, G->madj[id][j]);
|
||||
}
|
||||
|
||||
EDGEsort(edges, N, G);
|
||||
|
||||
for (int j = 0; j < N; j++)
|
||||
{
|
||||
printf(" - %s %s, peso %d\n", STsearchByIndex(G->tab, edges[j].w).name, STsearchByIndex(G->tab, edges[j].w).subnet, edges[j].wt);
|
||||
}
|
||||
}
|
||||
|
||||
free(edges);
|
||||
free(items);
|
||||
}
|
||||
Reference in New Issue
Block a user