Teoria delle liste?

di il
23 risposte

23 Risposte - Pagina 2

  • Re: Teoria delle liste?

    Per poter capire come funziona una lista, e pure scritta in C, devi conoscere:

    1) la sintassi del C
    2) la differenza tra stack e heap
    3) le funzioni di allocazione della memoria
    4) il concetto di puntatore
    5) il concetto di struttura dati
    6) il concetto di collezione
    7) il concetto di operazione su una collezione
    8 ) il concetto di lista. Ed anche qui hai: lista semplice, lista doppiamente lincata, lista circolare

    Ora, onestamente, per arrivare al concetto di lista, devi avere gia' compreso i concetti descritti dal punto 1 al punto 7. In prima aprossimazione sono l'equivalente di 7 lezioni. Oppure 7 capitoli di un libro.

    Vediamo:

    definizione 1)

    una lista e' una struttura dati che puo' essere definita in modo ricorsivo come:

    lista vuota: []
    una struttura dati formata da una testa, contenete un valore, e una coda, rappresentata da una lista: [testa | coda]

    definizione 2)

    una lista e' un particolare tipo di collezione in cui le operazioni hanno la seguente complessita:

    operazione di ricerca: O(n)
    operazione di inserimento in testa: O(1)
    operazione di rimozione dalla testa: O(1)

    inserimento in mezzo/coda: O(n)
    rimozione dal mezzo/dalla coda: O(n) (lista semplice), O(1) (lista doppiamente lincata)

    Ci sono diverse possibili implementazioni, a seconda delle operazioni richieste e delle proprieta' desiderate

    1) lista semplice: ogni nodo ha una struttura del tipo:
    
    template<T>
    struct NodeList {
       T value;
       NodeList *next;
    }
    
    2) lista doppiamente lincata e lista circolare: ogni nodo ha una struttura del tipo:
    
    template<T>
    struct NodeLinkedList {
       T value;
       NodeLinkedList *prev;
       NodeLinkedList *next;
    }
    
    A seconda del tipo di lista, le operazioni vengono implementate in modo opportuno.


    Esempio di programma che usa una lista (semplice) e alloca alcuni nodi:
    
    typedef
    struct NodeList {
       int value;
       NodeList *next;
    } NodeList;
    
    int main (int argc, char** argv)
    {
        NodeList *l = NULL;
        NodeList  *p;
    
       p = (NodeList*)malloc(sizeof(NodeList));
       p->value = 0;
       p->next = NULL;
    
       l = p;
    
       p = (NodeList*)malloc(sizeof(NodeList));
       p->value = 1;
       p->next = NULL;
    
       l->next = p;   
    
       for(p = l; p != NULL; p = p->next)
         if (p->value == 1)
            printf("Trovato 1\n");
    
    }
    
    
    E adesso?

    Ti rendi conto che non e' possibile spiegare il concetto di lista senza avere chiaro tutto quello che ci sta' attorno?
    Non stiamo parlando di una definizione adatta alla casalinga (la lista della spesa), ma per qualcuno che deve saper come implementarla utilizzando un linguaggio di programmazione (in questo caso il C).

    TE TOCCA STUDIA'
  • Re: Teoria delle liste?

    Per la seconda parte della tua domanda:
    
    
    int i = 0;  // variabile di tipo intero
    int *p = NULL;  // puntatore ad un intero
    
    p = &i; // salvo in p l'indirizzo di memoria di i;
    
    *p = 2;  // salvo all'indirizzo di memoria puntata da p il valore 2
    
    Quanto vale 'i'?
    Perche'?
    
    typedef struct S { int i; S *n; } S;
    
    S s, t;
    s.i = 0;
    s.n = NULL;
    
    t.i = 1;
    t.n = NULL;
    
    S *p = NULL;
    
    p = &s;
    p->n = &t;
    
    p->n->i = 3;
    
    
    Quanto vale 's.i'?
    Quanto vale 't.i'?
    Perche'?

    ( e questa e' la versione semplice! )
  • Re: Teoria delle liste?

    Primo es....
    la variabile i vale 0 perchè è stata dichiarata all'inizio... dato che non è sato modificato il valore della variabile i rimane sempre lo stesso!

    secondo es....
    "s.i" e "t.i" dovrebbe vale entrambi 3....
    il motivo secondo me è perchè il puntatore "p" inserisce il dato alla cella di memoria che è puntato, il valore 3...

    credo che sia giusto! almeno spero!
  • Re: Teoria delle liste?

    crc89 ha scritto:


    primo es....
    la variabile i vale 0 perchè è stata dichiarata all'inizio... dato che non è sato modificato il valore della variabile i rimane sempre lo stesso!
    Purtroppo no!

    i vale zero all'inizio. con 'p = &i' si memorizza in 'p' l'indirizzo di 'i' con '*p=2' si va a scrivere all'indirizzo puntato da 'p' il valore 2. Ma poiche' l'indirizzo puntatod a 'p' e' quello di 'i', il risultato e' che 'i' vale 2!

    secondo es....
    "s.i" e "t.i" dovrebbe vale entrambi 3....
    il motivo secondo me è perchè il puntatore "p" inserisce il dato alla cella di memoria che è puntato, il valore 3...

    credo che sia giusto! almeno spero!
    Purtroppo no nemmeno qui'

    's.i' vale 0 e 't.i' vale 3 per lo stesso giochino fatto nell'esempio precedente.
    Ma qui' e' piu' complicato perche':

    'p' contiene l'indirizzo di 's', 'p->n' (che e' equivalente a '(*p).n') contiene l'indirizzo di 't', quindi

    p->n->i equivalente a (*p).n-> i equivalente a (*((*p).n)).i corrisponde a 't.i'

    Come vedi, i concetti sono diversi (nel senso piu' di uno, non di tipo diverso) e vanno compresi.

    Nel primo esempio di codice ci sono le definizioni!

    Per capire bene servirebbero dei diagrammi.
    Sul libro di testo li trovi sicuramente.

    Non sono concetti difficili, ma non puoi sperare di comprenderli saltando a pie' pari tutto quello che ci sta' prima.
    E gli esempi proposti sono mooooooooolto semplici!


    TE TOCCA STUDIA'
  • Re: Teoria delle liste?

    NOOOOOOOOO!!!!!!!

    VA BEH MI TOCCA STUDIARE!!!!!
  • Re: Teoria delle liste?

    Ciao,
    scusate ho una domanda da fare.... credo che sia molto banale, ma vorrei esserne sicuro...
    se io faccio una struttura di questo tipo:

    typedef struct El{
    int dato;
    struct *next;
    }ELEM;

    typedef ELEM *ListaElem;

    e dentro nel main chiedo lo spazio di memoria tramite la malloc per poter creare una lista...
    io ho incontrato varie implementazioni... è la stessa cosa?

    Testa=(ListaDiElem)malloc(sizeof(ElemLista));
    Testa=malloc(sizeof(ElemLista));

    c'è qualche differenza tra le due oppure è la stessa cosa??
    se non sono la stessa cosa, che cosa cambia dal punto di vista logico o concettuale??

    grazie
    crc89
  • Re: Teoria delle liste?

    Veramente non c'è nulla di corretto ...

    Cosa è Testa?

    ListaDiElem non esiste ...

    ElemLista non esiste ...
  • Re: Teoria delle liste?

    crc89 ha scritto:


    ciao,
    scusate ho una domanda da fare.... credo che sia molto banale, ma vorrei esserne sicuro...
    se io faccio una struttura di questo tipo:

    typedef struct El{
    int dato;
    struct *next;
    }ELEM;

    typedef ELEM *ListaElem;

    e dentro nel main chiedo lo spazio di memoria tramite la malloc per poter creare una lista...
    io ho incontrato varie implementazioni... è la stessa cosa?

    Testa=(ListaDiElem)malloc(sizeof(ElemLista));
    Testa=malloc(sizeof(ElemLista));

    c'è qualche differenza tra le due oppure è la stessa cosa??
    se non sono la stessa cosa, che cosa cambia dal punto di vista logico o concettuale??

    grazie
    crc89
    Ci sono diversi errori:
    1) "Testa" non e' definito
    2) "ElemLista" non e' definito
    3) "ListaDiElem" non e' definito
    4) "Testa=(ListaDiElem)malloc(sizeof(ElemLista));" potrebbe essere corretto o sbagliato a seconda di come viene definito "ListaDiElem"
    5) "Testa=malloc(sizeof(ElemLista));", supponendo che "ElemLista" sia definito, e' corretto in C ma non in C++

    Il compilatore C++ fa molti piu' controlli del compilatore C. In generale conviene sempre compilare un'applicazione C utilizzando il compilatore C++. per farlo basta che il file abbia estensione .cpp o .cxx invece che .c .

    Il tuo esempi, corretto, e':
    
    typedef struct El{
    int dato;
    struct *next;
    } ELEM;
    
    typedef ELEM *ListaElem;
    
    ListaElem Test;
    
    Testa = (ListaElem)malloc(sizeof(ELEM));
    Testa = malloc(sizeof(ELEM));
    
  • Re: Teoria delle liste?

    Si scusate ho sbagliato a scrivere le frasi di codice...
    chiedo scusa!!!
    ricapitolando vorrei capire perchè il mio compilatore mi dice che c'è un errore ed io non lo capisco!

    il codice è questo:
    /* Si scriva una funzione che, dato un vettore di N numeri interi, restituisce la lista contenente gli N elementi del vettore; l’elemento di indice 0 va in testa alla lista, ecc. Si scriva la funzione che stampa a terminale i valori contenuti nella lista in ordine inverso rispetto a quello della lista stessa (leggendoli dalla lista, non dal vettore). */
    
    #include <stdio.h>
    #include <stdlib.h>
    #define N 50
    
    typedef struct El{
    	int dato;
    	struct EL *next;
    }ELEM;
    
    typedef ELEM *ListaElem;
    
    ListaElem inserimento (int [],int);
    void inverso (ListaElem);
    
    
    
    int main (int argc,char argv[])
    {
    	ListaElem start=NULL;
    	int vet[N];
    	int i,n;
    	
    	printf("\nQuanti numeri vuoi inserire? max 50\n");
    	scanf("%d",&n);
    	for(i=0;i<n;i++)
    	{	printf("dammi un valore: ");
    		scanf("%d",&vet[i]);
    	}
    	inverso(inserimento(vet,n));
    	return 0;
    }
    
    ListaElem inserimento (int v[],int size)
    {
    	ListaElem Testa;
    	if (size==0)
    		return NULL;
    	Testa=(ListaElem)malloc(sizeof(ELEM));//	Testa=malloc(sizeof(ELEM)); quale dei due?
    	Testa->dato=v[0];
    	Testa->next=inserimento(&v[1],size-1);
    	return Testa;
    
    }
    
    void inverso (ListaElem Lista)
    {
    	if(Lista==NULL)
    		return;
    	inverso(Lista->next);
    	printf("%d",Lista->dato);
    }
    

    il mio complitore dice questo:
    es3.c: In function ‘inserimento’:
    es3.c:42:13: warning: assignment from incompatible pointer type [enabled by default]
    es3.c: In function ‘inverso’:
    es3.c:51:2: warning: passing argument 1 of ‘inverso’ from incompatible pointer type [enabled by default]
    es3.c:47:6: note: expected ‘ListaElem’ but argument is of type ‘struct EL *’
    
    DOMANDA: dove sbaglio?

    grazie
Devi accedere o registrarti per scrivere nel forum
23 risposte