Rappresentazione di liste mediante puntatori in linguaggio C

Похожие документы
Strutture dati dinamiche in C (II)

Laboratorio di Programmazione

Programmazione I - Laboratorio

Inserimento in una lista ordinata

Strutture Dinamiche. Fondamenti di Informatica

4 Le liste collegate 4.0. Le liste collegate. 4 Le liste collegate Rappresentazione di liste 4.1 Rappresentazione di liste

La struttura dati CODA

PILE E CODE. Pile (stack):

Informatica 1. Prova di recupero 21 Settembre 2001

Hash Table. Hash Table

Struttura dati astratta Coda

Implementazione di Liste puntate

Laboratorio di Informatica

Il linguaggio C. Puntatori e dintorni

Linguaggio C. Esercizio 1

LE STRUTTURE DATI DINAMICHE: GLI ALBERI. Cosimo Laneve

Esercizi Strutture dati di tipo astratto

Le liste. ADT e strutture dati per la rappresentazione di sequenze. Ugo de' Liguoro - Algoritmi e Sperimentazioni 03/04 - Lez. 5

Alberi ed Alberi Binari

Questa soluzione va contemplata quando le lunghezze stimate dalle liste usate sono significativamente maggiori delle dimensioni di un elemento.

Esercizio 1: funzione con valore di ritorno di tipo puntatore

Esercizi su programmazione ricorsiva 1. Pericle Perazzo 23 marzo 2012

Per semplicità eliminiamo le ripetizioni nell'albero.

Lezione 8 Struct e qsort

Una funzione è detta ricorsiva se chiama, direttamente o indirettamente, se stessa. In C tutte le funzioni possono essere usate ricorsivamente.

Linguaggi di programmazione + laboratorio a.a. 2012/2013

Lezione 12 Tabelle Hash

Algoritmi e Strutture Dati

Alberi e alberi binari I Un albero è un caso particolare di grafo

Corso di Informatica 1 (IN1) Tutorato n. 11

Heap e code di priorità

ARRAY E STRINGHE. ESERCIZIO 2 Scrivere un programma che calcola il numero di doppie e di dittonghi (2 vocali vicine) presenti in una stringa.

I PUNTATORI E LE STRUTTURE DATI DINAMICHE. Cosimo Laneve/Ivan Lanese

PUNTATORI A STRUTTURE

Alberi binari e alberi binari di ricerca

Introduzione al linguaggio C Puntatori

Liste con sentinella. intlist *createlist(void){ intlist *q = malloc(sizeof(intlist)); if(!q) { exit(-1); } q->next = q->prev = q; return q; }

Esercitazione 12. Esercizi di Ricapitolazione

Alberi Binari di Ricerca

Esercizi. Stringhe. Stringhe Ricerca binaria

Esercizio 1: Puntatori impiegati che sono manager

Puntatori a Funzioni e Callback. Massimo Benerecetti

Lezione 9 Alberi binari di ricerca

Lezione 9: Strutture e allocazione dinamica della memoria

Esercizio 2 (punti 7) Dato il seguente programma C: #include <stdio.h> int swap(int * nome, int length);

Alberi. Gli alberi sono una generalizzazione delle liste che consente di modellare delle strutture gerarchiche come questa: Largo. Fosco.

Indice PARTE A. Prefazione Gli Autori Ringraziamenti dell Editore La storia del C. Capitolo 1 Computer 1. Capitolo 2 Sistemi operativi 21 XVII XXIX

Esercizi Capitolo 10 - Code con priorità e insiemi disgiunti

Linguaggio C: PUNTATORI

FONDAMENTI DI INFORMATICA

Laboratorio di Calcolatori 1 Corso di Laurea in Fisica A.A. 2006/2007

Appello di Informatica B

Esercitazione 6. Alberi binari di ricerca

Programmazione Ricorsione

Algoritmi di ordinamento: Array e ricorsione

Laboratorio di Algoritmi e Strutture Dati. Aniello Murano. people.na.infn.it/~murano/ Murano Aniello - Lab. di ASD Terza Lezione

I puntatori e l allocazione dinamica di memoria. Esercizi risolti

Grafi: visita generica

Esercizio 1 Liste: calcolo perimetro di un poligono

Транскрипт:

Rappresentazione di liste mediante puntatori in linguaggio C Specifica del tipo degli elementi typedef... TipoElemLista; struct StructLista TipoElemLista key; struct StructLista *next; ; typedef struct StructLista TipoNodoLista; typedef TipoNodoLista *TipoLista; key contiene l elemento della lista next contiene il puntatore alla struttura che rappresenta l elemento successivo Una lista vuota è rappresentata dal puntatore NULL, una lista non vuota è rappresentata dal puntatore al suo elemento iniziale Eserc-III-19

Implementazione di operazioni elementari Inizializzazione (la variabile lis è un puntatore doppio) void InitLista(TipoLista *lis) *lis = NULL; Inserimento di un elemento in testa /* pseudo-code like */ TipoLista Inserisci(TipoLista lis, TipoLista nodo) nodo->next = lis; return nodo; /*free-style */ void InserisciTestaLista(TipoLista *lis, TipoElemLista elem) TipoLista paux; paux = malloc(sizeof(tiponodolista)); paux->key = elem; paux->next = *lis; *lis = paux; Eserc-III-20

Implementazione di operazioni elementari Inserimento di un elemento in testa non distruttivo TipoLista InserisciTestaListaND(TipoLista *lis, TipoElemLista elem) TipoLista paux; paux = malloc(sizeof(tiponodolista)); paux->info = elem; paux->next = *lis; return paux; Test di lista vuota bool TestListaVuota(TipoLista lis) return (lis == NULL); Restituzione dell elemento in testa void TestaLista(TipoLista lis, TipoElemLista *elem) if (lis!= NULL) *elem = lis->info; Eserc-III-21

Resto e Resto non distruttivo Implementazione di operazioni elementari void RestoLista(TipoLista *lis) if (*lis!= NULL) *lis = (*lis)->next; TipoLista RestoListaND(TipoLista *lis) TipoLista paux; if (*lis!= NULL) paux = (*lis)->next; else paux = NULL; return paux; Eserc-III-22

Rimozione del primo elemento Implementazione di operazioni elementari void CancellaPrimoLista(TipoLista *lis) TipoLista paux; if (*lis!= NULL) paux = *lis; *lis = (*lis)->next; free(paux); Tutte le funzioni distruttive modificano la lista su cui operiamo e quindi per mantenere una lista integra operiamo su una copia Esigenze del problema sono determinanti Eserc-III-23

Copia lista Provate a farla per esercizio. Funzioni supplementari void CopiaLista(TipoLista lis, TipoLista *copia); Inserire in coda e stampare in ordine inverso void InserisciCodaLista(TipoLista *lis, TipoElemLista elem) TipoLista ultimo; TipoLista paux; paux = malloc(sizeof(tiponodolista)); paux->info = elem; paux->next = NULL; if (*lis == NULL) *lis = paux; else ultimo = *lis; while (ultimo->next!= NULL) ultimo = ultimo->next; ultimo->next = paux; Eserc-III-24

void StampaListaInversaRic(TipoLista lis) TipoLista suc; suc = lis; if (suc!= NULL) TipoElemLista x; x = suc->info; suc = (suc)->next; StampaListaInversaRic(&suc); printf(" %d ",x); Calcola la lunghezza di una lista (Fate la versione ricorsiva per esercizio) int LunghezzaLista(TipoLista lis) int length=0; TipoLista papp=lis; while (papp!= NULL) length++; papp = papp->next; return length; Eserc-III-25

Reverse ricorsivo void List_Invert_Ric(TipoLista *lis) TipoLista papp; if (*lis!= NULL) int appo = (*lis)->info; RestoLista(lis); List_Invert_Ric(lis); InserisciCodaLista(lis, appo); La lista viene distrutta e ricostruita. Non è necessario lavorare su una copia. IN GENERALE: Uso della ricorsione è più semplice da un punto di vista concettuale Eserc-III-26

Esercizio Date n liste collegate contenenti m interi distinti e un intero x, scrivere lo pseudo-codice di una funzione che conta le occorrenze di x nelle n liste. Strutture dati utilizzate: Una lista L che contiene i puntatori alle n liste e n liste contenenti gli m interi. L algoritmo prevede che: PROBLEMA(L,x) occ <- 0 conto le occorrenze nelle singole liste e le sommo in occ ritorno il valore della variabile occ Devo scorrere L e per ogni suo elemento conto le occorrenze di x nella lista corrispondente PROBLEMA(L,x) occ <- 0 WHILE (L <> NIL) occ <- occ + (calcolo le occorrenze di x nella lista puntata dall elemento corrente di L) L <- NEXT[L] ritorno il valore della variabile occ Eserc-III-27

Esercizio mi serve una funzione che conti le occorrenze di x in una lista di interi CALCOLAOCCORRENZE(L,x) cont <- 0 WHILE (L <> NIL) IF (INFO[L] = x) THEN cont <- cont + 1 L <- NEXT[L] RETURN cont quindi lo pseudo-codice di PROBLEMA diventa: PROBLEMA(L,x) occ <- 0 WHILE (L <> NIL) occ <- occ + CALCOLAOCCORRENZE(PINFO[L],x) L <- NEXT[L] RETURN occ Eserc-III-28

Variazione sul tema Se le n liste fossero ordinate (<), avremmo modo di rendere più efficiente il nostro algoritmo? Se si, come? Eserc-III-29

Variazione sul tema Se le n liste fossero ordinate (<), avremmo modo di rendere più efficiente il nostro algoritmo? Se si, come? Sapendo che gli interi sono ordinati possiamo aggiungere una condizione alla ricerca in CALCO- LAOCCORRENZE: se l elemento da valutare è maggiore di quello che cerchiamo èinutileproseguireacercare. In pseudo-codice: CALCOLAOCCORRENZE(L,x) cont <- 0 WHILE (L <> NIL AND INFO[L] <= x) IF (INFO[L] = x) THEN cont <- cont + 1 L <- NEXT[L] RETURN cont Eserc-III-30

Codifica C Innanzitutto dobbiamo pensare alle strutture per le liste. Per le liste di interi sappiamo come fare: typedef int TipoElemLista; struct StructLista TipoElemLista info; struct StructLista *next; ; typedef struct StructLista TipoNodoLista; typedef TipoNodoLista *TipoLista; Per la lista L dobbiamo ridefinire le strutture, sfruttando sempre la definizione generica typedef TipoLista ptipoelemlista; struct pstructlista TipoLista pinfo; struct pstructlista *pnext; ; typedef struct pstructlista ptiponodolista; typedef ptiponodolista *ptipolista; Eserc-III-31

int calcolaocc(tipolista l, int val) int cont = 0; Codifica C - Liste ordinate while ((l!= NULL) && (l->info <= val)) if (l->info == val) cont++; l = l->next; return cont; int Problema(pTipoLista L, int val) int occorrenze = 0; while (L!= NULL) occorrenze = occorrenze + calcolaocc(l->pinfo,val); L = L->pnext; return occorrenze; Eserc-III-32

Funzione principale Per usare le funzioni appena definite, scriviamo lo pseudo-codice per la creazione di n liste di m interi e quindi traduciamolo in codice C. funzione(n,m,x) pinitlista(l) FOR I = 1 TO N InitLista(APP) FOR J = 1 TO M ;;LEGGI DA TASTIERA UN INTERO (VAL) INSERISCITESTALISTA(APP,VAL) PINSERISCITESTALISTA(L,APP) RISULTATO <- Problema(L,X) INSERISCITESTALISTA e PINSERISCITESTALISTA eseguono la stessa operazione di inserimento, ma su tipi di dato differente Eserc-III-33

funzione(int n, int m,int x) ptipolista plista1,papp; int i,j,res; pinitlista(&plista1); for(i=0;i<n;i++) TipoLista app; InitLista(&app); for (j=0;j<m;j++) int val; Funzione principale in C printf("inserisci elem in lista %d ",(i+1)); scanf("%d",&val); InserisciTestaLista(&app,val); pinseriscitestalista(&plista1,app); printf("%d è presente %d volte\n",x,problema(plista1,x)); Modificare lo pseudo-codice della generazione delle liste nel caso in cui n e m non siano noti a priori. Eserc-III-34