COLLEZIONI. SOMMARIO Collezioni: Liste: ITERATORI ITERATORI

Documenti analoghi
Sommario. Collezioni. Collezioni: Liste: Pile (stack) Collezioni. Collezioni. Collezioni Struttura indicizzata (array) Nodi

Fondamenti di Informatica e Laboratorio T-AB T-15 Strutture dati

STRUTTURE DATI: OLTRE GLI ARRAY LISTE

Inserimento in una lista ordinata

Strutture dati. Il che cosa e il come. F. Damiani - Alg. & Lab. 04/05

Sul pattern Iterator

ADT Mappa. Le chiavi (il mezzo per accedere agli elementi) hanno lo scopo di rendere efficiente la ricerca. Strutture Dati

Esercitazione 11. Liste semplici

Esercizi riassuntivi (Fondamenti di Informatica 2 Walter Didimo) Soluzioni

ALBERI : introduzione SOMMARIO ALBERI ALBERI. ALBERI: introduzione ALBERI BINARI: introduzione VISITE RICORSIVE DI ALBERI

Capitolo 17. Introduzione alle strutture di dati. Capitolo 17 Introduzione alle strutture di dati

LE STRUTTURE DATI DINAMICHE: GLI ALBERI. Cosimo Laneve

Strutture fisiche e strutture di accesso ai dati

22 - Strutture Dati (Java Collections Framework)

Algoritmi di Ricerca. Esempi di programmi Java

Sommario. Le strutture dati elementari per implementare sequenze: Vettori Liste

Liste doppie. Doubly Linked Lists. GT: 6.2 (e 3.3) Argomenti della lezione

La struttura dati CODA

QUEUE : considerazioni. QUEUE : considerazioni. QUEUE : esempio. QUEUE : esempio

Algoritmi di Ricerca. Esempi di programmi Java

Implementazione ADT: Alberi

Laboratorio di Informatica

INTRODUZIONE INTRODUZIONE TABELLE HASH FUNZIONE HASH

Argomenti della lezione. Introduzione agli Algoritmi e alle Strutture Dati. Lista Lineare. Lista Lineare come Tipo di Dato Astratto

Algoritmi di ordinamento

ADT Dizionario. Come nella Mappa: Diversamente dalla Mappa:

Informatica 3. Informatica 3. LEZIONE 13: Liste doppie, pile e code. Lezione 13 - Modulo 1. Free list (2) Free list. Free list

Introduzione al Java Collections Framework. Java Collections Framework (cont.) Interfacce del Collections Framework

Esempio su strutture dati dinamiche: ArrayList

Fondamenti di Informatica II

Il linguaggio C. Puntatori e dintorni

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

Introduzione al Java Collections Framework

Strutture dati per insiemi disgiunti

Liste concatenate. Collezione ordinata di nodi. Carlo Paolo Simona. Anna. ciascun nodo contiene due riferimenti:

ADT LISTA: altre operazioni non primitive ADT LISTA COSTRUZIONE ADT LISTA COSTRUZIONE ADT LISTA (2)

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

Il TDA Dictionary. Definizione informale. I metodi del TDA Dictionary 1. Applicazioni. I metodi del TDA Dictionary 2. I metodi del TDA Dictionary 3

Strutture dati. Le liste

Le liste con array. Rimuovere la perla rossa costringe a spostare molte altre perle. Dove mettere la perla verde se si è esaurito il filo?

Generics & Collections

Implementazione dell albero binario in linguaggio C++

Una breve introduzione all implementazione in C di algoritmi su grafo

Esercizi Strutture dati di tipo astratto

Esercizi su strutture dati

Linked Lists. Liste linkate (1) liste linkate ( stack, queues ), trees. Liste linkate come strutture

Introduzione Generics Iteratori. Collezioni in Java. Dr. Giulio Pellitta. 13 aprile 2011

Metodi di una Collection

Informatica 3. LEZIONE 12: Liste. Modulo 1: ADT lista e implementazione basata su array Modulo 2: Lista concatenata

se invoco un metodo di Object che è ridefinito in Point, viene invocato il metodo definito in Point

Strutture Dinamiche. Fondamenti di Informatica

Prof. E. Occhiuto INFORMATICA 242AA a.a. 2010/11 pag. 1

Alberi. Strutture dati: Alberi. Alberi: Alcuni concetti. Alberi: definizione ricorsiva. Alberi: Una prima realizzazione. Alberi: prima Realizzazione

5. Quinta esercitazione autoguidata: liste semplici

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

9 - Array. Programmazione e analisi di dati Modulo A: Programmazione in Java. Paolo Milazzo

Capitolo 14 Introduzione alle strutture di dati. Cay S. Horstmann Concetti di informatica e fondamenti di Java quarta edizione

Alberi binari e alberi binari di ricerca

Il linguaggio C Strutture

INDICI PER FILE. Accesso secondario. Strutture ausiliarie di accesso

Fondamenti di Informatica. Algoritmi di Ricerca e di Ordinamento

Laboratorio di Algoritmi e Strutture Dati. Code con Priorità

LABORATORIO DI PROGRAMMAZIONE 2 Corso di laurea in matematica. Algoritmi ricorsivi

Il tipo astratto di dati Node List

Corso di Laurea Ingegneria Informatica Fondamenti di Informatica 2

Algoritmi di ordinamento: Array e ricorsione

Heap e code di priorità

Informatica 1. Prova di recupero 21 Settembre 2001

Indice. Prefazione. 3 Oggetti e Java 53

Tipi di dato strutturati: Array

ADT Dizionario. Ordered search table. Supponiamo che sia definita una relazione d'ordine totale sulle chiavi del dizionario D:

liste ogni nodo ha un successore, tranne l ultimo della lista che ne ha zero; alberi binari ogni nodo ha zero, uno oppure due figli

Java Le stringhe. Stringhe

Il Java Collections Framework

Calcolare x n = x x x (n volte)

Pile: implementazione. Pile: implementazione. Pile: implementazione con array. Pile: implementazione con array. Pile: implementazione con array

lezione 9 min-heap binario Heap e Alberi posizionali generali


Problemi, istanze, soluzioni

Perché il linguaggio C?

Argomenti della lezione. Tipo di dato astratto. Array. Tipo di dato Lista. Liste Implementazione di liste in Java Stack Code

Tipi di dato e Strutture dati elementari

Organizzazione Fisica dei Dati (Parte II)

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

Implementazione della coda con liste concatenate. x v. il front della coda è memorizzato nel primo nodo (head) della lista

Informatica 3. Informatica 3. LEZIONE 17: Alberi generici. Lezione 17 - Modulo 1. Introduzione. ADT dell albero generico.

Corso: Fondamenti di Informatica (Canale 5) a.a Corsi di laurea: Ing. Settore Informazione

Array e liste. IASD a.a

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

GLI ALBERI BINARI DI RICERCA. Cosimo Laneve

Algoritmi e Strutture Dati

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

Algoritmi e Strutture Dati

CORSO DI PROGRAMMAZIONE

SOMMARIO IL PROBLEMA DELLA RICERCA. Algoritmi di ricerca: Algoritmi di ordinamento: RICERCA LINEARE

Heap scenario. Ho un insieme dinamico di oggetti, ciascuno identificato con una priorità. (la priorità è semplicemente un numero);

Java: Definire Classi e Creare Oggetti

Linguaggio C: PUNTATORI

Strutture dati e algoritmi. Sommario

Dizionari Liste invertite e Trie

Transcript:

SOMMARIO Collezioni: Array e liste. Iteratori. Classi interne. Nodi: dati e riferimenti. Liste: LinkedList: specifica e implementazione. Prestazioni. COLLEZIONI Una collezione (contenitore) è un oggetto che raggruppa più dati in una singola struttura. Vi sono due tecniche fondamentali per rappresentare collezioni di elementi: quella basata su strutture indicizzate (array, composti da elementi consecutivi) e quella basata su strutture collegate (list, composte da nodi: ogni nodo contiene dati e collegamenti ad altri nodi). Le collezioni sono usate per memorizzare, leggere, manipolare dati strutturati e per trasmettere tali dati da un metodo ad un altro. Strutture Software 1 - Liste 1 Strutture Software 1 - Liste 2 ITERATORI Una tipica operazione che si esegue su collezioni è esaminare tutti gli elementi uno alla volta. Per gli array è semplice scandire tutti gli elementi attraverso un indice e un ciclo for. In generale, una generica collezione non ha i dati organizzati in una struttura così rigida e lineare. Di conseguenza si introduce il concetto di iteratore, generalizzando la scansione lineare di un array. Strutture Software 1 - Liste 3 ITERATORI Un iteratore è un oggetto di una classe che implementa l interfaccia IEnumerator. Tale interfaccia contiene: bool MoveNext(); object Currentget; void Reset();. Un iteratore è restituito da una collezione sulla quale si è invocato il metodo: IEnumerator GetEnumerator(); descritto dall interfaccia IEnumerable. Tale iteratore consente di scandire i dati della collezione usando i metodi dell interfaccia. Strutture Software 1 - Liste 4

ITERATORI Il metodo MoveNext() sposta l iteratore sul successivo elemento della collezione (al momento della creazione l iteratore precede il primo elemento), restituisce se l operazione è andata a buon fine, false se si è superata la fine della collezione. La proprietà Current fornisce l elemento corrente nella collezione (solo in lettura). Il metodo Reset() riposiziona l iteratore nella posizione iniziale: precedente il primo elemento della collezione. Un iteratore è valido solo se la collezione non è modificata mentre lo si usa. Strutture Software 1 - Liste 5 ITERATORI Sfruttando questo strumento possiamo scrivere una porzione di codice per accedere a tutti gli elementi di una qualsiasi collezione. Vediamo un esempio con la collezione array. int[] vett = 1, 3, 5, 2, 4, 6 ; IEnumerator iter = vett.getenumerator(); while (iter.movenext()) Console.Write(iter.Current + " "); Una possibile uscita 1 3 5 2 4 6 Strutture Software 1 - Liste 6 ITERATORI In C# vi è la parola chiave foreach che permette di accedere in modo semplificato agli iteratori delle collezioni: foreach(int valore in vett) Console.Write(valore + " "); Da questo esempio si può intuire la potenza degli iteratori. Tuttavia la loro implementazione ci porta a considerare le classi interne. Perché è un oggetto che può operare sui dati privati della collezione ed è ritornato da un metodo della classe della collezione, inoltre si possono creare più oggetti iteratore sulla stessa collezione. Strutture Software 1 - Liste 7 CLASSI INTERNE Una classe interna (inner class) è definita internamente ad un altra classe (outer class). La classe interna può accedere a tutti i membri della classe esterna. Di solito è una helper class che non è esplicitamente utilizzata all esterno. Di solito la classe interna implementa un interfaccia che permette di invocare dall esterno i metodi della classe interna attraverso il riferimento creato da un metodo della classe che la include. Strutture Software 1 - Liste 8

CLASSI INTERNE Il fatto di creare una classe interna, invece di creare un unica classe, ci permette di creare più oggetti della classe interna che operano sullo stesso oggetto della classe esterna. Un esempio di classe interna è mostrato nella realizzazione di un iteratore per una collezione. NODI Fino ad ora si sono usate le strutture dati array (semplici e performanti). La loro caratteristica è di avere celle memorizzate sequenzialmente che sono accessibili attraverso indici con costo O(1). Tuttavia si può pensare di usare strutture dati in cui l ordinamento dei dati è solo a livello logico (senza usare un sottostante ordinamento fisico). Questo si può realizzare associando ad ogni elemento anche un riferimento all elemento che lo segue nella sequenza. Strutture Software 1 - Liste 9 Strutture Software 1 - Liste 10 NODI La struttura dati che sfrutta tale idea è la lista. Per ora vediamo di realizzare questa idea di elementi più riferimenti: un oggetto (nodo) che contenga, oltre all informazione sull elemento memorizzato, anche un riferimento al nodo che contiene l elemento che nella sequenza lo segue. Esempio di due nodi: null Strutture Software 1 - Liste 11 class object Element; Next; I due campi sono private per default. NODI La dichiarazione ricorsiva (il campo next è di tipo ) di un nodo può sembrare pericolosa, ma è corretta. Ciò che dichiara è un riferimento ad un oggetto di tipo e non un oggetto stesso. public (object e) if (e == null) throw new Exception("Elemento null."); Element = e; Next = null; Strutture Software 1 - Liste 12

NODI public (object e, n) if (e == null) throw new Exception("Elemento null."); Element = e; Next = n; public next get return Next; set Next = value; public object element get return Element; set Element = value; NODI Vediamo un semplice uso di tale oggetto: n1, n2; n1 = new ("Primo"); n2 = new ("Secondo"); n1.next = n2; Console.WriteLine(n1.element); Console.WriteLine(n1.next.element); Una possibile uscita Primo Secondo Attraverso n1 si accede al contenuto di n2. Strutture Software 1 - Liste 13 Strutture Software 1 - Liste 14 LISTE: introduzione Gli array presentano due limitazioni: Modificare la dimensione dell array richiede la creazione di un nuovo array e la copia di tutti i dati dall array originale a quello nuovo. Inserire un elemento nell array richiede lo scorrimento di dati nell array. Queste limitazioni possono essere superate da strutture concatenate: una collezione di nodi che contengono dati e riferimenti ad altri nodi. In particolare si fa riferimento alle liste concatenate (linked list). Strutture Software 1 - Liste 15 LISTE: introduzione Uno svantaggio delle liste concatenate consiste nell onerosità dell accesso ai suoi elementi: l unico modo per raggiungere un elemento della lista è quello di seguire le connessioni della lista dall inizio in modo sequenziale. Mentre negli array è possibile accedere a qualsiasi elemento attraverso un indice. I metodi di manipolazione delle liste sono diversi da quelli visti per gli array. In generale, una lista rende più semplice la riorganizzazione degli elementi. Strutture Software 1 - Liste 16

LISTE: specifica Una possibile (e minima) interfaccia è la seguente: interface IList: IEnumerable bool Add(object x); Per scandire gli elementi in sequenza attraverso un iteratore. Inserisce l'oggetto x in fondo alla lista. LISTE Sia L un oggetto di tipo IList: ecco alcune operazioni senza iteratori. Invocazione metodo L.IsEmpty(); L.Add( a ); Stato della lista [] [a] risultato bool Remove(object x); bool Contains(object x); bool IsEmpty(); void Clear(); Cancella la prima occorrenza dell'oggetto x. Verifica se la lista contiene l'oggetto x. Verifica se la lista è logicamente vuota. Svuota la lista. L.Add( b ); L.Add( c ); L.Contains( b ); L.Remove( b ); L.Contains( b ); L.IsEmpty(); [a b] [a b c] [a b c] [a c] [a c] [a c] false false Strutture Software 1 - Liste 17 Strutture Software 1 - Liste 18 LISTE Alcune operazioni con iteratori: la barra denota un cursore. Invocazione metodo L.Add(2); L.Add(5); L.Add(4); IEnumerator i=l.getenumerator(); i.movenext() i.movenext() i.current() i.reset() Stato della lista [ 2 ] [ 2 5 ] [ 2 5 4 ] [ 2 5 4 ] [ 2 5 4 ] [ 2 5 4 ] [2 5 4 ] [ 2 5 4 ] risultato i è un iteratore Strutture Software 1 - Liste 19 5 LISTE: esempio Una porzione di codice che legge un file (nomi.txt) e memorizza il contenuto in una lista. Viene allocata la giusta quantità di elementi. Stampa il contenuto della lista attraverso l uso di un iteratore. Rimuove un elemento della lista (Mario) e stampa il nuovo contenuto della lista attraverso l uso di un foreach. nomi.txt Luca Mario Elisa Andrea Una possibile uscita Luca Mario Elisa Andrea ------------------------------ Luca Elisa Andrea Strutture Software 1 - Liste 20

LISTE: esempio StreamReader fin = new StreamReader("nomi.txt"); string sinput1; IList L = new LinkedList(); while ((sinput1 = fin.readline())!= null) L.Add(sInput1); fin.close(); IEnumerator iter = L.GetEnumerator(); while (iter.movenext()) Console.Write(iter.Current + " "); Console.Write("\n----------------------\n"); L.Remove("Mario"); foreach (string s in L) Console.Write(s + " "); LISTE: implementazione Una possibile realizzazione della lista consiste nel considerare una sequenza di nodi che contengono un dato e un riferimento al nodo successivo nella sequenza. Tale sequenza è realizzata nella classe LinkedList che implementa l interfaccia IList. Un oggetto di tipo LinkedList è manipolato utilizzando i metodi resi disponibili dall interfaccia IList, non si accede direttamente alla sequenza di nodi. È un tipo di dato astratto, ADT. Strutture Software 1 - Liste 21 Strutture Software 1 - Liste 22 LISTE: implementazione Si realizza l interfaccia IList con la classe LinkedList e l interfaccia IEnumerator con la classe interna Iteratore. <<interface>> IList: IEnumerable bool Add(object x) bool Remove(object x) bool Contains(object x) bool IsEmpty() void Clear() <<interface>> IEnumerator bool MoveNext() object Current void Reset() LinkedList first last int mod IEnumerator GetEnumerator() bool Add(object x) bool Remove(object x) bool Contains(object x) bool IsEmpty() void Clear() Iteratore LinkedList ll; cursor; int expmod; Iteratore() bool MoveNext() object Current void Reset() NODI: operazioni principali Le due principali operazioni da realizzare sulle liste concatenate (sui nodi della lista nella fase di implementazione) sono: la cancellazione di un elemento della lista e l inserimento di un elemento nella lista. Quindi diminuire o aumentare la lunghezza di una lista. La semplicità di tali operazioni è la ragione d essere delle liste concatenate. Strutture Software 1 - Liste 23 Strutture Software 1 - Liste 24

current= NODI: operazioni principali element=obj3 current= NODI: operazioni principali element=obj3 x= null element=obj3 Il nodo da cancellare viene fatto cadere : current è un riferimento ad un oggetto, se prima della cancellazione current.next punta al nodo obj2, allora: current.current.next.next; Strutture Software 1 - Liste 25 element=obj3 Un nodo da inserire: current e x sono riferimenti ad oggetti, se prima dell inserimento current.next punta al nodo obj3, allora: x.current.next; current.x; Strutture Software 1 - Liste 26 LISTE: implementazione, LinkedList Vediamo una possibile implementazione della lista. LINKEDLIST Una possibile rappresentazione grafica: Si usa una variabile first che mantiene il riferimento al primo nodo della lista e una variabile last che mantiene un riferimento all ultimo nodo. Inoltre è utilizzata una variabile intera mod, che tiene conto delle modifiche alla lista, per evitare che modifiche concorrenti possano interferire con il comportamento degli iteratori. LinkedList first= last= mod=... element=objn null Strutture Software 1 - Liste 27 Strutture Software 1 - Liste 28

class LinkedList : IList private first; private last; private int mod; LINKEDLIST public LinkedList() first = last = null; mod = 0; Numero di modifiche: chiamate a Remove(), Add() e Clear(). LINKEDLIST public bool IsEmpty() return first == null; public void Clear() first = last = null; mod++; Strutture Software 1 - Liste 29 Strutture Software 1 - Liste 30 LINKEDLIST: ricerca public bool Contains(object x) if (x == null) throw new Exception("Argomento null."); for ( i = first; i!= null; i = i.next) if (x.equals(i.element)) return ; return false; Si esaminano i nodi della lista con un ciclo for: si definisce una variabile i di tipo a cui si assegna un riferimento al primo nodo. Si esce dal ciclo quando si finiscono i nodi. L incremento si ottiene con l assegnamento i=i.next, che sposta il riferimento al nodo successivo. Strutture Software 1 - Liste 31 first= first= element=obja element=obja LINKEDLIST: ricerca i = first; i!= null; x.equals(i.element); i= i = i.next element=objb i= element=objb element=objc element=objc i!= null; x.equals(i.element); Strutture Software 1 - Liste 32

LINKEDLIST: inserimento LINKEDLIST: inserimento public bool Add(object x) if (x == null) throw new Exception("Argomento null."); if (IsEmpty()) first = last = new (x); Lista non vuota else last.next = new (x); last = last.next; mod++; return ; Lista vuota Strutture Software 1 - Liste 33 Lista non vuota: last= element=objn null element=objn last= element=x null last.new (x); last=last.next; Strutture Software 1 - Liste 34 LINKEDLIST: prestazioni Aggiungere un nodo alla lista ha un costo computazionale costante O(1): è indipendente dal numero di nodi nella lista. Non si devono copiare gli elementi in una nuova struttura, come nel caso di array pieni. Verificare se la lista contiene un dato oggetto implica l uso di un ciclo for. Si consideri il caso medio: se ogni nodo della lista ha la stessa probabilità di contenere il dato, allora si ha una iterazione per verificare il primo nodo, due iterazioni per verificare il secondo nodo, e in una sequenza lunga n si ha in media 1 n i= 1 1 n( n + 1) i = n 2 = O( n) Strutture Software 1 - Liste 35 n LINKEDLIST: rimozione public bool Remove(object x) if (x == null) throw new Exception("Argomento null."); if (IsEmpty()) return false; if (x.equals(first.element)) if (first == last) last = null; first = first.next; mod++; return ; Primo elemento e ultimo for ( i = first; i.next!= null; i = i.next) if (x.equals(i.next.element)) if (i.next == last) last = i; i.next = i.next.next; mod++; return ; return false; Strutture Software 1 - Liste 36

LINKEDLIST: rimozione LINKEDLIST: prestazioni Primo elemento: first= first=first.next; first= Considerazioni analoghe a quelle sviluppate per calcolare la complessità computazionale media del metodo per la ricerca di un dato valgono anche per il metodo di rimozione di un dato. Quindi il metodo Remove() ha in media un costo lineare, cioè O(n). Strutture Software 1 - Liste 37 Strutture Software 1 - Liste 38 LINKEDLIST: iteratore Il metodo GetEnumerator() restituisce un oggetto iteratore sulla lista per scandire gli elementi in sequenza a partire dall inizio della lista. public IEnumerator GetEnumerator() return new Iteratore(this); La classe dell iteratore è definita come classe interna (Iteratore) alla classe LinkedList. LINKEDLIST: implementazione iteratore Vediamo una possibile implementazione dell iteratore secondo l interfaccia IEnumerator. Si usa una variabile cursor che individua il nodo il cui contenuto è restituito dalla proprietà Current. La variabile ll di tipo LinkedList fa riferimento all oggetto che ha creato l iteratore: attraverso tale riferimento si accede ai dati contenuti nell oggetto lista. Inoltre è utilizzata una variabile intera expmod, che tiene conto delle modifiche alla lista durante l iterazione, per verificare se sono avvenute eventuali modifiche concorrenti. Strutture Software 1 - Liste 39 Strutture Software 1 - Liste 40

LINKEDLIST: implementazione iteratore class LinkedList : IList class Iteratore : IEnumerator LinkedList ll; cursor; int expmod; Classe interna public Iteratore(LinkedList o) ll = o; cursor = null; expmod = ll.mod; Strutture Software 1 - Liste 41 LINKEDLIST: implementazione iteratore public object Current Modifica concorrente get if (ll.mod!= expmod) throw new Exception("Collezione modificata."); if (cursor == null) throw new Exception("Stato non valido."); return cursor.element; public void Reset() if (ll.mod!= expmod) throw new Exception("Collezione modificata."); cursor = null; Strutture Software 1 - Liste 42 LINKEDLIST: implementazione iteratore public bool MoveNext() if (ll.mod!= expmod) throw new Exception("Collezione modificata."); if (ll.isempty()) return false; if (cursor == null) cursor = ll.first; return ; if (cursor!= ll.last) cursor = cursor.next; return ; else return false; LISTE: considerazioni Se è necessario un accesso immediato a ciascun elemento, allora l array è la scelta migliore. Se si accede frequentemente solo ad alcuni elementi (i primi, gli ultimi) e se la modifica della struttura è il cuore di un algoritmo, allora la lista concatenata è la scelta migliore. Un vantaggio delle liste è che usano la quantità minima di memoria necessaria e sono facilmente ridimensionabili. Al contrario un array può essere modificato in dimensione solo di quantità fisse (per esempio dimezzato o raddoppiato). Strutture Software 1 - Liste 43 Strutture Software 1 - Liste 44

LISTE: prestazioni Vediamo in dettaglio le prestazioni di un array e di una linkedlist. Si devono distinguere due casi: dati ordinati e dati non ordinati. Elementi non in ordine. Con entrambe le soluzioni la ricerca è sequenziale e quindi ha un costo O(n). L inserimento o la rimozione di un dato ha un costo costante O(1): si può inserire in fondo alla lista, dato che non deve essere mantenuto un ordinamento. Nel caso dell array potrebbe essere necessario un ridimensionamento. Strutture Software 1 - Liste 45 LISTE: prestazioni Elementi ordinati. Per un array ordinato si può sfruttare l algoritmo di ricerca binaria con un costo O(log n), mentre per una lista la ricerca è sequenziale con un costo O(n) (non si può accedere direttamente al centro di una lista). Inserimento o rimozione di un dato. Per un array è veloce trovare la posizione, O(log n), ma è necessario far scorrere gli elementi per mantenere l ordinamento, costo O(n). Pertanto il costo dell operazione è lineare, O(n). Inoltre potrebbe essere necessario un ridimensionamento. Strutture Software 1 - Liste 46 LISTE: prestazioni Inserimento o rimozione di un dato. Per una lista è più oneroso trovare la posizione, O(n), ma è una operazione veloce inserire o rimuovere un elemento, costo O(1). Pertanto il costo dell operazione è lineare, O(n). Si deve tener presente che due operazioni che hanno lo stesso costo computazionale asintotico non implicano lo stesso tempo di esecuzione. La notazione asintotica è un approssimazione del numero di operazioni base eseguite. LISTE: ordinamento Risulta evidente che c è interesse ad avere delle tabelle di dati ordinati. Vediamo come si può affrontare il problema dell ordinamento per le liste. Nel caso delle liste sono utili gli algoritmi che elaborano i dati sequenzialmente, modalità che può essere efficientemente supportata dalle liste concatenate. Si può pensare di inserire un metodo Sort(), che ordini la lista lavorando direttamente sui nodi. Strutture Software 1 - Liste 47 Strutture Software 1 - Liste 48

LISTE: ordinamento Consideriamo l ordinamento per selezione di una lista concatenata. Si scandisce la lista per determinare il valore minimo, si rimuove tale elemento dalla lista e lo si inserisce in fondo ad una nuova lista. Si usano dei nodi ausiliari per poter manipolare la lista. Per la rimozione è conveniente avere il riferimento al nodo che precede quello che contiene il minimo. Vediamo una possibile implementazione. Strutture Software 1 - Liste 49 LISTE: ordinamento public void Sort() least, outfirst = null, outlast = null; if (IsEmpty() last == first) return; i = new (new object(), first); while (i.next!= null) least = i; for ( j = i.next; j.next!= null; j = j.next) if (((IComparable)j.next.element).CompareTo(least.next.element)< 0) least = j; if (outfirst == null) outfirst = outlast = least.next; else outlast.next = least.next; outlast = outlast.next; least.next = least.next.next; first = outfirst; last = outlast; mod++; Strutture Software 1 - Liste 50 LISTE: ordinamento Un esempio di uso del metodo Sort(): LinkedList L = new LinkedList(); Random rnd = new Random(); for (int i = 0; i < 15; i++) L.Add(rnd.Next(21) - 10); foreach (int n in L) Console.Write(n + " "); Console.Write("\n"); L.Sort(); foreach (int n in L) Console.Write(n + " "); Una possibile uscita 9 3 9 8-5 4 10 1 10 8-4 0 6-2 9-5 -4-2 0 1 3 4 6 8 8 9 9 9 10 10 Boxing del tipo int. Strutture Software 1 - Liste 51 LISTE: ordinamento In molti casi non si ha bisogno di implementare esplicitamente un algoritmo di ordinamento. Si può mantenere ordinata la lista mentre si inseriscono elementi: è sufficiente modificare il metodo Add() in modo che inserisca il nuovo elemento nella corretta posizione. In tal caso il costo dell operazione di inserimento è maggiore perché implica prima una ricerca. Strutture Software 1 - Liste 52

LISTE: ordinamento Un altra possibile soluzione è quella di copiare la lista in un array, ordinare l array (con un costo O(n log n)) e iterare sulla lista per mettere i dati ordinati nuovamente in lista. In generale, potrebbe essere necessario implementare un diverso tipo di iteratore che permetta operazioni sugli elementi della lista, quali rimozioni e inserimenti. Strutture Software 1 - Liste 53 LISTE: doppiamente concatenate Esistono altri tipi di lista, vediamone alcuni. La lista descritta è di tipo semplicemente concatenata: i nodi hanno informazione solo sul loro successore, per cui non si ha accesso al loro predecessore. Si può definire una lista doppiamente concatenata in modo che ogni nodo abbia due campi riferimento: uno al successore e uno al predecessore. In tal modo è possibile percorrere la lista nei due sensi. Strutture Software 1 - Liste 54 LISTE: con salti Per trovare un elemento in una lista è necessaria uno scansione sequenziale. Anche se la lista è ordinata è sempre necessaria una scansione sequenziale. Si evita questo problema utilizzando una lista con salti: liste che consentano di saltare alcuni nodi per evitare manipolazioni sequenziali. La struttura interna è più complessa: nodi con un numero di campi riferimento diverso. o1 o2 o3 LISTE: con salti o4 o5 La ricerca può essere efficiente, anche O(log n), tuttavia sono molto inefficienti le procedure di inserimento e cancellazione. o6 o7 o8 o9 Strutture Software 1 - Liste 55 Strutture Software 1 - Liste 56