Visualizzazione dei risultati da 1 a 3 su 3
  1. #1
    Utente di HTML.it
    Registrato dal
    Jan 2010
    Messaggi
    211

    C++ grafo con liste delle adiacenze

    ciao a tutti, ho creato la struttura dati grafo con liste delle adiacenze e sembra funzionare tutto, se non per il fatto che nella classe base ho creato un metodo dfs che, dato un grafo, essettua la visita in profondità e ho scoperto che quando vado a connettere tutti i vari nodi del grafo, c'è un nodo con una connessione non prevista.
    il problema non è nel metodo dfs, ma secondo me deve essere nel metodo insarco.
    posto i codici:

    nodogl.h
    codice:
    #ifndef nodogl_h
    #define nodogl_h
    
    #include<iostream>
    #include<stdlib.h>
    #include<string>
    
    using namespace std;
    
    template<class tipoelem>
    class nodogl
    {
       public:
          typedef struct adiacent
          {
             nodogl<tipoelem> adiac;
             int peso;
          } arco;
          nodogl();
          
          void setetichetta(tipoelem);
          void setposizione(int);
          void setadiacent(listap<arco> *);
          
          tipoelem getetichetta();
          int getposizione();
          listap<arco> *getadiacent();
          
          nodogl<tipoelem> operator=(nodogl<tipoelem>);
          bool operator==(nodogl<tipoelem>); 
       private:
          tipoelem etichetta;
          int posizione;
          listap<arco> *adiacent;
    };
    
    #endif
    
    template<class tipoelem>
    nodogl<tipoelem>::nodogl()
    {
       posizione = -1;
       adiacent = NULL;
    }
    
    template<class tipoelem>
    void nodogl<tipoelem>::setetichetta(tipoelem et)
    {
       etichetta = et;
    }
    
    template<class tipoelem>
    void nodogl<tipoelem>::setposizione(int pos)
    {
       posizione = pos;
    }
    
    template<class tipoelem>
    void nodogl<tipoelem>::setadiacent(listap<typename nodogl<tipoelem>::arco> *ad)
    {
       if(adiacent == NULL)
          adiacent = new listap<struct adiacent>;
       adiacent = ad;
    }
    
    template<class tipoelem>
    tipoelem nodogl<tipoelem>::getetichetta()
    {
       return(etichetta);
    }
    
    template<class tipoelem>
    int nodogl<tipoelem>::getposizione()
    {
       return(posizione);
    }
    
    template<class tipoelem>
    listap<typename nodogl<tipoelem>::arco> *nodogl<tipoelem>::getadiacent()
    {
       return(adiacent);
    }
    
    template<class tipoelem>
    nodogl<tipoelem> nodogl<tipoelem>::operator=(nodogl<tipoelem> nodo)
    {
       this->setetichetta(nodo.getetichetta());
       this->setposizione(nodo.getposizione());
       this->setadiacent(nodo.getadiacent());
    }
    
    template<class tipoelem>
    bool nodogl<tipoelem>::operator==(nodogl<tipoelem> nodo)
    {
       bool etic = (this->getetichetta() == nodo.getetichetta());
          
       return(etic);
    }
    grafo.h
    codice:
    #ifndef grafo_h
    #define grafo_h
    
    #include<iostream>
    #include<stdlib.h>
    
    using namespace std;
    
    template<class nodo, class tipoelem>
    class grafo
    {
       public:
          grafo();
       
          virtual void creagrafo() = 0;
          virtual bool grafovuoto() = 0;
          virtual bool esistenodo(nodo &) = 0;
          virtual bool esistearco(nodo, nodo) = 0;
          virtual void insnodo(nodo &) = 0;
          virtual void insarco(nodo &, nodo &) = 0;
          virtual void cancnodo(nodo &) = 0;
          virtual void cancarco(nodo &, nodo &) = 0;
          virtual listap<nodo> adiacenti(nodo &) = 0;
          virtual tipoelem legginodo(nodo) = 0;
          virtual int leggiarco(nodo, nodo) = 0;
          virtual void scrivinodo(nodo &, tipoelem) = 0;
          virtual void scriviarco(nodo, nodo, int) = 0;
          
          void test();
          void dfs(nodo, listap<nodo> &);
       protected:
          int numnodi;
    };
    
    #endif
    
    template<class nodo, class tipoelem>
    grafo<nodo, tipoelem>::grafo()
    {
       numnodi = 0;
    }
    
    template<class nodo, class tipoelem>
    void grafo<nodo, tipoelem>::test()
    {
       cout << "grafovuoto() = " << this->grafovuoto() << "\n\n";
       
       cout << "inserimento di 5 nodi con le seguenti etichette:\n";
       cout << "{1, 2, 3, 4, 5, 6,l 7, 8, 9, 10}\n\n";
       
       for(int i = 1; i <= 10; i++)
       {
          nodo n;
          this->insnodo(n);
       }
       cout << "\n\n";
       
       cout << "controllo sull'esistenza dei nodi 4 e 11:\n";
       nodo k;
       k.setetichetta(4);
       cout << "esistenodo(4) = " << this->esistenodo(k) << "\n";
       k.setetichetta(11);
       cout << "esistenodo(11) = " << this->esistenodo(k) << "\n\n";
       
       cout << "inserimento dei seguenti due archi: (1, 2) e (1, 3):\n";
       nodo j;
       k.setetichetta(1);
       j.setetichetta(2);
       this->insarco(k, j);
       j.setetichetta(3);
       this->insarco(k, j);
       cout << "\n\n";
       
       cout << "controllo sull'esistenza degli archi (1, 3) e (2, 3):\n";
       j.setetichetta(3);
       cout << "esistearco(1, 3) = " << this->esistearco(k, j) << "\n";
       k.setetichetta(2);
       j.setetichetta(3);
       cout << "esistearco(2, 3) = " << this->esistearco(k, j) << "\n\n";
       
       cout << "cancellazione e verifica dell'esistenza del nodo 5:\n";
       k.setetichetta(5);
       cout << "esistenodo(5) = " << this->esistenodo(k) << "\n";
       cout << "cancellazione...\n";
       this->cancnodo(k);
       cout << "esistenodo(5) = " << this->esistenodo(k) << "\n\n";
       
       cout << "cancellazione e verifica dell'esistenza dell'arco (1, 3):\n";
       k.setetichetta(1);
       j.setetichetta(3);
       cout << "esistearco(1, 3) = " << this->esistearco(k, j) << "\n";
       cout << "cancellazione...\n";
       this->cancarco(k, j);
       cout << "esistearco(1, 3) = " << this->esistearco(k, j) << "\n\n";
       
       cout << "creazione e stampa della lista degli adiacenti del nodo 1:\n";
       k.setetichetta(1);
       listap<nodo> L = this->adiacenti(k);
       typename listap<nodo>::posizione p = L.primolista();
       cout << "Ladiacenti = {";
       while(p != L.predlista(L.primolista()))
       {
          cout << L.leggilista(p).getetichetta() << " ";
          p = L.suclista(p);
       }
       cout << "}\n\n";
       
       cout << "inserimento e visualizzazione dell' etichetta 11 nel nodo con etichetta 1:\n";
       this->scrivinodo(k, 11);
       cout << "valore del nodo = " << this->legginodo(k) << "\n";
       this->scrivinodo(k, 1);
       cout << "valore del nodo = " << this->legginodo(k) << "\n\n";
       
       cout << "inserimento e visualizzazione del peso 11 nell'arco (1, 2):\n";
       j.setetichetta(2);
       esistenodo(j);
       this->scriviarco(k, j, 11);
       cout << "peso dell'arco (1, 2) = " << this->leggiarco(k, j) << "\n\n";
       
       cout << "connessione del grafo, ai fini delle visite, con i seguenti archi:\n";
       cout << "(1, 5), (1, 8), (2, 3), (4, 1), (4, 8), (5, 6), (6, 2), (6, 3), (6, 7),\n";
       cout << "(6, 9), (8, 5), (8, 9), (9, 10), (10, 7)\n";
       k.setetichetta(1);
       this->esistenodo(k);
       j.setetichetta(2);
       this->esistenodo(j);
       this->cancarco(k, j);
       k.setetichetta(5);
       cout << "\n";
       this->insnodo(k);
       bool fine = false;
       while(!fine)
       {
          nodo m;
          nodo n;
          cout << "digitare l'etichetta del primo nodo dell'arco: ";
          tipoelem etic;
          cin >> etic;
          m.setetichetta(etic);
          this->esistenodo(m);
          cout << "digitare l'etichetta del secondo nodo dell'arco: ";
          etic;
          cin >> etic;
          n.setetichetta(etic);
          this->esistenodo(n);
          this->insarco(m, n);
          cout << "fine (0. no, 1. si)? ";
          cin >> fine;
       }   
    }
    
    template<class nodo, class tipoelem>
    void grafo<nodo, tipoelem>::dfs(nodo n, listap<nodo> &visitati)
    {
       listap<nodo> adiacents = this->adiacenti(n);
       typename listap<nodo>::posizione padiac = adiacents.primolista();
       cout << "\nad(" << n.getetichetta() << ") = {";
       while(padiac != adiacents.predlista(adiacents.primolista()))
       {
          cout << adiacents.leggilista(padiac).getetichetta() << " ";
          padiac = adiacents.suclista(padiac);
       }
       cout << "}\n\n";
       system("pause");
       padiac = adiacents.primolista();
       
       cout << n.getetichetta() << " ";
       visitati.inslista(visitati.predlista(visitati.primolista()), n);
       n = adiacents.leggilista(padiac);
       this->esistenodo(n);
       typename listap<nodo>::posizione pvisit;
       while(padiac != adiacents.predlista(adiacents.primolista()))
       {
          pvisit = visitati.primolista();
          bool presente = false;
          while(!presente && (pvisit != visitati.predlista(visitati.primolista())))
          {
             if(n.getetichetta() == visitati.leggilista(pvisit).getetichetta())
                presente = true;
             else
                pvisit = visitati.suclista(pvisit);
          }
          if(!presente)
             dfs(n, visitati);
          padiac = adiacents.suclista(padiac);
          n = adiacents.leggilista(padiac);
          this->esistenodo(n);
       }
    }
    --->continua

  2. #2
    Utente di HTML.it
    Registrato dal
    Jan 2010
    Messaggi
    211
    grafola.h
    codice:
    #ifndef grafolla_h
    #define grafolla_h
    
    #include<iostream>
    #include<stdlib.h>
    #include<assert.h>
    
    using namespace std;
    
    template<class tipoelem>
    class grafolla : public grafo<nodogl<tipoelem> , tipoelem>
    {
       public:
          typedef nodogl<tipoelem> nodo;
                
          grafolla();
          
          void creagrafo();
          bool grafovuoto();
          void insnodo(nodo &);
          void insarco(nodo &, nodo &);
          void cancnodo(nodo &);
          void cancarco(nodo &, nodo &);
          listap<nodo> adiacenti(nodo &);
          bool esistenodo(nodo &);
          bool esistearco(nodo, nodo);
          tipoelem legginodo(nodo);
          void scrivinodo(nodo &, tipoelem);
          int leggiarco(nodo, nodo);
          void scriviarco(nodo, nodo, int);
       private:
          nodogl<tipoelem> *nodi;
    };
    
    #endif
    
    template<class tipoelem>
    grafolla<tipoelem>::grafolla()
    {
       this->creagrafo();
    }
    
    template<class tipoelem>
    void grafolla<tipoelem>::creagrafo()
    {
       nodi = new nodogl<tipoelem>[grafo<nodogl<tipoelem>, tipoelem>::numnodi + 1];
    }
    
    template<class tipoelem>
    bool grafolla<tipoelem>::grafovuoto()
    {
       return(grafo<nodogl<tipoelem>, tipoelem>::numnodi == 0);
    }
    
    template<class tipoelem>
    void grafolla<tipoelem>::insnodo(typename grafolla<tipoelem>::nodo &node)
    {
       cout << "inserire l'etichetta del nodo: ";
       tipoelem c;
       cin >> c;
       node.setetichetta(c);
       
       assert(!this->esistenodo(node));
    
       node.setposizione(grafo<nodogl<tipoelem>, tipoelem>::numnodi);
       nodogl<tipoelem> *noditmp = new nodogl<tipoelem>[grafo<nodogl<tipoelem>, tipoelem>::numnodi + 1];
       
       if(grafo<nodogl<tipoelem>, tipoelem>::numnodi >= 1) 
       { 
          for(int i = 0; i < grafo<nodogl<tipoelem>, tipoelem>::numnodi; i++)
             noditmp[i] = nodi[i];
       }
       noditmp[grafo<nodogl<tipoelem>, tipoelem>::numnodi] = node; 
       nodi = noditmp;
       noditmp = NULL;
       grafo<nodogl<tipoelem>, tipoelem>::numnodi++;
    }  
    
    template<class tipoelem>
    void grafolla<tipoelem>::insarco(typename grafolla<tipoelem>::nodo &n1, typename grafolla<tipoelem>::nodo &n2)
    {
       assert(this->esistenodo(n1) && this->esistenodo(n2) && !this->esistearco(n1, n2));
       
       typename nodogl<tipoelem>::arco a;
       a.adiac.setetichetta(n2.getetichetta());
       a.adiac.setposizione(n2.getposizione());
       a.peso = 0;
       if(nodi[n1.getposizione()].getadiacent() == NULL)
       {
          listap<typename nodogl<tipoelem>::arco> *k = new listap<typename nodogl<tipoelem>::arco>;
          nodi[n1.getposizione()].setadiacent(k);
          
       }
       listap<typename nodogl<tipoelem>::arco> *l = nodi[n1.getposizione()].getadiacent();
       l->inslista(l->predlista(l->primolista()), a);   
    }
    
    template<class tipoelem>
    void grafolla<tipoelem>::cancnodo(typename grafolla<tipoelem>::nodo &node)
    {
       assert(this->esistenodo(node));
       
       //eliminazione degli archi (adiacenze) uscenti
       if(node.getadiacent() != NULL)
       {
          listap<typename nodogl<tipoelem>::arco> *l = nodi[node.getposizione()].getadiacent();
          while(!l->listavuota())
             l->canclista(l->primolista());
       }
           
       //eliminazione degli archi (adiacenze) entranti
       for(int k = 0; k < grafo<nodogl<tipoelem>, tipoelem>::numnodi; k++)
       {
          if(this->esistearco(nodi[k], node))
             this->cancarco(nodi[k], node);
          k++;
       }
       
       //modifica del vettore dei nodi
       nodo *noditmp = new nodogl<tipoelem>[grafo<nodogl<tipoelem>, tipoelem>::numnodi - 1];
       int i = node.getposizione();
       for(int j = 0; j < i; j++)  
            noditmp[j] = nodi[j];
          
       for(int j = i; j < (grafo<nodogl<tipoelem>, tipoelem>::numnodi - 1); j++)
       {
          noditmp[j] = nodi[j + 1];
          noditmp[j].setposizione(nodi[j + 1].getposizione() - 1);
       }
       
       nodi = noditmp;
       noditmp = NULL;
       
       grafo<nodogl<tipoelem>, tipoelem>::numnodi--;
    }
    
    template<class tipoelem>
    void grafolla<tipoelem>::cancarco(typename grafolla<tipoelem>::nodo &n1, typename grafolla<tipoelem>::nodo &n2)
    {
       assert(this->esistenodo(n1) && this->esistenodo(n2) && this->esistearco(n1, n2));
       
       if(nodi[n1.getposizione()].getadiacent() != NULL)
       {
          listap<typename nodogl<tipoelem>::arco> *l = nodi[n1.getposizione()].getadiacent();
          typename listap<typename nodogl<tipoelem>::arco>::posizione p = l->primolista();
          bool trovato = false;
          while(!trovato && (p != l->predlista(l->primolista())))
          {
             if(l->leggilista(p).adiac.getetichetta() == nodi[n2.getposizione()].getetichetta())
             {
                l->canclista(p);
                trovato = true;
             }
             else
                p = l->suclista(p);
          }
       }
    }
    
    template<class tipoelem>
    listap<typename grafolla<tipoelem>::nodo> grafolla<tipoelem>::adiacenti(typename grafolla<tipoelem>::nodo &node)
    {
       assert(this->esistenodo(node));
       
       listap<nodogl<tipoelem> > lis;
       if(!nodi[node.getposizione()].getadiacent()->listavuota() && (nodi[node.getposizione()].getadiacent() != NULL))
       {
          listap<typename nodogl<tipoelem>::arco> *l = nodi[node.getposizione()].getadiacent();
          typename listap<typename nodogl<tipoelem>::arco>::posizione p = l->primolista();
          while(p != l->predlista(l->primolista()))
          {
             nodogl<tipoelem> n = l->leggilista(p).adiac;
             this->esistenodo(n);
             lis.inslista(lis.predlista(lis.primolista()), n);
             p = l->suclista(p);
          }
       }
       
       return lis;
    }
    
    template<class tipoelem>
    bool grafolla<tipoelem>::esistenodo(typename grafolla<tipoelem>::nodo &node)
    {
       bool esito = false;
       int i = 0;
       while(!esito && (i < grafo<nodogl<tipoelem>, tipoelem>::numnodi))
       {
          if(nodi[i].getetichetta() == node.getetichetta())
          {
             esito = true;
             node = nodi[i];
          }
          else
             i++;
       }
       return esito;
    }
    
    template<class tipoelem>
    bool grafolla<tipoelem>::esistearco(typename grafolla<tipoelem>::nodo n1, typename grafolla<tipoelem>::nodo n2)
    {
       assert(this->esistenodo(n1) && this->esistenodo(n2));
       
       bool trovato = false;
       if(nodi[n1.getposizione()].getadiacent() != NULL)
       {
          listap<typename nodogl<tipoelem>::arco> *l = nodi[n1.getposizione()].getadiacent();
          typename listap<typename nodogl<tipoelem>::arco>::posizione p = l->primolista();
       
          while(!trovato && (p != l->predlista(l->primolista())))
          {
             if(l->leggilista(p).adiac.getetichetta() == nodi[n2.getposizione()].getetichetta())
                trovato = true;
             else
                p = l->suclista(p);
          }
       }
       
       return trovato;
    }
    
    template<class tipoelem>
    tipoelem grafolla<tipoelem>::legginodo(typename grafolla<tipoelem>::nodo node)
    {
       assert(this->esistenodo(node));
       
       return(nodi[node.getposizione()].getetichetta());
    }
    
    template<class tipoelem>
    void grafolla<tipoelem>::scrivinodo(typename grafolla<tipoelem>::nodo &node, tipoelem elem)
    {
       assert(this->esistenodo(node));
       node.setetichetta(elem);
       nodi[node.getposizione()] = node;
    }
    
    template<class tipoelem>
    int grafolla<tipoelem>::leggiarco(typename grafolla<tipoelem>::nodo n1, typename grafolla<tipoelem>::nodo n2)
    {
       assert(this->esistearco(n1, n2));
       
       listap<typename nodogl<tipoelem>::arco> *l = nodi[n1.getposizione()].getadiacent();
       typename listap<typename nodogl<tipoelem>::arco>::posizione p = l->primolista();
       bool trovato = false;
       while(!trovato && (p != l->predlista(l->primolista())))
       {
          if(l->leggilista(p).adiac.getetichetta() == n2.getetichetta())
             trovato = true;
          else
             p = l->suclista(p);
       }
       
       return(l->leggilista(p).peso);
    }
    
    template<class tipoelem>
    void grafolla<tipoelem>::scriviarco(typename grafolla<tipoelem>::nodo n1, typename grafolla<tipoelem>::nodo n2, int pes)
    {
       assert(this->esistearco(n1, n2));
       
       listap<typename nodogl<tipoelem>::arco> *l = nodi[n1.getposizione()].getadiacent();
       typename listap<typename nodogl<tipoelem>::arco>::posizione p = l->primolista();
       bool trovato = false;
       while(!trovato && (p != l->predlista(l->primolista())))
       {
          if(l->leggilista(p).adiac.getetichetta() == n2.getetichetta())
          {
             typename nodogl<tipoelem>::arco n = l->leggilista(p);
             n.peso = pes;
             l->scrivilista(p, n);
             trovato = true;
          }
          else
             p = l->suclista(p);
       }
    }
    testgrafi.cpp
    codice:
    #include<iostream>
    #include<stdlib.h>
    #include "listap.h"
    #include "nodog.h"
    #include "nodogl.h"
    #include "grafo.h"
    #include "grafoma.h"
    #include "grafolla.h"
    
    using namespace std;
    
    int main()
    {
       /*cout << "                ***test grafo con matrice delle adiacenze***\n\n";
       grafoma<int> G1;
       G1.test();
       listap<nodog<int> > visit;
       nodog<int> n1;
       n1.setetichetta(4);
       G1.esistenodo(n1);
       cout << "dfs del grafo iniziando dal nodo con etichetta 4:\n";
       G1.dfs(n1, visit);
       system("pause");
       system("cls");*/
       
       cout << "                ***test grafo con lista delle adiacenze***\n\n";
       grafolla<int> G2;
       G2.test();
       listap<nodogl<int> > visit2;
       nodogl<int> n2;
       //G2.esistenodo(n2);
       n2.setetichetta(4);
       cout << "dfs del grafo iniziando dal nodo con etichetta 4:\n";
       G2.dfs(n2, visit2);
       
       system("pause");
       return 0;
    }
    in pratica nel metodo dfs, c'è la lista delle adiacenze per ogni nodo e ho scoperto che la lista delle adiacenze del nodo con etichetta 1 contiene il nodo 6, arco che io non ho mai inserito. dove avviene l'inserimente di questo arco non previsto? non riesco a capirlo.
    vi prego aiutatemi.

  3. #3
    Utente di HTML.it
    Registrato dal
    Jan 2010
    Messaggi
    211
    il problema dell'arco indesiderato l'ho risolto. adesso sorge un altro problema:
    quando faccio la visita in profondità (dfs), appena si arriva a considerare un nodo privo di adiacenti (lista delle adiacenze vuota) l'esecuzione va in crash. perchè???

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.