C - Libreria Grafo

di il
49 risposte

49 Risposte - Pagina 3

  • Re: C - Libreria Grafo

    violet_prog ha scritto:


    (6)A->(-2.5)B;B->C,(+4.2)D;C->(+3.2)D,F;D;E->(+1.0)A;F;.
    Dovrebbe voler dire:
    6 vertici
    A->B (-2.5)
    B->C (senza peso)
    B->D (+4.2)
    C->D (+3.2)
    C->F (senza peso)
    D (senza archi uscenti)
    E->A (+1.0)
    F (senza archi uscenti)
  • Re: C - Libreria Grafo

    A->(-2.5)B
    B->C,(+4.2)D
    C->(+3.2)D,F
    D-> (senza archi)
    E->(+1.0)A
    F-> (senza archi)
  • Re: C - Libreria Grafo

    Vedi un'altra idea, di passare da una rappresentazione all'altra, potrebbe essere quella di costruire una funzione che parsifichi il grafo secondo questa codifica, in modo a poter poi leggere questa parsificazione e costruire il nuovo grafo.
  • Re: C - Libreria Grafo

    SVNiko ha scritto:


    Vedi un'altra idea, di passare da una rappresentazione all'altra, potrebbe essere quella di costruire una funzione che parsifichi il grafo secondo questa codifica, in modo a poter poi leggere questa parsificazione e costruire il nuovo grafo.
    Ma io ho già una funzione che parsifica il grafico a partire da questa codifica...
  • Re: C - Libreria Grafo

    Dovresti creare una funzione che dato un grafo la codifichi con quella grammatica.
  • Re: C - Libreria Grafo

    SVNiko ha scritto:


    Dovresti creare una funzione che dato un grafo la codifichi con quella grammatica.
    Ai fini della conversione?
  • Re: C - Libreria Grafo

    Al fine di poter passare da una rappresentazione all'altra.
  • Re: C - Libreria Grafo

    Credi questa sia la soluzione migliore?
    Il programma inizia con un grafo in un file, che viene letto, parsificato con le funzioni e immagazzinato in una delle due strutture. Poi prendere il grafo riparsificarlo e immagazzinarlo nell'altra struttura? Non è troppo?
  • Re: C - Libreria Grafo

    violet_prog ha scritto:


    Credi questa sia la soluzione migliore?
    Il programma inizia con un grafo in un file, che viene letto, parsificato con le funzioni e immagazzinato in una delle due strutture. Poi prendere il grafo riparsificarlo e immagazzinarlo nell'altra struttura? Non è troppo?
    Troppo per cosa?

    Se hai un grafo puoi creare una stringa con quella grammatica, ciò ti consente di passare da una rappresentazione all'altra senza passare dalla matrice come avevamo previsto.
  • Re: C - Libreria Grafo

    Io credo che non vada bene così. Perchè in realtà io la conversione la potrei fare anche utilizzando sempre il file, e si semplificherebbe ancora di più il tutto. Ma credo che quello che voglia il prof. sia proprio passare da una rappresentazione all'altra utilizzando le strutture stesse, altrimenti non avrebbe senso l'esercitazione. Si potrebbero utilizzare mille scorciatoie per risolvere il problema, ma non sarebbe ciò che viene richiesto. "Conversione tra le due rappresentazioni".. passaggio da una all'altra.
  • Re: C - Libreria Grafo

    violet_prog ha scritto:


    Io credo che non vada bene così. Perchè in realtà io la conversione la potrei fare anche utilizzando sempre il file, e si semplificherebbe ancora di più il tutto. Ma credo che quello che voglia il prof. sia proprio passare da una rappresentazione all'altra utilizzando le strutture stesse, altrimenti non avrebbe senso l'esercitazione. Si potrebbero utilizzare mille scorciatoie per risolvere il problema, ma non sarebbe ciò che viene richiesto. "Conversione tra le due rappresentazioni".. passaggio da una all'altra.
    La conversione utilizzando lo stesso file non ha alcun senso. Implementare una funzione che passi da una rappresentazione all'altra significa che devi congelare quello che hai in memoria in una data rappresentazione e poterla rappresentare un altro modo.

    Immagina tu abbia caricato dei dati dal file iniziale e aggiunto nuovi archi, questi nuovi archi non ce li hai nel file iniziale, ma quando converti essi devono essere rappresentati.

    Sarebbe possibile salvare su un file la struttura dati e leggere quest'ultimo file, ma non si fa a meno di particolari esigenze perché operazione costosa.

    Quello che devi fare è prendere i dati che sono rappresentati ad una certa maniera e poterli interpretare per poterli immagazzinare in un'altra rappresentazione. Adesso come estrapoli questi dati?
    1) Mettendoli in una matrice (hai la funzione speculare che da matrice immagazzina nella rappresentazione desiderata)
    2) Mettendoli in una stringa codificata con una determinata grammatica (hai la funzione speculare che da quella codifica immagazzina nella rappresentazione desiderata)
    3) Mettendo i dati in una struttura stranissima, non importa quanto strano ma che tu sai codificare/decodificare (hai la funzione speculare che dalla struttura stranissima immagazzina nella rappresentazione desiderata)
  • Re: C - Libreria Grafo

    SVNiko ha scritto:


    La conversione utilizzando lo stesso file non ha alcun senso. Implementare una funzione che passi da una rappresentazione all'altra significa che devi congelare quello che hai in memoria in una data rappresentazione e poterla rappresentare un altro modo.

    Immagina tu abbia caricato dei dati dal file iniziale e aggiunto nuovi archi, questi nuovi archi non ce li hai nel file iniziale, ma quando converti essi devono essere rappresentati.

    Sarebbe possibile salvare su un file la struttura dati e leggere quest'ultimo file, ma non si fa a meno di particolari esigenze perché operazione costosa.

    Quello che devi fare è prendere i dati che sono rappresentati ad una certa maniera e poterli interpretare per poterli immagazzinare in un'altra rappresentazione. Adesso come estrapoli questi dati?
    1) Mettendoli in una matrice (hai la funzione speculare che da matrice immagazzina nella rappresentazione desiderata)
    2) Mettendoli in una stringa codificata con una determinata grammatica (hai la funzione speculare che da quella codifica immagazzina nella rappresentazione desiderata)
    3) Mettendo i dati in una struttura stranissima, non importa quanto strano ma che tu sai codificare/decodificare (hai la funzione speculare che dalla struttura stranissima immagazzina nella rappresentazione desiderata)

    Mmm preferisco la soluzione che mi avevi proposto prima delle funzioni interne alle librerie, questa non mi piace
  • Re: C - Libreria Grafo

    #include <stdio.h>
    #include <stdlib.h>
    #include "grafolista.h"
    #include "grafomatrice.h"
    #include "grafo.h"
    
    GrafoMatr convertToMatrice (GrafoAdj G, int n)
    {
        GrafoMatr M; int i;
        M=creaGrafoMatr(n);
    
        char *v=(char*)malloc((n)*sizeof(char));
    
        float **p=(float**)malloc((n)*sizeof(float*));
        for(i=0;i<n;i++)
            p[i]=(float*)malloc((n)*sizeof(float));
    
        int **m=(int**)malloc((n)*sizeof(int*));
        for(i=0;i<n;i++)
            m[i]=(int*)malloc((n)*sizeof(int));
    
        estrapolaLista(G,&v,&m,&p);
        M=generaGrafoMatr(M,v,m,p);
    
        free(v); free(p); free(m);
        return M;
    
    }
    
    
    GrafoAdj convertToLista (GrafoMatr M, int n)
    {
        GrafoAdj G; int i;
        G=creaGrafoLista(n);
    
        char *v=(char*)malloc((n)*sizeof(char));
    
        float **p=(float**)malloc((n)*sizeof(float*));
        for(i=0;i<n;i++)
            p[i]=(float*)malloc((n)*sizeof(float));
    
        int **m=(int**)malloc((n)*sizeof(int*));
        for(i=0;i<n;i++)
            m[i]=(int*)malloc((n)*sizeof(int));
    
        estrapolaMatrice(M,&v,&m,&p);
        G=generaGrafoLista(G,v,m,p);
    
        free(v); free(p); free(m);
        return G;
    }
    Così funziona.. Che dici?
  • Re: C - Libreria Grafo

    Il codice non ho modo di controllarlo, ma sembra funzioni.

    Hai adottato la soluzione della libreria grafo che ha il compito di fare la conversione:

    grafo.h
    GrafoMatr convertToMatrice (GrafoAdj G, int n);
    GrafoAdj convertToLista (GrafoMatr M, int n);
  • Re: C - Libreria Grafo

    SVNiko ha scritto:


    Il codice non ho modo di controllarlo, ma sembra funzioni.

    Hai adottato la soluzione della libreria grafo che ha il compito di fare la conversione:

    grafo.h
    GrafoMatr convertToMatrice (GrafoAdj G, int n);
    GrafoAdj convertToLista (GrafoMatr M, int n);
    Esatto. Ma ho un errore, che quando faccio la conversione da lista a matrice la stampa dei vertici mi visualizza simboli a caso. Il debug mi porta errore in grafoStampaMatr ma non riesco a trovarlo. Copio il codice:

    main.c
    #include <stdio.h>
    #include <stdlib.h>
    #include "grafolista.h"
    #include "grafomatrice.h"
    #include "grafo.h"
    #include "grafoparser.h"
    
    
    int menuIniziale(void);
    int menuGrafo(void);
    char * scegliFile(void);
    char * scriviGrafo(void);
    
    
    int main()
    {
        FILE *file;
        char *nome;
        GrafoAdj G=NULL,Gc=NULL;
        GrafoMatr M=0,Mc=0;
        int numVertici=0;
        int scelta,tipo,conv;
    
        printf("\t***************************************************\n");
        printf("\t*                                                 *\n");
        printf("\t*      PROGRAMMA PER LA GESTIONE DI GRAFI         *\n");
        printf("\t*                                                 *\n");
        printf("\t***************************************************\n\n\n");
        printf("Benvenuto nel programma di gestione della struttura dati dinamica: GRAFO\n");
        printf("Prima di iniziare e' necessario costruire ALMENO un Grafo.\n\n");
        system("PAUSE");
    
        scelta= menuIniziale();
    
        if (scelta==1) nome = scegliFile();
        else nome= scriviGrafo();
    
        file = fopen(nome,"r");
    
        printf("\n>>Scegli il tipo di rappresentazione:\n1)Liste di adiacenza\n2)Matrice di adiacenza\n\n");
        scanf("%d",&tipo);
        printf("\n\nINIZIO TRADUZIONE FILE...\n");
        system("PAUSE"); system("cls");
        printf("Le informazioni estratte sono le seguenti:\n\n");
    
        if(tipo==1) numVertici=parseGrafo(file,&G,0,tipo);        // Parse grafo
        else if(tipo==2) numVertici=parseGrafo(file,NULL,&M,tipo);
    
        fclose(file);
    
        printf("\nIl grafo creato:\n");
        if(G!=NULL) stampaGrafoLista(G,numVertici);
        else if (M!=NULL) stampaGrafoMatr(M,numVertici);
        else
            printf("Grafo vuoto\n");
    
        system("PAUSE");
        system("cls");
    
        scelta=menuGrafo();
    
        switch (scelta)
        {
            case 1:break;
            case 2:break;
            case 3:break;
            case 4:break;
            case 5:break;
            case 6:break;
            case 7:break;
            case 8:break;
            case 9:break;
            case 10:
                printf("Converti da un tipo ad un altro:\n1)Da Lista a Matrice\n2)Da Matrice a Lista\n");
                scanf("%d",&conv);
                if(conv==1)
                {
                    M=convertToMatrice(G,numVertici);
                    printf("\n\n");
                    stampaGrafoLista(G,numVertici);
                    printf("\n\n");
                    stampaGrafoMatr(M,numVertici);
                    printf("\n\n");
                }
                else
                {
                    G=convertToLista(M,numVertici);
                    printf("\n\n");
                    stampaGrafoMatr(M,numVertici);
                    printf("\n\n");
                    stampaGrafoLista(G,numVertici);
                    printf("\n\n");
    
                    }
                break;
            default:;
        }
    
    
    
    
    
        system("PAUSE");
    
    
    
        return 0;
    }
    
    int menuIniziale(void)
    {
        int x;
        system("cls");
        printf("\t CREAZIONE GRAFO :\n\n");
        printf("1)Leggi il grafo da un file;\n2)Scrivi un nuovo grafo su un file.\n");
        scanf("%d",&x);
    
        return x;
    }
    
    char *scegliFile(void)
    {
        char *nome; int x,y;
    
        printf("\n\nScegli uno dei file esistenti:\n1) Grafo 1\n2) Grafo 2\n3) Grafo 3\n");
        scanf("%d",&x);printf("\n");
        switch(x)
        {
        case 1:
            nome="grafo1.txt";
            break;
        case 2:
            nome="grafo2.txt";
            break;
        case 3:
            nome="grafo3.txt";
            break;
        default:
            printf("::ERRORE:: La scelta non è valida!!\n\n Riprova -> 1\nPremi un tasto qualsiasi per Uscire...\n");
            scanf("%d",&y);
            if(y==1) nome=scegliFile();
            else exit(1);
        }
    
        return nome;
    }
    
    char * scriviGrafo()
    {
        system("cls");
        int n,x,y,j,v,i;
        char *nome="grafonew.txt";
        FILE *filenuovo=fopen("grafonew.txt","w");
        printf("\t\t.:POPOLAMENTO GRAFO:.\n\n");
        printf("Quanti vertici deve contenere il grafo? ");
        scanf("%d",&n); printf("\n");
        fprintf(filenuovo,"%c%d%c",'(',n,')');
    
        for(i=1;i<=n;i++)
        {
            printf("\nVertice %d :\n",i);
            fprintf(filenuovo,"%c%d%s",' ',i,"->");
            printf("\n1)Crea Archi\n2)Passa al vertice successivo\n");
            scanf("%d",&x);
            if(x==2) fprintf(filenuovo,"%s","(-0.0);");
            else
            {
                printf("Quanti archi? ");
                scanf("%d",&y);printf("\n");
                fprintf(filenuovo,"%s%d%s","(+",y,".0)");
                printf("Inserisci vertici incidenti \n");
                for(j=1;j<=y;j++)
                {
                    scanf("%d",&v);
                    fprintf(filenuovo,"%c%d%c%d",' ',i,'|',v);
                    if(j==y) fprintf(filenuovo,"%c ",';');
                }
    
            }
    
        }
    
        fprintf(filenuovo,"%c",'.');
        printf("FILE SCRITTO CON SUCCESSO!!!\n");
        fclose(filenuovo);
        system("PAUSE");
    
        return nome;
    }
    
    int menuGrafo(void)
    {
        int scelta;
        printf("\t\t.:: MENU GRAFO ::.\n\n");
        printf("1- Inserisci Vertice\n2- Inserisci Arco\n");
        printf("3- Cancella Vertice\n4- Cancella Arco\n");
        printf("5- Calcola Grafo Trasposto\n6- Visita in Ampiezza\n7- Visita in Profondità\n");
        printf("8- Stampa di un percorso tra due vertici\n9- Verifica Aciclicità del Grafo\n");
        printf("10- Cambia rappresentazione grafo.\n\n");
    
        scanf("%d",&scelta);
    
        return scelta;
    }
    
    grafoparser.h
    #ifndef GRAFOPARSER_H_INCLUDED
    #define GRAFOPARSER_H_INCLUDED
    typedef enum {PARSX, PARDX, NUM, PUNTO, MENO, PIU, PUNT, PUNTOV, VIRG, PESO, ID} type; // Tipo dei simboli terminali
    
    int parseGrafo (FILE *file, GrafoAdj *G, GrafoMatr *M, int tipo);
    void verticiAdj (GrafoAdj G, GrafoMatr M, char nodo, FILE *file);
    int confronto(FILE *file, type x);
    void sposta (FILE *file, type x);
    int traduciNumeroNodi(FILE *file);
    int traduciIntero(FILE *file);
    float traduciPeso (FILE *file);
    
    #endif // GRAFOPARSER_H_INCLUDED
    grafoparser.c
    #include <ctype.h>
    #include "grafo.h"
    #include "grafoparser.h"
    #include <string.h>
    
    // Elaborazione simboli NON TERMINALI
    
    int parseGrafo (FILE *file, GrafoAdj *G, GrafoMatr *M, int tipo)
    { //Traduce il grafo [ritorna il puntatore alla radice]
        int x,n=0,i=0;
        char val;
    
        n=traduciNumeroNodi(file); //leggi il numero di nodi che dovrà contenere il grafo
    
        if(tipo==2)*M=creaGrafoMatr(n);
        else *G=creaGrafoLista(n);
    
        while(i<n)
        {
            x=confronto(file,ID); //verifica che dopo il numero di nodi ci sia un nodo stesso
            if(x)
            {
                val=fgetc(file); //estrai il primo nodo
                ungetc(val,file);
                if(tipo==1)
                {
                    *G=aggiungiVerticeLista(*G,val,0);
                    sposta(file,ID);
                    verticiAdj(*G,0,val,file);
                }
                else
                {
                    *M=aggiungiVerticeMatr(*M,val,0,n);
                    sposta(file,ID);
                    verticiAdj(NULL,*M,val,file); //traduce i vertici adiacenti al nodo
                }
            }
            else printf(":: ERRORE VERTICE! ::\n\n");
    
            i++;
        }
        // else ERRORE NESSUN NODO PRESENTE!!!
        return n;
    }
    
    int traduciNumeroNodi(FILE *file) // DOPO LA FUNZIONE LO STREAM SI TROVA DOPO LA PARENTESI CHIUSA
    {//Esamina i simboli che rappresentano il numero di nodi [se ' (numeroIntero) ' ritorna il numero, altrimenti errore]
        int n=0;
        if(confronto(file,PARSX)) //se il simbolo corrente è una parentesi aperta è verificato il primo simbolo
        {
            sposta(file,PARSX);//ci si sposta al simbolo successivo la parentesi
            if (confronto(file,NUM)) // se il simbolo corrente è del tipo intero è verificato il secondo simbolo
                {
                    n=traduciIntero(file);
                    //sposta(file,NODO); //ci si sposta al simbolo successivo al nodo NON NECESSARIO
                    if(confronto(file,PARDX)) //se il simbolo corrente è una parentesi chiusa è verificato anche il terzo simbolo
                        {
                            sposta(file,PARDX); //si sposta al simbolo successivo all'interno del file
                            return n;}
                    }
        }
        return 0; //ritorna errore
    }
    
    int traduciIntero (FILE *file) // DOPO LA FUNZIONE LO STREAM SI TROVA DOPO L'INTERO
    {//Traduci il simbolo non terminale che rappresenta un intero [ritorna il vertice intero del nodo]
    	int c=0,num=0,l=0;
    	while ((c=fgetc(file)) != EOF && isdigit(c)) {
    		  if (num <= ((INT_MAX - (c-'0'))/10)){
    		      num = num*10 + (c-'0');
    		      l++;
       		  }
    	     // else syntax_error("Integer ID <= 2147483647",file); // Number too big: ERROR
    	}
    	//if (l==0) syntax_error("Integer ID",file); // The ID is not a number
    	if(c != EOF)       // If EndOfFile not yet reached
    		ungetc(c,file);      // push the last character back to the file
    
    	return num;
    }
    
    float traduciPeso (FILE *file)
    {
        float peso; char segno; int pintera, pdecimale; char stringa[10];
    
        segno=fgetc(file);
        pintera=traduciIntero(file);
        if (confronto(file,PUNTO)) //se dopo l'intero c'è un un punto allora è un float
        {
            sposta(file,PUNTO); //sposta allo stream successivo al punto
            pdecimale=traduciIntero(file);
    
        }
        else
        {
            printf("Errore Sintassi Peso! Il numero non è floating point!!\n");
            return 0;
        }
    
    
        sprintf(stringa, "%c", segno);
        sprintf(stringa, "%s%d", stringa,pintera);
        sprintf(stringa, "%s%c",stringa, '.');
        sprintf(stringa, "%s%d", stringa,pdecimale);
    
        peso=atof(stringa);
    
        sposta(file,PARDX);
    
        return peso;
    }
    
    void verticiAdj (GrafoAdj G, GrafoMatr M, char nodo, FILE *file)
    {//Traduci vertici adiacenti
        int res;
        char val;
        float peso;
        res=confronto(file,PUNT);  // Cerca freccia che indica a quali vertici punta il nodo in questione
        while(res!=0)
        {// Se IL SIMBOLO PUNTATORE è stato trovata verificare che segua un peso
            peso=0;
            if (confronto(file,PARSX))
            {sposta(file,PARSX);
            if(confronto(file,PESO))
                peso=traduciPeso(file);
            }
    
            val=fgetc(file);
    
            if(G!=NULL) G=aggiungiArcoLista(G,nodo,val,peso);
            else M=aggiungiArcoMatr(M,nodo,val,peso);
    
            if (confronto(file,VIRG))
                sposta(file,VIRG);
            else
                res=0;
            }
         //non ha altri vertici adiacenti
    
        sposta(file,PUNTOV);
        printf("\n");
    
    }
    
    
    
    
    // Elaborazione simboli TERMINALI
    
    int confronto(FILE *file, type x)
    { //Verifica se il tipo x corrisponde al simbolo nel file [ritorna 1  se vero, 0 altrimenti]
    	char c;
    	type rp;                       // Read symbol type
    	int res=0;
    
    	while(((c = fgetc(file)) == '\t') || (c== '\n') || (c== ' '))
    			;
        switch(c) {               // Determine the read symbol type
            case '(': rp = PARSX; break;
            case ')': rp = PARDX; break;
            case '-':
                rp=MENO;
                if(confronto(file,PUNT)) rp=PUNT;
                else rp=PESO;
                break;
            case '>': rp=PUNT; break;
            case '+': rp=PESO; break;
            case ';': rp = PUNTOV; break;
            case ',': rp = VIRG; break;
            case '.': rp= PUNTO; break;
            default : rp = NUM; break;
        }
    
        if(rp==NUM) //se alla fine dello switch rp è NUM è un intero altrimenti è un ID
           {
               if(!isdigit(c))
                    rp=ID;
           }
    
        ungetc(c,file); // Push the read character back to the file
    
        if(rp==PUNT) //Se il tipo è un puntatore effettuo uno spostamento in avanti in quanto il simbolo corrente potrebbe essere il meno perchè il simbolo del punt è fatto da '-' e '>'
            sposta(file,PUNT);
    
        if (rp==x)        // The expexted type et and the read symbol type rp match
    			res = 1;
    
      return res;
    }
    
    void sposta (FILE *file, type x)
    {//si sposta nel file al simbolo successivo a quello del tipo x
    	int dim = 0;
    
        switch(x) {               // Assign the read symbol type
       	   case PARSX:; case PARDX:; case NUM:; case PUNTO:; case MENO:; case PIU:; case PUNT:; case PUNTOV:; case VIRG:; case ID:; case PESO:dim=1; break;
        } //qualunque sia il simbolo ricevuto dim=1, ci si sposta di un passo
    
    	fseek(file,dim,SEEK_CUR);   // Si muove di dim passi a partire da quello corrente all'interno del file
    }
    
    grafo.h
    #ifndef GRAFO_H_INCLUDED
    #define GRAFO_H_INCLUDED
    
    
    GrafoMatr convertToMatrice (GrafoAdj G, int n);
    GrafoAdj convertToLista (GrafoMatr M,int n);
    
    #endif // GRAFO_H_INCLUDED
    grafo.c
    #include <stdio.h>
    #include <stdlib.h>
    #include "grafolista.h"
    #include "grafomatrice.h"
    #include "grafo.h"
    
    GrafoMatr convertToMatrice (GrafoAdj G, int n)
    {
        GrafoMatr M; int i;
        M=creaGrafoMatr(n);
    
        char *v=(char*)malloc((n)*sizeof(char));
    
        float **p=(float**)malloc((n)*sizeof(float*));
        for(i=0;i<n;i++)
            p[i]=(float*)malloc((n)*sizeof(float));
    
        int **m=(int**)malloc((n)*sizeof(int*));
        for(i=0;i<n;i++)
            m[i]=(int*)malloc((n)*sizeof(int));
    
        estrapolaLista(G,&v,&m,&p);
        M=generaGrafoMatr(M,v,m,p);
    
        free(v); free(p); free(m);
        return M;
    
    }
    
    
    GrafoAdj convertToLista (GrafoMatr M, int n)
    {
        GrafoAdj G; int i;
        G=creaGrafoLista(n);
    
        char *v=(char*)malloc((n)*sizeof(char));
    
        float **p=(float**)malloc((n)*sizeof(float*));
        for(i=0;i<n;i++)
            p[i]=(float*)malloc((n)*sizeof(float));
    
        int **m=(int**)malloc((n)*sizeof(int*));
        for(i=0;i<n;i++)
            m[i]=(int*)malloc((n)*sizeof(int));
    
        estrapolaMatrice(M,&v,&m,&p);
        G=generaGrafoLista(G,v,m,p);
    
        free(v); free(p); free(m);
        return G;
    }
    
    grafolista.h
    #ifndef GRAFOLISTA_H_INCLUDED
    #define GRAFOLISTA_H_INCLUDED
    
    typedef struct grafolista * GrafoAdj;
    typedef struct elementoLista * nodoLista;
    
    GrafoAdj creaGrafoLista(int n); //restituisce un puntatore ad una struttura dati grafo con n liste di adiacenza vuote
    GrafoAdj aggiungiVerticeLista (GrafoAdj g, char val, int i);
    GrafoAdj aggiungiArcoLista (GrafoAdj G, char curr, char val, float p);
    nodoLista aggiungiInLista (nodoLista lista, char val,float p);
    void stampaGrafoLista (GrafoAdj g,int n);
    void stampaLista(nodoLista lista);
    int cercaVerticeLista(GrafoAdj G, char nodo, int n);
    int verificaArcoLista(GrafoAdj G, int x, int y);
    GrafoAdj DFS_Lista (GrafoAdj G);
    GrafoAdj DFS_Visita_Lista (GrafoAdj G,nodoLista lista,int i,int n);
    
    void estrapolaLista(GrafoAdj G, char **vertici, int ***matrice, float ***pesi);
    GrafoAdj generaGrafoLista (GrafoAdj G, char *vertici, int ** matrice, float ** peso);
    
    
    #endif // GRAFOLISTA_H_INCLUDED
    
    grafolista.c
    #include <stdio.h>
    #include <stdlib.h>
    #include "grafolista.h"
    #include <stdbool.h>
    
    
    typedef struct elementoLista{
    char vertice;
    float peso;
    //int dist; //distanza
    struct elementoLista *next;
    }elementoLista;
    
    typedef struct grafolista {
    int numVertici;
    char * colore;
    char * pred;
    elementoLista ** nodi; //array di liste di adiacenza
    }grafolista;
    
    
    GrafoAdj creaGrafoLista(int n)
    {
        GrafoAdj G; int i;
        G=(grafolista*)malloc(sizeof(grafolista));
        if(G==NULL)printf("Errore allocazione grafo!\n");
        else
        {
            G->nodi=(elementoLista**)malloc(n*sizeof(elementoLista*)); //alloca l'array di liste
            if((G->nodi==NULL)&&(n>0))
            {
                printf("Errore allocazione archi!\n");
                free(G);
                G=NULL;
            }
            else
            {
                G->numVertici=n;
                G->colore=(char*)malloc((n)*sizeof(char));
                G->pred=(char*)malloc((n)*sizeof(char));
                for(i=0;i<n;i++)
                {
                    G->nodi[i]=NULL;
                    G->colore[i]='b';
                    G->pred[i]=0;
                }
           }
       }
       return G;
    }
    
    GrafoAdj aggiungiVerticeLista (GrafoAdj G, char val, int i)
    {
        if(i<G->numVertici)
        {
           if(G->nodi[i]==NULL)
        {
            G->nodi[i]=(elementoLista*)malloc(sizeof(elementoLista));
            G->nodi[i]->vertice=val;
            G->nodi[i]->peso=0.0;
            G->nodi[i]->next=NULL;
    
            return G;
        }
        else
            return aggiungiVerticeLista(G,val,i+1);
        }
      /*  else
            {
                G->nodi=realloc(G->nodi,G->numVertici+1);
                G->numVertici=G->numVertici+1;
                return aggiungiVerticeLista(G,val,i);
            }
    */
    
        return G;
    }
    
    GrafoAdj aggiungiArcoLista (GrafoAdj G, char curr, char val, float p)
    {
        int i=cercaVerticeLista(G,curr,G->numVertici); //ritorna l'indice di curr
        G->nodi[i]->next=aggiungiInLista(G->nodi[i]->next,val,p);
    
        return G;
    }
    
    nodoLista aggiungiInLista (nodoLista lista, char val, float p)
    {
        if(lista==NULL)
        {
            lista=(elementoLista*)malloc(sizeof(elementoLista));
            lista->vertice=val;
            lista->peso=p;
            lista->next=NULL;
        }
        else
            lista->next=aggiungiInLista(lista->next,val,p);
    
        return lista;
    }
    
    
    int cercaVerticeLista(GrafoAdj G, char nodo, int n)
    {
        int i=0;
        while((i<n)&&(G->nodi[i]!=NULL))
        {
            if(G->nodi[i]->vertice==nodo)
                return i;
    
            i++;
        }
    
      return 0;
    }
    
    void stampaGrafoLista (GrafoAdj g, int n)
    {
        int i;
        if (g==NULL) { printf("\n"); return;}
        else
        {
            for(i=0;i<n;i++)
            {
                printf("%c ",g->nodi[i]->vertice);
                if(g->nodi[i]->next!=NULL)
                {
                        printf(" -> ");
                        stampaLista(g->nodi[i]->next);
                }
                else printf(" -> NULL \n");
    
    
            }
        }
    }
    
    void stampaLista(nodoLista lista) {
    
        if (lista == NULL) {printf("\n"); return;}
        else
        {
            if(abs(lista->peso) > 0) printf("(%.2f)",lista->peso);
            printf("%c",lista->vertice);
            if(lista->next!=NULL) printf(",");
            stampaLista(lista->next);
            }
    }
    
    
    int verificaArcoLista(GrafoAdj G,int x,int y)
    {
        nodoLista DA=G->nodi[x]->next;
        char A=G->nodi[y]->vertice;
    
        while(DA!=NULL)
        {
            if(DA->vertice==A)
                return 1;
            else
                DA=DA->next;
        }
    
        return 0;
    }
    
    GrafoAdj DFS_Lista (GrafoAdj G)
    {
        int i;
        int n=G->numVertici;
        //inizializza grafo
        for(i=0;i<n;i++)
        {
            G->colore[i]='b';
            G->pred[i]=0;
        }
    
    
        for(i=0;i<n;i++)
        {
            if(G->colore[i]=='b')
                G=DFS_Visita_Lista(G,G->nodi[i],i,n);
        }
    
        printf("ritorno!\n");
        return G;
    }
    
     GrafoAdj DFS_Visita_Lista (GrafoAdj G,nodoLista lista,int i,int n)
     {
         G->colore[i]='g';
    
         while(lista->next!=NULL)
         {
             lista=lista->next;
             i=cercaVerticeLista(G,lista->vertice,n);
             if(G->colore[i]=='b')
             {
                 G->pred[i]=lista->vertice;
                 G=DFS_Visita_Lista(G,lista,i,n);
             }
    
    
         }
    
         G->colore[i]='n';
         return G;
     }
    
     GrafoAdj generaGrafoLista (GrafoAdj G, char * vertici, int ** matrice, float ** peso)
     {
         int i,j;
         int n=G->numVertici;
    
         for(i=0;i<n;i++)
        {
            G=aggiungiVerticeLista(G,vertici[i],i);
            for(j=0;j<n;j++)
            {
                if((i!=j)&&(matrice[i][j]))
                    G=aggiungiArcoLista(G,vertici[i],vertici[j],peso[i][j]);
            }
        }
    
        return G;
    
     }
    
     void estrapolaLista(GrafoAdj G, char **vertici, int ***matrice, float ***pesi)
     {
         int n=G->numVertici;
         nodoLista lista=NULL;
    
         int i=0,j;
         while(i<n)
         {
             (*vertici)[i]=G->nodi[i]->vertice; printf("(*vertici)[%d]=%c\n",i,(*vertici)[i]);
             lista=G->nodi[i]->next;
             while(lista!=NULL)
             {
                 printf("%c ha archi adiacenti\n",G->nodi[i]->vertice);
                 j=cercaVerticeLista(G,lista->vertice,n);
                 (*matrice)[i][j]=1;
                 if(abs(lista->peso)!=0.0)
                    (*pesi)[i][j]=lista->peso;
                 lista=lista->next;
             }
             i++;
         }
     }
    
    grafomatrice.h
    //grafomatrice.h
    
    #ifndef GRAFOMATRICE_H_INCLUDED
    #define GRAFOMATRICE_H_INCLUDED
    
    typedef struct grafomatrice * GrafoMatr;
    
    GrafoMatr creaGrafoMatr(int n);
    GrafoMatr aggiungiVerticeMatr (GrafoMatr M, char val, int i, int n);
    GrafoMatr aggiungiArcoMatr(GrafoMatr M,char curr, char val, float peso);
    int cercaVerticeMatr(char * arrayVertici, char val,int n);
    void stampaGrafoMatr (GrafoMatr M, int n);
    
    void estrapolaMatrice(GrafoMatr M, char **vertici, int ***matrice, float ***pesi);
    GrafoMatr generaGrafoMatr (GrafoMatr M, char *vertici, int ** matrice, float ** peso);
    
    #endif // GRAFOMATRICE_H_INCLUDED
    grafomatrice.c
    #include <stdio.h>
    #include <stdlib.h>
    #include "grafomatrice.h"
    
    typedef struct grafomatrice {
    int numVertici;
    char * vertici; //array di vertici
    char * colore;
    float ** peso; //matrice dei pesi //i pesi non posso metterli al posto dell'1 nella matr adj in quanto nn so come rapp un arco senza peso!
    int ** matrice;
    }grafomatrice;
    
    
    GrafoMatr creaGrafoMatr(int n)
    {
        int i,j;
        GrafoMatr M=(grafomatrice*)malloc(sizeof(grafomatrice));
        M->numVertici=n;
        M->vertici=(char*)malloc((n)*sizeof(char));
        M->colore=(char*)malloc((n)*sizeof(char));
        M->peso=(float**)malloc((n)*sizeof(float*));
        M->matrice=(int**)malloc((n)*sizeof(int*));
        for(i=0;i<n;i++)
        {
            M->vertici[i]=0;
            M->colore[i]='b';
            M->peso[i]=(float*)malloc((n)*sizeof(float));
            M->matrice[i]=(int*)malloc((n)*sizeof(int));
            for(j=0;j<n;j++)
            {
                    M->matrice[i][j]=0;
                    M->peso[i][j]=0.0;
            }
        }
    
        return M;
    }
    
    GrafoMatr aggiungiVerticeMatr (GrafoMatr M, char val, int i, int n)
    {
        if((i<n)&&(M->vertici[i]!=val))
        {
            if(M->vertici[i]==0)
                M->vertici[i]=val;
            else
                return aggiungiVerticeMatr(M,val,i+1,n);
        }
    
        return M;
    }
    
    GrafoMatr aggiungiArcoMatr(GrafoMatr M,char curr, char val, float peso)
    {
    
        int posCurr,posVal;
        int n=M->numVertici;
    
        posCurr=cercaVerticeMatr(M->vertici,curr,n); //esiste sicuramente
        posVal=cercaVerticeMatr(M->vertici,val,n); //potrebbe non esser stato inserito
    
        if(M->vertici[posVal]==0)
            M=aggiungiVerticeMatr(M,val,0,n);
    
        M->matrice[posCurr][posVal]=1;
        M->peso[posCurr][posVal]=peso;
    
        return M;
    }
    
    int cercaVerticeMatr(char * arrayVertici, char val,int n)
    {
        int i=0;
        while(i<n)
        {
            if((arrayVertici[i]==val) || (arrayVertici[i]==0))//se arriva ad una casella vuota vuol dire che non ha trovato altro;
                return i;
            else i++;
        }
    
        return 0;
    }
    
    void stampaGrafoMatr (GrafoMatr M, int n)
    {
        int i,j;
        printf("\n    ");
        for(i=0;i<n;i++) printf("%c ",M->vertici[i]);
        printf("\n\n");
        for(i=0;i<n;i++)
        {
            printf("  %c ",M->vertici[i]);
            for(j=0;j<n;j++)
            {
                if(abs(M->peso[i][j]) > 0) printf("(%.2f)",M->peso[i][j]);
                printf("%d ",M->matrice[i][j]);
            }
    
            printf("\n");
        }
    }
    
    void estrapolaMatrice(GrafoMatr M, char **vertici, int ***matrice, float ***pesi)
    {
        int i,j;
        int n=M->numVertici;
    
        for(i=0;i<n;i++)
        {
            (*vertici)[i]=M->vertici[i];
            for(j=0;j<n;j++)
            {
                (*matrice)[i][j]=M->matrice[i][j];
                (*pesi)[i][j]=M->peso[i][j];
            }
        }
    }
    
    GrafoMatr generaGrafoMatr (GrafoMatr M, char *vertici, int ** matrice, float ** peso)
    {
        printf("sono in genera grafo\n");
    
        M->vertici=vertici;
        M->matrice=matrice;
        M->peso=peso;
    
        return M;
    }
    
Devi accedere o registrarti per scrivere nel forum
49 risposte