Le strutture informative Corso di Informatica 2 Informatica 2 - Strutture Dati Che cos’è una struttura dati? modo sistematico di rappresentare ed Struttura dati = organizzare dati 0010011010010111 numero intero rappr. in binario a f k z q d i w vettore Informatica 2 - Strutture Dati Come rappresentare collezioni? Una soluzione è il vettore: dim − 1 0 v proxlibero v dim proxlibero array Informatica 2 - Strutture Dati 1 Come rappresentare collezioni? Una soluzione è il vettore: struct VettRec { int dim, proxlibero; T *array; v }; dim typedef VettRec* Vettore; proxlibero array Informatica 2 - Strutture Dati I record Un record è una tupla di valori di tipi possibilmente diversi acceduti attraverso etichette: struct <nome struttura> { <tipo1> <etichetta campo1>; ... <tipok> <etichetta campok>; } Informatica 2 - Strutture Dati I record struct puntocolorato { int x, y; // coord. sullo schermo Colore c; // tipo enumerato } ... struct puntocolorato p; p.x = 44; p.y = 12; p.c = rosso; selettore del campo Informatica 2 - Strutture Dati 2 Allocazione di un Vettore Tutte queste istruzioni debbono essere ripetute per ciascun nuovo vettore Vettore NuovoVettore (int dim) { Vettore v = new VettRec; v->dim = dim; v->proxlibero = 0; v->array = new T[dim]; return v; } Informatica 2 - Strutture Dati Uso di un Vettore Vettore A = NuovoVettore(10) // A potrà contenere al più 10 el. // supponendo che T == int, aggiungiamo // un intero alla collezione A if (A->proxlibero < A->dim) A->array[v->proxlibero++] = 7; A->array[i] abbrevia(*A).array[i] ecc. Per accedere ad A bisogna ricordare molte cose Informatica 2 - Strutture Dati Uso di un Vettore void Aggiungi (Vettore v, T valore) // Pre: in v c’è posto per un nuovo // valore // Post: aggiunge valore a quelli in v { } v->array[v->proxlibero++] = valore; bool VettorePieno (Vettore v) // Post: ritorna true sse v è pieno { return v->proxlibero == v->dim; } Informatica 2 - Strutture Dati 3 Uso di un Vettore Vettore A = NuovoVettore(10) // A potrà contenere al più 10 el. // supponendo che T == int, aggiungiamo // un intero alla collezione A if (!VettorePieno(A)) Aggiungi(A,7); Codice che non richiede la conoscenza della realizzazione Informatica 2 - Strutture Dati Deallocazione • La memoria dinamica allocata può essere recuperata usando la funzione delete: delete <puntatore> • Per deallocare un vettore non occorre ricordarne la dimensione: delete [] <nome vettore> • Per deallocare una struttura complessa occorrono tante chiamate di delete quante sono state quelle di new Informatica 2 - Strutture Dati Deallocazione di un Vettore void DeallocaVettore (Vettore v) { delete [] v->array; // dealloca il vettore dei valori delete v; // dealloca il record di accesso } Informatica 2 - Strutture Dati 4 Un esempio più complesso: matrici struct MatrRec { int righe, colonne; T **vecrighe; }; typedef MatrRec* Matrice; n m m 64748 n Informatica 2 - Strutture Dati Un esempio più complesso: matrici Matrice NuovaMatrice (int r, int c) { Matrice m; m = new MatrRec; m->righe = r; m->colonne = c; m->vecrighe = new int*[r]; for (int i = 0; i < r; i++) m->vecrighe[i] = new T[c]; return m; } Informatica 2 - Strutture Dati Deallocazione di Matrice void DeallocaMatrice (Matrice m) { for(int i = 0; i < m->righe; i++) delete [] m->vecrighe[i]; delete [] m->vecrighe; delete m; } Informatica 2 - Strutture Dati 5 Le liste Come struttura dati una lista è una sequenza di record, ciscuno dei quali contiene un campo che punta al successivo: info next l 2 5 9 1 ∅ Informatica 2 - Strutture Dati Le liste struct Nodo { T info; Lista next; Lista è ricorsivo }; typedef Nodo* Lista; l 2 5 9 1 ∅ Informatica 2 - Strutture Dati La funzione Cons Lista Cons (T x, Lista l) { Lista nl = new Nodo; nl->info = x; nl->next = l; return nl; Cons è un allocatore } Cons(4, l ) 4 l 2 5 9 1 ∅ Informatica 2 - Strutture Dati 6 Le funzioni Head e Tail T Head (Lista l) // Pre: l non è vuota { Può essere un L-value return l->info; } Lista& Tail (Lista l) // Pre: l non è vuota { return l->next; l Tail(l ) Head(l ) = 2 2 } … 5 Informatica 2 - Strutture Dati La lista vuota bool ListaVuota (Lista l) { … return l == NULL; 5 ∅ } Al fondo di ogni lista c’è la lista vuota, ossia un puntatore a NULL void StampaLista (Lista l) { while (!ListaVuota(l)) { cout << Head(l) << " "; l = Tail(l); } } Informatica 2 - Strutture Dati Inserimento in una lista Cons(x,p->next); x p Informatica 2 - Strutture Dati 7 Inserimento in una lista p->next = Cons(x,p->next); x L’inserimento è O(1) posto che si conosca p p Informatica 2 - Strutture Dati Inserimento iterativo void Inserimento (T x, int i, Lista& l) // Pre: 1 <= i <= lunghezza(l) + 1 // Post: inserisce x in l come i-esimo el. { effetto collaterale if (i == 1) l = Cons(x, l); else // 1 < i <= lunghezza(l) + 1 { int j = 1; Lista p = l; while (j < i-1 && p != NULL) Se p è da cercare allora l’inserimento è O(n) // inv. p punta al j-esimo el. di l { j++; p = Tail(p);} if (p != NULL) // allora j == i-1, Tail(p) = Cons(x, Tail(p)); } } Informatica 2 - Strutture Dati Un metodo ricorsivo Lista InsRic (T x, int i, Lista l) // Pre: 1 <= i <= lunghezza(l) + 1 // Post: inserisce x in l come i-esimo el. { if (i == 1) return Cons(x, l); else { Tail(l) = InsRic (x, i-1, Tail(l)); return l; } } Informatica 2 - Strutture Dati 8 Cancellazione da una lista temp = p->next; p->next = p->next->next p Informatica 2 - Strutture Dati Cancellazione da una lista delete temp; temp p Informatica 2 - Strutture Dati Liste bidirezionali Realizzazione di liste bidirezionali con sentinella (liste doppie) sentinella ∅ info 1 12 pred 7 3 ∅ next L Informatica 2 - Strutture Dati 9 Liste bidirezionali Realizzazione di liste bidirezionali circolari con sentinella (liste doppie circolari) 1 12 7 3 L Informatica 2 - Strutture Dati Inserimento in una lista 1 12 p Se la posizione è implementata con un puntatore allora Insert(a, L, p) è O(1) 7 q temp = p->next p->next = q, q->pred = p temp->pred = q, q->next = temp Informatica 2 - Strutture Dati Inserimento in una lista 1 12 p 7 Se invece p = posi è un indice allora Insert(a, L, p) è O(n) !! q temp = p->next p->next = q, q->pred = p temp->pred = q, q->next = temp Informatica 2 - Strutture Dati 10 Inserimento in una lista sentinella 12 p L’inserimento avviene in modo uniforme al principio … 7 q temp = p->next p->next = q, q->pred = p temp->pred = q, q->next = temp Informatica 2 - Strutture Dati Inserimento in una lista … 12 7 p temp punta alla sentinella q … come alla fine della lista temp = p->next p->next = q, q->pred = p temp->pred = q, q->next = temp Informatica 2 - Strutture Dati Cancellazione da una lista 1 12 7 p temp = p->next; p->next = p->next->next; p->next->pred = p; delete temp; • Delete(L, p) è O(1) se p è un puntatore, O(n) se è un indice • la cancellazione è uniforme all’inizio ed alla fine della lista Informatica 2 - Strutture Dati 11 La lista vuota Nel caso della lista doppia con sentinella, il valore nil non è un puntatore NULL: L bool IsEmpty? (Lista l) { return l->next == l; // L punta alla sentinella } Informatica 2 - Strutture Dati 12