Scaricare la presentazione
La presentazione è in caricamento. Aspetta per favore
1
Grafi Rappresentazione mediante liste di adiacenza:
struct graph_l { /* array di puntatori a liste */ list **adj_list; /* numero di vertici */ int n; }; Rappresentazione mediante matrici di adiacenza: struct graph_m /* matrice da allocare dinamicamente */ int **adj_matrix;
2
Creazione grafo con matrice di adiacenza
graph_m *crea_grafo_m(int n) { int i, j; graph_m *g = (graph_m *)malloc(sizeof(graph_m)); g->n = n; g->adj_matrix = (int **)malloc(sizeof(int*)*n); for(y=0; y < n; y++) g->adj_matrix[y] = (int *)malloc(sizeof(int)*n); for(x=0; x < n; x++) g->adj_matrix[y][x] = 0; } return g;
3
Creazione grafo con liste di adiacenza
graph_l *crea_grafo_l(int n) { int i; graph_l *g = (graph_l *)malloc(sizeof(graph_l)); g->n = n; g->adj_list = (list **)malloc(sizeof(list *)*n); for(y=0; y < n; y++) g->adj_list[y] = NULL; return g; }
4
Visita in profondità (Depth-First Search)
Utilizziamo un array v per memorizzare i nodi già visitati void DFS(graph *g, int k) { list *edges = g->adj_list[k]; v[k] = 1; printf(“%d,”, k); while(edges != null) int j = edges->el; /* visita un nodo solo se non è stato ancora visitato */ if (v[j] == 0) DFS(g, j); edges = edges->next; }
5
Visita in ampiezza (Breadth-First Search)
Utilizziamo una coda per implementare una visita “a buccia di cipolla”: void BFS(graph *g, int k) { coda *t = crea_coda(); tail_add(t, k); v[k] = 1; printf(“%d”, k); while(!coda_vuota(t)) int j = tail_remove(t); list *edges = g->adj_list[j]; while(edges != NULL) j = edges->el; If (v[j] == 0) printf(“%d,”, j); v[j] = 1; tail_add(t, m); } edges = edges->next;
6
Esercizi Scrivere una funzione che, dato un grafo rappresentato sotto forma di liste di adiacenza, ne restituisca la rappresentazione sotto forma di matrice di adiacenza Scrivere una funziona ricorsiva che, dato un grafo rappresentato mediante liste di adiacenza e dato un camino rappresentato mediante una lista di nodi, verifichi se il cammino esiste nel grafo fornito in input. Scrivere una funzione che dato un grafo e un nodo k di partenza determini per ciascun nodo destinazione j un cammino di lunghezza minima da k a j e la distanza di tale cammino Suggerimento: modificare la BFS in modo da memorizzare il nodo di provenienza e la distanza
7
Esercizio 1 Pre condizioni: Post condizioni:
Scrivere una funzione che, dato un grafo rappresentato sotto forma di liste di adiacenza, ne restituisca la rappresentazione sotto forma di matrice di adiacenza. Pre condizioni: La funzione prende in ingresso un grafo rappresentato mediante liste di adiacenza Post condizioni: La funzione restituisce un grafo equivalente rappresentato mediante matrici di adiacenza.
8
Esercizio 1 graph_m *list2matrix(graph_l *g1) { int y; list *l;
graph_m *g2 = crea_grafo_m(g1->n); for(y=0; y<g1->n; y++) for(l= g1->m[y]; l != NULL; l=l->next) g2->m[y][l->el] = 1; return g2; }
9
Esercizio 2 Pre condizioni: Post condizioni:
Scrivere una funzione ricorsiva che, dato un grafo rappresentato mediante liste di adiacenza e un cammino rappresentato mediante una lista di nodi, verifichi se il cammino esiste nel grafo fornito in input. Pre condizioni: La funzione prende in ingresso un grafo e una lista di nodi (ovvero un cammino) Post condizioni: La funzione restituisce 1 se e' possibile percorrere il cammino nel grafo in input, 0 altrimenti.
10
Implementazione int verifica_arco(graph_l *g, int u, int v) {
list *adj = g->adj_list[u]; while(adj) if (adj->el == v) return 1; adj = adj->next; } return 0; int verifica(graph *g_l, list *p) if (!p || p->next == NULL) return 1; return verifica_arco(g, p->el, p->next->el) && verifica(g, p->next);
11
Esercizio 3 Pre condizioni: Post condizioni:
Scrivere una funzione che dato un grafo e un nodo k di partenza determini per ciascun nodo destinazione j un cammino di lunghezza minima da k a j e la distanza di tale cammino. Pre condizioni: La funzione prende in ingresso un grafo, un nodo iniziale e gli indirizzi dei vettori distanza e cammino Post condizioni: La funzione imposta per ciascun nodo j nei due vettori rispettivamente la distanza minima partendo da k e il predecessore di j nel cammino minimo che parte da k
12
Svolgimento void dist_min(graph_l *g, int p, int **dist, int **predec) { int i; *dist = (int *)malloc(sizeof(int), g->n); *predec = (int *)malloc(sizeof(int), g->n); /* predecessore del cammino min. di ciascun nodo */ for (i=0; I < g->n; i++) dist[i] = -1; /* -1 =>non visitato, altrimenti la distanza */ coda *c = crea_coda(); add_tail(c, p); dist[p] = 0; while(!coda_vuota(c)) int curr = remove_head(c); for(l=g->m[curr]; l != NULL; l=l->next) if(dist[l->el] == -1) /* nodo non ancora visitato */ dist[l->el] = dist[curr] + 1; predec[l->el] = curr; add_tail(c, l->el); }
Presentazioni simili
© 2024 SlidePlayer.it Inc.
All rights reserved.