Le liste. Le liste linkate

Похожие документы
Inserimento in una lista ordinata

Laboratorio di Programmazione

Programmazione 1 A.A. 2015/2016

Laboratorio di Informatica

Strutture dati dinamiche

E17 Esercizi sugli Array in Java

Esercizio laboratorio (Java 0) Raccolto stampato nel turno successivo di laboratorio

La struttura dati CODA

Rappresentazione di liste mediante puntatori in linguaggio C

Strutture Dinamiche. Fondamenti di Informatica

3. un metodo che restituisce l elenco delle matricole di tutti gli studenti del corso;

public static boolean occorre (int[] a, int n) { int i = 0; boolean trovato = false;

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

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

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

Strutture dati dinamiche in C (II)

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

Algoritmi di Ricerca. Esempi di programmi Java

Programmazione I - Laboratorio

Esempio su strutture dati dinamiche: ArrayList

Esempio su strutture dati dinamiche: ArrayList

Struct e liste concatenate

Esercizi su array. Corso di Laurea Ingegneria Informatica Fondamenti di Informatica. Dispensa E08. C. Limongelli Gennaio 2012

Esempio: Tombola! Vogliamo progettare una applicazione che realizza il gioco della tombola Versione semplificata: un banco, un

Esercizio: Lista Circolare

Hash Table. Hash Table

Транскрипт:

Le liste Le liste linkate Molto spesso bisogna gestire insiemi di oggetti dello stesso tipo. Un modo molto semplice per tenere in memoria tali insiemi consiste nel creare un array per contenerli. Nome Cognome Matricola CdL Nome Cognome Matricola CdL 1

Le liste linkate Gli array presentano però alcuni svantaggi: La dimensione deve essere prefissata L occupazione effettiva di memoria non coincide con la necessità del processo in fase di esecuzione Non è possibile allungare un array Non è possibile inserire elementi nuovi nel mezzo dell array. Occorre spostare in avanti tutti gli elementi a destra della posizione di inserimento, operazione non semplice. Desiderata: Gli elementi organizzati in un unica struttura La dimensione dell insieme deve adattarsi alle reali necessità del processo in esecuzione L insieme deve potersi mantenere ordinato L inserimento in mezzo deve essere possibile ed agevole Le liste linkate Lista linkata: Info Link Info Link Info Link Ogni elemento della lista contiene un riferimento all elemento successivo Serve un identificatore esterno per tenere traccia della lista 2

Le liste linkate - implementazione public class Lista private Nodo ; public Lista() = null; Info Link Info Link Info Link Info Le liste linkate - implementazione public class Nodo private int info; private Nodo next; public Nodo(int val) info = val; next = null; public Nodo(int val, Nodo n) info = val; next = n; public void setinfo(int val) info = val; public int getinfo() return info; public void setnext(nodo n) next = n; public Nodo getnext() return next; info Nodo next 3

Le liste linkate - implementazione Creazione di un nuovo elemento: Nodo elem = new Nodo(10); elem Info 10 Link elem n Creazione di un secondo elemento: Info Link Info Link elem.setnext(new Nodo(13)); 10 13 Le liste linkate - implementazione Creazione di un terzo elemento: (elem.getnext()).setnext(new Nodo(45)); elem Info Link Info Link 10 13 elem.getnext() elem n Info Link Info Link Info Link 10 13 45 4

Le liste linkate - implementazione 1) Nodo = new Nodo(13); 2) Nodo = ; 1) 13 2) 13 Le liste linkate - implementazione 3).setNext(new Nodo()); 4) =.getnext(); 3) n 4) 5

Le liste linkate - implementazione 5).setNext(new Nodo(18)); 5) n 18 Risultato finale: 18 Le liste linkate inserimento di un nuovo elemento 3 possibilità di inserimento: 18 13 in testa 18 in coda 6

Le liste linkate inserimento di un nuovo elemento 3 possibilità di inserimento: 13 15 ordinato Le liste linkate inserimento di un nuovo elemento Inserimento in testa: 1. istanziare un nuovo elemento; 2. collegare la lista già esistente al nuovo nodo; 3. modificare il riferimento alla testa; 18 istanziamo un nuovo elemento Nodo = new Nodo(18, ); 7

Le liste linkate inserimento di un nuovo elemento Inserimento in testa: 1. istanziare un nuovo elemento; 2. collegare la lista già esistente al nuovo nodo; 3. modificare il riferimento alla testa; 18 colleghiamo la lista già esistente al nuovo nodo Nodo = new Nodo(18, ); Le liste linkate inserimento di un nuovo elemento Inserimento in testa: 1. istanziare un nuovo elemento; 2. collegare la lista già esistente al nuovo nodo; 3. modificare il riferimento alla testa; 18 modificare il riferimento alla testa = ; 8

Le liste linkate inserimento di un nuovo elemento public class Lista private Nodo ; public Lista() = null; public void inserthead(int val) Nodo = new Nodo(val,); = ; public class Lista private Nodo ; public Lista() = null; public void inserthead(int val) = new Nodo(val,); Le liste linkate inserimento di un nuovo elemento Inserimento in coda: 1. scorrere la lista fino all ultimo elemento; 2. istanziare un nuovo elemento; 3. collegare l ultimo elemento trovato con il nuovo elemento appena creato; scorriamo la lista fino all ultimo elemento Nodo = ; for( ;.getnext()!= null; =.getnext()); Attenzione! 9

Le liste linkate inserimento di un nuovo elemento Inserimento in coda: 1. scorrere la lista fino all ultimo elemento; 2. istanziare un nuovo elemento; 3. collegare l ultimo elemento trovato con il nuovo elemento appena creato; scorriamo la lista fino all ultimo elemento Nodo = ; for( ;.getnext()!= null; =.getnext()); Attenzione! Le liste linkate inserimento di un nuovo elemento Inserimento in coda: 1. scorrere la lista fino all ultimo elemento; 2. istanziare un nuovo elemento; 3. collegare l ultimo elemento trovato con il nuovo elemento appena creato; n 18 istanziamo un nuovo elemento.setnext(new Nodo(18)); 10

Le liste linkate inserimento di un nuovo elemento Inserimento in coda: 1. scorrere la lista fino all ultimo elemento; 2. istanziare un nuovo elemento; 3. collegare l ultimo elemento trovato con il nuovo elemento appena creato; n 18 colleghiamo l ultimo elemento trovato con il nuovo elemento appena creato.setnext(new Nodo(18)); Le liste linkate inserimento di un nuovo elemento Inserimento in coda: ATTENZIONE!!! Quando inseriamo in coda è necessario prima verificare se la lista è vuota! se == null la lista è vuota se!= null la lista non è vuota Occorre implementare un metodo membro della classe Lista che esegua questo controllo! public class Lista private Nodo ; public Lista() = null; public boolean isempty() return ( == null? true : false); 11

Le liste linkate inserimento di un nuovo elemento public class Lista private Nodo ; public Lista() = null; public void inserttail(int val) if (isempty()) = new Nodo(val); else Nodo = ; for( ;.getnext()!= null; =.getnext());.setnext(new Nodo(val)); Le liste linkate inserimento di un nuovo elemento Inserimento ordinato: 1. scorrere la lista confrontando gli elementi presenti con quello da inserire, arrestandosi quando si trova un elemento maggiore (o minore); 2. collegare la parte con gli elementi minori al nuovo elemento; 3. collegare la parte con gli elementi maggiori; 13 14 scorriamo la lista fino al punto di inserimento Nodo = ; for( ; (.getnext()!= null) && (.getnext()).getinfo() < val); =.getnext()); Attenzione! 12

Le liste linkate inserimento di un nuovo elemento Inserimento ordinato: 1. scorrere la lista confrontando gli elementi presenti con quello da inserire, arrestandosi quando si trova un elemento maggiore (o minore); 2. collegare la parte con gli elementi minori al nuovo elemento; 3. collegare la parte con gli elementi maggiori; 13 14 scorriamo la lista fino al punto di inserimento Nodo = ; for( ; (.getnext()!= null) && (.getnext()).getinfo() < val); =.getnext()); Attenzione! Le liste linkate inserimento di un nuovo elemento Inserimento ordinato: 1. scorrere la lista confrontando gli elementi presenti con quello da inserire, arrestandosi quando si trova un elemento maggiore (o minore); 2. collegare la parte con gli elementi maggiori al nuovo elemento; n 3. collegare la parte con gli elementi minori; 13 14 15 collegare la parte con gli elementi maggiori al nuovo elemento.setnext(new Nodo(val,.getNext())); 13

Le liste linkate inserimento di un nuovo elemento Inserimento ordinato: 1. scorrere la lista confrontando gli elementi presenti con quello da inserire, arrestandosi quando si trova un elemento maggiore (o minore); 2. collegare la parte con gli elementi maggiori al nuovo elemento; n 3. collegare la parte con gli elementi minori; 15 13 14 collegare la parte con gli elementi minori al nuovo elemento.setnext(new Nodo(val,.getNext())); Le liste linkate inserimento di un nuovo elemento Inserimento ordinato: ATTENZIONE!!! Quando inseriamo in coda è necessario prima verificare se la lista è vuota e, in subordine, controllare se il primo elemento della lista verifica già la condizione! public class Lista private Nodo ; public Lista() = null; public void insertordered(int val) if (isempty()) = new Nodo(val); else if(.getinfo() > val) = new Nodo(val, ); else Nodo = ; for( ; (.getnext()!= null) && ((.getnext()).getinfo() < val); =.getnext());.setnext(new Nodo(val,.getNext())); 14

Le liste linkate inserimento di un nuovo elemento 1. Lista ordinata: public class Lista private Nodo ; public Lista() = null; public Nodo searchord(int key) //CORPO DEL METODO Le liste linkate ricerca di un elemento 1. Lista ordinata: public class Lista private Nodo ; public Lista() = null; public Nodo searchord(int key) Nodo = ; for( ;!=null &&.getinfo() < key; =.getnext()); if(!=null &&.getinfo() == key) return ; return null; 15

Le liste linkate ricerca di un elemento 2. Lista non ordinata: public class Lista private Nodo ; public Lista() = null; public Nodo search(int key) //CORPO DEL METODO Le liste linkate ricerca di un elemento 2. Lista non ordinata: public class Lista private Nodo ; public Lista() = null; public Nodo search(int key) Nodo = ; for( ;!=null &&.getinfo()!= key; =.getnext()); return ; //ATTENZIONE!!!

Le liste linkate cancellazione di un elemento 1. cancellazione del primo elemento con restituzione del valore info: 13 15 Le liste linkate cancellazione di un elemento 1. cancellazione del primo elemento con restituzione del valore info: 13 15 public int deletehead() //CORPO DEL METODO 17

Le liste linkate cancellazione di un elemento 1. cancellazione del primo elemento con restituzione del valore info: public class Lista private Nodo ; public Lista() = null; public int deletehead() if (isempty()) System.out.println( Lista vuota ); return 0; else Nodo = ; =.getnext(); return.getinfo(); Le liste linkate cancellazione di un elemento 1. cancellazione dell ultimo elemento con restituzione del valore info: 13 15 prev 18

Le liste linkate cancellazione di un elemento 1. cancellazione dell ultimo elemento con restituzione del valore info: 13 15 prev Le liste linkate cancellazione di un elemento 1. cancellazione dell ultimo elemento con restituzione del valore info: 13 15 prev public int deletetail() //CORPO DEL METODO 19

Le liste linkate cancellazione di un elemento 1. cancellazione dell ultimo elemento con restituzione del valore info: public class Lista private Nodo ; public Lista() = null; public int deletetail() if (isempty()) System.out.println( Lista vuota ); return 0; else Nodo = ; Nodo prev = null; for( ;.getnext()!= null; prev =, =.getnext()); if(prev == null) =null; //A CHE SERVE QUESTA ISTRUZIONE? else prev.setnext(null); return.getinfo(); Le liste linkate cancellazione di un elemento 1. cancellazione di un elemento qualsiasi con restituzione del Nodo: 13 15 prev 20

Le liste linkate cancellazione di un elemento 1. cancellazione dell ultimo elemento con restituzione del valore info: 13 15 prev public Nodo deletekey(int key) //CORPO DEL METODO Le liste linkate cancellazione di un elemento 1. cancellazione di un elemento qualsiasi con restituzione del Nodo: public class Lista private Nodo ; public Lista() = null; public Nodo deletekey(int key) //ABBIAMO UN PARAMETRO! if (isempty()) System.out.println( Lista vuota ); return null; else Nodo = ; Nodo prev = null; for( ;.getnext()!= null &&.getinfo()!= key; prev =, =.getnext()); if(!= null) if(prev == null) //NON E INUTILE QUESTO CONTROLLO? =.getnext(); else prev.setnext(.getnext()); return ; 21

Le liste linkate esercizi a) Aggiungere alla classe Lista un metodo gethead() che restituisca un riferimento alla testa della lista; b) Aggiungere alla classe Lista un metodo printlist() che stampi a video tutti gli elementi della lista; 1. Concatenare una lista linkata ad un'altra lista linkata. 2. Fondere due liste linkate ed ordinate di interi in una lista linkata ordinata. 3. Invertire una lista linkata. 4. Invertire una lista linkata con una procedura ricorsiva. Le liste linkate esercizi Metodo gethead() : public Nodo gethead() return ; Metodo printlist() : public void printlist() Nodo = ; for(;!=null; =.getnext()) System.out.println(.getInfo()); 22

Le liste linkate esercizi Una possibile soluzione per l esercizio 1: public class Esercizio1 public static void concatlists(lista l1, Lista l2) if (l2.isempty()) return; Nodo pl2=l2.gethead(); for(; pl2!=null; pl2=pl2.getnext()) l1.inserttail(pl2.getinfo()); public static void main(string[] args) Lista l1 = new Lista(); Lista l2 = new Lista(); for(int i = 1; i<=10; i++ ) l1.inserttail(i); for(int i = 11; i<=20; i++ ) l2.inserttail(i); concatlists(l1,l2); l1.printlist(); Le liste linkate esercizi Una possibile soluzione per l esercizio 2: public static Lista mergelist(lista l1, Lista l2) Lista l3 = new Lista(); Nodo p1 = l1.gethead(); Nodo p2 = l2.gethead(); while(p1!= null && p2!= null) if(p1.getinfo() <= p2.getinfo()) //l'elemento corrente di l1 è <= a quello di l2 l3.inserttail(p1.getinfo()); p1 = p1.getnext(); else //l'elemento corrente di l1 è > a quello di l2 l3.inserttail(p2.getinfo()); p2 = p2.getnext(); //End while CONTINUA 23

Le liste linkate esercizi Una possibile soluzione per l esercizio 2: RIPRENDE //Attacchiamo l'eventuale coda della lista piu' lunga while(p1!= null) // l1 e' la lista piu' lunga l3.inserttail(p1.getinfo()); p1 = p1.getnext(); while(p2!= null) // l2 e' la lista piu' lunga l3.inserttail(p2.getinfo()); p2 = p2.getnext(); return l3; Le liste linkate esercizi Una possibile soluzione per l esercizio 2: public class Esercizio2 public static Lista mergelist(lista l1, Lista l2) //Corpo della funzione public static void main(string[] args) int[] vl1 = 2,2,9,11,23; int[] vl2 = 8,10,34; Lista l1 = new Lista(); Lista l2 = new Lista(); Lista l3 = new Lista(); for(int i = 0; i < vl1.length; i++ ) l1.insertordered(vl1[i]); for(int i = 0; i < vl2.length; i++ ) l2.insertordered(vl2[i]); l1.printlist( ); System.out.println(); l2.printlist( ); System.out.println(); l3 = mergelist(l1,l2); l3.printlist(); 24

Le liste linkate esercizi Una possibile soluzione per l esercizio 3: public class Esercizio3 public static Lista reverse(lista l) Lista l = new Lista(); Nodo = l.gethead(); while(!= null) l.inserthead(.getinfo()); =.getnext(); return l; public static void main(string[] args) Lista lx = new Lista(); for(int i = 1; i<=10; i++ ) lx.inserttail(i); lx.printlist(); //Stampiamo la lista prima dell'inversione System.out.println(); lx = reverse(lx); lx.printlist(); Le liste linkate esercizi Una possibile soluzione per l esercizio 4: 1. Come possiamo pensare questo metodo in termini ricorsivi? return(l) se (L = Ø) reverse(l) = reverse(l ) + metti primo(l) in coda alla lista risultante se (L Ø) Dove L = L primo(l) 25

Le liste linkate esercizi L 7 5 4 3 L L 5 4 3 L 4 3 L L Le liste linkate esercizi L 3 L L L 3 26

Le liste linkate esercizi L 3 4 L 3 4 5 L 3 4 5 7 Le liste linkate esercizi Una possibile soluzione per l esercizio 4: public class Esercizio4 public static Lista reverser(lista l) if (! l.isempty()) int n = l.deletehead(); reverser(l).inserttail(n); return l; public static void main(string[] args) Lista lx = new Lista(); for(int i = 1; i<=10; i++ ) lx.inserttail(i); lx.printlist(); //Stampiamo la lista prima dell'inversione System.out.println(); lx = reverser(lx); lx.printlist(); 27