1
0

feat: Initial commit

This commit is contained in:
2024-03-22 17:37:24 +01:00
parent 4288bd63a1
commit 6732a7a166
120 changed files with 9620 additions and 0 deletions

View 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);
}