PROGRAMMAZIONE AVANZATA JAVA E C. Massimiliano Redolfi. Lezione 7: Code, Stack, Liste PAJC. Ricerca. prof. Massimiliano Redolfi PAJC



Documenti analoghi
Il tipo di dato astratto Pila

Strutture. Strutture e Unioni. Definizione di strutture (2) Definizione di strutture (1)

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

Gli array. Gli array. Gli array. Classi di memorizzazione per array. Inizializzazione esplicita degli array. Array e puntatori

Informatica 3. LEZIONE 21: Ricerca su liste e tecniche di hashing. Modulo 1: Algoritmi sequenziali e basati su liste Modulo 2: Hashing

Funzioni in C. Violetta Lonati

Strutturazione logica dei dati: i file

B+Trees. Introduzione

Allocazione dinamica della memoria - riepilogo

Algoritmi di Ricerca. Esempi di programmi Java

GESTIONE INFORMATICA DEI DATI AZIENDALI

Breve riepilogo della puntata precedente:

Algoritmi e strutture dati. Codici di Huffman

I tipi di dato astratti

Sistemi Operativi. Interfaccia del File System FILE SYSTEM : INTERFACCIA. Concetto di File. Metodi di Accesso. Struttura delle Directory

Informatica 3. LEZIONE 23: Indicizzazione. Modulo 1: Indicizzazione lineare, ISAM e ad albero Modulo 2: 2-3 trees, B-trees e B + -trees

Introduzione alla programmazione in C

PROBLEMA DELLA RICERCA DI UN ELEMENTO IN UN ARRAY E ALGORITMI RISOLUTIVI

10 - Programmare con gli Array

Plate Locator Riconoscimento Automatico di Targhe

La struttura dati ad albero binario

CALCOLATORI ELETTRONICI A cura di Luca Orrù. Lezione n.7. Il moltiplicatore binario e il ciclo di base di una CPU

Mac Application Manager 1.3 (SOLO PER TIGER)

void funzioneprova() { int x=2; cout<<"dentro la funzione x="<<x<<endl; }

FIRESHOP.NET. Gestione completa delle fidelity card & raccolta punti. Rev

Access. P a r t e p r i m a

Per scrivere una procedura che non deve restituire nessun valore e deve solo contenere le informazioni per le modalità delle porte e controlli

Organizzazione degli archivi

Struttura a record. File ad accesso diretto. Modalità di apertura. Modalità di apertura

Archivio CD. Fondamenti di Programmazione

Alberi binari di ricerca

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

Laboratorio di Algoritmi e Strutture Dati

Gestione dinamica di una pila

Programmazione I - Laboratorio

Laboratorio di programmazione

Appunti tratti dal videocorso on-line di Algoritmi e Programmazione Avanzata By ALeXio

Definire all'interno del codice un vettore di interi di dimensione DIM, es. int array[] = {1, 5, 2, 4, 8, 1, 1, 9, 11, 4, 12};

Realizzazione di Politiche di Gestione delle Risorse: i Semafori Privati

Cosa è un foglio elettronico

APPELLO SCRITTO DI PROGRAMMAZIONE 1 CORSO DI LAUREA IN MATEMATICA UNIVERSITÀ DEGLI STUDI DI MILANO XI.2015

Corso di Laurea Ingegneria Informatica Fondamenti di Informatica 2

FIRESHOP.NET. Gestione del taglia e colore.

L algoritmo di ricerca binaria. Daniele Varin LS Ing. Informatica Corso di Informatica teorica Docente: prof. Paolo Sipala

Le Liste. Elisa Marengo. Università degli Studi di Torino Dipartimento di Informatica. Elisa Marengo (UNITO) Le Liste 1 / 31

Matematica - SMID : Programmazione Febbraio 2009 FOGLIO RISPOSTE

Algoritmi e Strutture Dati

FONDAMENTI di INFORMATICA L. Mezzalira

INFORMATICA 1 L. Mezzalira

I puntatori e l allocazione dinamica di memoria

Manuale d uso Software di parcellazione per commercialisti Ver [05/01/2015]

Note su quicksort per ASD (DRAFT)

dall argomento argomento della malloc()

[MANUALE VISUAL BASIC SCUOLA24ORE PROF.SSA PATRIZIA TARANTINO] 14 dicembre 2008

Algoritmi di ordinamento

Dispensa di database Access

1. PRIME PROPRIETÀ 2

Esempio: dest = parolagigante, lettere = PROVA dest (dopo l'invocazione di tipo pari ) = pprrlogvgante

Università di Torino Facoltà di Scienze MFN Corso di Studi in Informatica. Programmazione I - corso B a.a prof.

SOMMARIO Coda (queue): QUEUE. QUEUE : specifica QUEUE

12 - Introduzione alla Programmazione Orientata agli Oggetti (Object Oriented Programming OOP)

Appello di Informatica B

Ing. Paolo Domenici PREFAZIONE

Ricorsione. (da lucidi di Marco Benedetti)

Corso di Informatica

Matematica in laboratorio

Le stringhe. Le stringhe

Tipi primitivi. Ad esempio, il codice seguente dichiara una variabile di tipo intero, le assegna il valore 5 e stampa a schermo il suo contenuto:

Invio SMS. DM Board ICS Invio SMS

Testi di Esercizi e Quesiti 1

I file di dati. Unità didattica D1 1

2. Spiegare brevemente qual è la funzione del compilatore e la sua importanza per il programmatore.

Dall Algoritmo al Programma. Prof. Francesco Accarino IIS Altiero Spinelli Sesto San Giovanni

AA LA RICORSIONE

Capitolo Silberschatz

Concetto di Funzione e Procedura METODI in Java

Fondamenti di Informatica e Laboratorio T-AB T-16 Progetti su più file. Funzioni come parametro. Parametri del main

Appunti di Sistemi Operativi. Enzo Mumolo address web address :

Esercizi Capitolo 6 - Alberi binari di ricerca

SISTEMI DI NUMERAZIONE DECIMALE E BINARIO

LUdeS Informatica 2 EXCEL. Seconda parte AA 2013/2014

Il principio di induzione e i numeri naturali.

Abstract Data Type (ADT)

Lezione 4 Le code. Informatica. 26 Aprile Le pizze devono essere preparate e consegnate seguendo l ordine di arrivo degli ordini

Esercitazione Informatica I AA Nicola Paoletti

La Metodologia adottata nel Corso

Programmazione. Laboratorio. Roberto Cordone DI - Università degli Studi di Milano

Laboratorio di Algoritmi e Strutture Dati

Access. Microsoft Access. Aprire Access. Aprire Access. Aprire un database. Creare un nuovo database

4 3 4 = 4 x x x 10 0 aaa

Mon Ami 3000 Produzione base Produzione articoli con distinta base e calcolo dei fabbisogni

jt - joetex - percorsi didattici

1 CARICAMENTO LOTTI ED ESISTENZE AD INIZIO ESERCIZIO

RICERCA DI UN ELEMENTO

A intervalli regolari ogni router manda la sua tabella a tutti i vicini, e riceve quelle dei vicini.

Appunti sulla Macchina di Turing. Macchina di Turing

Traccia di soluzione dell esercizio del 25/1/2005

Tipi classici di memoria. Obiettivo. Principi di localita. Gerarchia di memoria. Fornire illimitata memoria veloce. Static RAM. Problemi: Dynamic RAM

Alberi binari di ricerca

Sistemi Operativi IMPLEMENTAZIONE DEL FILE SYSTEM. D. Talia - UNICAL. Sistemi Operativi 9.1

Transcript:

PROGRAMMAZIONE AVANZATA JAVA E C Massimiliano Redolfi Lezione 7: Code, Stack, Liste Ricerca 2

Ricerca Se dobbiamo cercare un elemento in un array possiamo trovarci in due situazioni Elementi non ordinati Elementi ordinati Ricerca sequenziale Ricerca binaria 3 Ricerca sequenziale La ricerca sequenziale è molto semplice: si passano tutti gli elementi dell array, dal primo all ultimo, alla ricerca dell elemento chiave: int search_seq(const char *items, int count, char key) for(int i=; i<count; i++) if(items[i] == key) return i; // corrispondenza trovata return -1; // nessuna corrispondenza trovata La ricerca restituisce l indice dell elemento trovato oppure, se nessun elemento corrisponde alla chiave -1. Evidentemente una ricerca richiederà, in media, count/2 confronti. 4

Ricerca sequenziale E possibile migliorare l efficienza dell algoritmo scorrendo l array tramite puntatori e non tramite il sistema di indicizzazione: int search_seq(const char *items, int count, char key) char *p = items; for(int i=; i<count; i++) if(*p++ == key) return i; // corrispondenza trovata return -1; // nessuna corrispondenza trovata 5 Ricerca binaria Se i dati non sono ordinati non c è altra possibilità di ricerca, bisogna scorrere i dati uno alla volta e se i dati sono molti è chiaro che i tempi si allungano (con progressione lineare) Ma se i dati sono ordinati c è un alternativa molto efficiente al posto della ricerca sequenziale, la ricerca binaria! 6

Ricerca binaria Supponiamo di voler cercare il numero 4 all interno di un array ordinato: 1 2 3 4 5 6 7 8 9 L idea è semplice: confrontiamo il valore centrale dell array rispetto alla chiave se è maggiore allora ripeteremo la ricerca nella prima metà altrimenti nella seconda. A questo punto basta ripetere il procedimento ricorsivamente sino a quando non si trova l elemento cercato oppure non ci sono più elementi da cercare. 7 Ricerca binaria Cerco il numero 4: 1 2 3 4 5 6 7 8 9 Poiché 5 è maggiore di 4 cerco nella prima metà: 1 2 3 4 Poiché 2 è minore di 4 cerco nella seconda metà: 3 4 4 Trovato! Ogni volta divido per 2 lo spazio su cui agisco à Il numero di confronti è al più pari a log 2 n 8

int search_bin(char *items, int count, char key) int low=, high=count-1, mid; while(low <= high) mid = (low + high) / 2; if(key < items[mid]) high = mid-1; else if (key > items[mid]) low = mid+1; else return mid; /* Trovato!! */ return -1; /* nessuna corrispondenza */ Ricordarsi che funziona SOLO SU ARRAY ORDINATI! Supposto key = 4 low mid Ricerca binaria high 1 2 3 4 5 6 7 8 9 low mid high 1 2 3 4 5 6 7 8 9 mid lowhigh 1 2 3 4 5 6 7 8 9 low mid high 1 2 3 4 5 6 7 8 9 9 Code, Stack, Liste ed Alberi 1

Rappresentazione astratta dei dati Un programma è composto da due parti fondamentali: gli algoritmi i dati Abbiamo visto che i dati possono essere strutturati in vario modo dai tipi semplici (int, char, ) ad insiemi omogenei (gli array) a tipi di dati complessi come le strutture. 11 Rappresentazione astratta dei dati I dati possono essere rappresentati da due punti di vista distinti: - a livello macchina: in cui ci si concentra sulla rappresentazione fisica del dato (numero di bit, MIPS, ) - a livello astratto: in cui ci si concentra sugli aspetti funzionali legati al dato, tralasciando i dettagli fisici (si ha già un esempio di questo nel passaggio da int a float ) Quando si progetta un sistema, un software è buona cosa immaginare i dati come oggetti astratti, senza preoccuparsi particolarmente dei dettagli fisici che subentreranno solo in un secondo momento, quando si dovranno implementare effettivamente le funzionalità del sistema. 12

astrazione? strutture float int Rappresentazione astratta dei dati Sino a questo momento ci siamo occupati di dati via via sempre più astratti ma sempre legati ad una caratterizzazione fisica del dato (anche le strutture non sono altro che raggruppamenti di tipi ben associabili ad elementi fisici). Il livello successivo trascende questi aspetti astraendo ulteriormente il concetto di dato e comprendendo in questo le funzionalità stesse che permettono di accedere ad un elemento, ovvero le routine di inserimento, estrazione, ricerca del dato stesso. 13 astrazione motori di elaborazione strutture float int Rappresentazione astratta dei dati In questo senso il livello di astrazione che affrontiamo oggi include la logica stessa di accesso al dato in modo indipendente dal tipo trattato. Analizzeremo alcuni tra i principali di motori per l elaborazione dei dati: 1. le code 2. gli stack 3. le liste concatenate 14

Code 15 Code Una coda è un elenco lineare di in cui gli accessi avvengono secondo un ordinamento di tipo FIFO (first-in, firstout). Questo significa che il primo oggetto inserito è anche il primo che verrà estratto. dato inserito E D C B A dato estratto E la tipica situazione della coda in posta od al supermercato chi prima arriva prima viene servito 16

Le operazioni ammesse su una coda sono due: c_ins, c_ret per aggiungere e recuperare un oggetto rispettivamente. Notiamo che non ci sono funzioni ad accesso diretto ad una coda. Code Azione c_ins(a) c_ins(b) c_ret(), ottiene A c_ins(c) c_ins(d) c_ret(), ottiene B c_ret(), ottiene C Contenuto della coda A AB B BC BCD CD D 17 Code Si noti che, come per gli altri motori di elaborazione dei dati, poco ci importa di che cosa siano i dati trattati, quello che ci interessa è come i dati vengono gestiti. Utilità delle code: - buffer - elenchi di task - ritardi - Com è implementabile una coda? 18

Code insert retrive Possiamo vederla come un array di una certa lunghezza (il numero massimo di elementi gestibili dalla coda) e due puntatori o indici: uno punta alla posizione di inserimento, l altra a quella di estrazione 19 Code insert stato iniziale retrive insert c_ins(a) A retrive insert c_ins(b) A B retrive 2

Code insert c_ret() B retrive insert c_ins(c) B retrive C insert c_ins(d) B C D retrive 21 Code insert c_ret() C D retrive insert c_ret() D retrive insert c_ret() retrive 22

Code: un semplice esempio #include <stdio.h> #define MAX_EL 255 char coda[max_el]; int ipos =, rpos = ; void c_ins(char ch) if(ipos >= MAX_EL) printf( Coda piena!\n ); return; coda[ipos] = ch; ipos++; Utilizziamo nell esempio come buffer un array di char globale chiamato coda che contiene al più MAX_EL elementi. ipos e rpos sono rispettivamente gli indici in cui inserire ed estrarre i dati 23 Code: un semplice esempio ch c_ret(void) if(rpos >= ipos) printf( Coda vuota!\n ); return \ ; char ch = coda[rpos]; rpos++; return ch; int main(void) c_ins( A ); c_ins( B ); printf( \nret: %c, c_ret()); c_ins( C ); c_ins( D ); printf( \nret: %c, c_ret()); printf( \nret: %c, c_ret()); printf( \nret: %c, c_ret()); 24

Che fare quando si raggiunge la fine della coda (del buffer)? Code circolari O ci si ferma oppure si ricomincia dall inizio (memorizzando i dati nelle celle che nel frattempo si sono liberate). Quando scrittura e lettura proseguono in questo modo, dalla fine della coda all inizio si parla di code circolari. Come si modifica il sistema precedente per gestire le code circolari? (si devono modificare solo le funzioni c_ins e c_ret) 25 Code circolari: un semplice esempio void c_ins(char ch) // la coda è piena quando un inserimento cancellerebbe un // elemento non ancora letto, cioè quando ipos è uguale a rpos-1 // oppure ipos è alla fine dell array e rpos all inizio if( (ipos+1 == rpos) (ipos+1 == MAX_EL && rpos == ) ) print( Coda piena!\n ); return; coda[ipos++] = ch; if(ipos >= MAX_EL) ipos = ; // riprendi dall inizio 26

char c_ret() // la coda è vuota se i due indici coincidono if(rpos == ipos) printf( Coda vuota\n ); return \ ; Code circolari: un semplice esempio char ch = coda[rpos++]; if(rpos >= MAX_EL) rpos = ; // riprendi dall inizio return ch; 27 Stack 28

Stack Uno stack ha un funzionamento opposto a quello della coda in quanto gli gli accessi avvengono secondo un meccanismo di tipo LIFO (last-in, first-out). Questo significa che il primo oggetto inserito è l ultimo che verrà estratto. Si può immaginare una pila (stack) di piatti, i piatti vengono aggiunti e tolti dalla sommità della pila quindi l ultimo piatto appoggiato sulla pila sarà anche il primo ad essere estratto. 29 Le operazioni ammesse su uno stack sono due: c_ins, c_ret per aggiungere e recuperare un oggetto rispettivamente. Notiamo che non ci sono funzioni ad accesso diretto ad uno stack. Azione Contenuto dello stack inserisci Stack estrai c_ins(a) c_ins(b) c_ret(), ottiene B c_ins(c) c_ins(d) c_ret(), ottiene D c_ret(), ottiene C A BA A CA DCA CA A 3

Stack Per convenzione le funzioni di inserimento ed estrazione dei dati da uno stack sono dette push e pop rispettivamente. Un esempio classico di gestione della memoria di tipo LIFO è rappresentato dallo stack di sistema in cui vengono memorizzate le variabili locali Com è implementabile uno stack? 31 Stack: un semplice esempio #include <stdio.h> #define MAX_EL 255 int stack[max_el]; int tos = ; void push(int i) if(tos >= MAX_EL) printf( Stack pieno!\n ); return; stack[tos++] = i; Utilizziamo nell esempio come buffer un array di int globale chiamato stack che contiene al più MAX_EL elementi. Ci basta un solo indice che indica la cima dello stack (tos) 32

Stack: un semplice esempio int pop(void) if(--tos < ) printf( Stack vuoto!\n ); return tos = ; return stack[tos]; int main(void) push( A ); push( B ); printf( \nret: %c, pop()); push( C ); push( D ); printf( \nret: %c, pop()); printf( \nret: %c, pop()); printf( \nret: %c, pop()); 33 Liste concatenate 34

Liste concatenate Code e stack richiedono che la lettura del dato implichi l eliminazione dello stesso dalla memoria della coda, o dello stack. I dati inoltre sono memorizzati in celle di memoria contigue secondo una dimensione prefissata. Le liste danno invece la possibilità all utente di accedere ad un dato in esse contenute senza rimuoverlo automaticamente. Inoltre mantengono le in modo diverso senza la necessità di preallocare un buffer. Una lista concatenata può essere letta in modo più flessibile in quanto ogni record di informazione contiene un collegamento, un puntatore, al record successivo come in una sorta di catena. 35 Esistono due tipi di liste concatenate: Liste concatenate - liste concatenate semplici: ogni oggetto contiene un puntatore all oggetto successivo - liste concatenate doppie: ogni oggetto contiene due puntatori, uno all oggetto successivo l altro a quello precedente 36

Liste a concatenamento semplice: Liste a concatenamento semplice puntatore puntatore Notiamo che il dato proprio della lista (informazione) è solo una parte dell oggetto che compone l elemento della lista che deve prevedere anche il puntatore all elemento successivo. In genere l oggetto gestito dalla lista può essere visto come una struttura composta da un elemento il cui tipo dipende dall informazione gestita più un puntatore. 37 Liste a concatenamento semplice Supponiamo di realizzare una lista per una rubrica. L informazione è costituita da una struttura address tipo: struct address char nome[5]; char via[1]; char telefono[15]; ; L oggetto complessivo trattato dalla lista sarà: puntatore struct list_item struct address info; // è l informazione vera e propria struct list_item *next; ; 38

Inserire un oggetto alla fine della lista: Prima Liste a concatenamento semplice info info info NUOVO Dopo info info info NUOVO 39 Liste a concatenamento semplice Chiamiamo la funzione list_add, questa dovrà avere in input l elemento da aggiungere più un puntatore all ultimo elemento della lista (in modo da agganciare i due oggetti). struct list_item struct address info; struct list_item *next; ; void list_add(struct list_item *new_item, struct list_item **last_item) if(!*last_item) *last_item = i; // è il primo elemento della lista else (*last_item)->next = i; i->next = NULL; *last_item = i; Si noti che viene passato un puntatore all ultimo elemento della lista in modo da poter modificare il valore dello stesso. 4

Liste a concatenamento semplice Risulta particolarmente semplice visualizzare il contenuto di una lista, è sufficiente scorrerla dal primo all ultimo elemento: void list_show(struct list_item *first_item) struct list_item *p = first_item; int n = ; while(p) printf( \n[%d]: %s, ++n, p->info.nome); p = p->next; 41 Liste a concatenamento semplice: Liste a concatenamento semplice puntatore puntatore Oltre alle operazioni di inserimento e visualizzazione possiamo avere però altre situazioni: - inserire oggetti in una posizione iniziale o mediana - eliminare oggetti all inizio, alla fine o in posizione mediana Vediamo come si svolge concettualmente la cosa (per un esempio di codice si veda l esercitazione libretto_3) 42

Inserire un oggetto all inizio: Prima Liste a concatenamento semplice NUOVO puntatore puntatore Dopo NUOVO info info info 43 Liste a concatenamento semplice Inserire un oggetto in una posizione qualsiasi: Prima NUOVO info info info Dopo info NUOVO info info 44

Eliminare un oggetto all inizio: Prima Liste a concatenamento semplice info info info Dopo cancellato info info 45 Eliminare un oggetto alla fine: Prima Liste a concatenamento semplice info info info Dopo info info cancellato 46

Eliminare un oggetto mediano: Prima Liste a concatenamento semplice info info info Dopo info cancellato info 47 Liste a concatenamento doppio Liste a concatenamento doppio: ogni elemento è legato al successivo ed al precedente Chiaramente valgono tutte le osservazioni precedenti solo che ora i puntatori devono essere aggiornati a coppie 48

Liste a concatenamento semplice Riprendendo l esempio l oggetto trattato dalla lista a concatenamento doppio sarà: struct list_item struct address info; // è l informazione vera e propria struct list_item *next; struct list_item *previous; ; prev info next 49