Algoritmi elementari sulle liste Lunghezza, copia, concatenazione, inversione. Informatica 2 - Algoritmi sulle Liste Prescindiamo dalla realizzazione • Tutto quello che ci serve sapere è: typedef … ListOfInt; // è definito un tipo delle liste di interi ListOfInt TheEmptyList(); // ritorna la lista vuota ListOfInt Cons(int n, ListOfInt L); // ritorna la lista che si ottiene da L // aggiungendo n come primo elemento Informatica 2 - Algoritmi sulle Liste Prescindiamo dalla realizzazione • Tutto quello che ci serve sapere è: int& Head(ListOfInt L); // Pre: L non è vuota // Post: ritorna (e dà accesso a) la // testa di L ListOfInt& Tail(ListOfInt L); // Pre: L non è vuota // Post: ritorna (e dà accesso a) la // coda di L Informatica 2 - Algoritmi sulle Liste 1 Prescindiamo dalla realizzazione • Tutto quello che ci serve sapere è: bool IsEmpty (ListOfInt L); // true sse L == TheEmptyList() Informatica 2 - Algoritmi sulle Liste Il modello inteso • Tuttavia, per aiutarci nella ideazione di algoritmi iterativi, è comodo pensare le liste come semplicemente concatenate: l 2 5 9 1 ∅ Informatica 2 - Algoritmi sulle Liste Lunghezza di una lista • La lunghezza di una lista è il numero degli elementi che la compongono: L = [a1, …, an] è lunga n L L’ L L ∅ n = numero degli elementi che in L precedono la testa di L’ Informatica 2 - Algoritmi sulle Liste 2 Lunghezza di una lista • La lunghezza di una lista è il numero degli elementi che la compongono: L = [a1, …, an] è lunga n int Length(ListOfInt L) { int n = 0; while (!IsEmpty(L)) { n++; L = Tail(L); } return n; } Informatica 2 - Algoritmi sulle Liste Concatenazione di liste • La concatenazione fonde insieme due liste: L1 L2 5 ∅ 2 1 9 Idea: scandisco L1 sino al suo ultimo el. cui lego L2 Append(L1, L2) 2 3 ∅ 5 1 9 3 ∅ Informatica 2 - Algoritmi sulle Liste Concatenazione di liste ListOfInt Append(ListOfInt L1, ListOfInt L2) { if(IsEmpty(L1)) return L2; ListOfInt L; for (L = L1; !IsEmpty(Tail(L)); L = Tail(L)); Tail(L) = L2; return L1; } Per evitare che Tail(L) sia indefinita nel test del for, il caso IsEmpty(L1)) è trattato a parte Informatica 2 - Algoritmi sulle Liste 3 La copia di una lista L’ L 2 5 9 7 1 ∅ C’ C 2 9 ∅ 5 Tail(C) = Cons(Head(L),TheEmptyList()); Informatica 2 - Algoritmi sulle Liste La copia di una lista L’ L 2 5 9 7 1 ∅ Ma come si comincia? C’ C 2 5 9 7 ∅ Tail(C) = Cons(Head(L),TheEmptyList()); Informatica 2 - Algoritmi sulle Liste La copia di una lista L’ L 2 R 5 9 7 1 ∅ C’ C 2 5 9 ∅ Record fittizio sulla cui coda costruiamo la copia di L Informatica 2 - Algoritmi sulle Liste 4 La copia di una lista ListOfInt ListClone(ListOfInt L) { ListOfInt R = Cons(0,TheEmptyList()); ListOfInt C = R; while(!IsEmpty(L)) { Tail(C) = Cons(Head(L),TheEmptyList()); C = Tail(C); L = Tail(L); } Deallocazione necessaria per eliminare il record fittizio C = Tail(R); delete R; return C; } Informatica 2 - Algoritmi sulle Liste Inversione di una lista • Immaginiamo una situazione intermedia: T 2 ∅ 5 R 9 T = L; 1 ∅ 7 L Informatica 2 - Algoritmi sulle Liste Inversione di una lista • L’uso del temporaneo T consente di avanzare L: T 2 ∅ 5 R 9 1 ∅ 7 L L = Tail(L); Informatica 2 - Algoritmi sulle Liste 5 Inversione di una lista • Ora la coda di T può diventare R: T 2 ∅ 5 9 Tail(T) = R; 1 ∅ 7 L R Informatica 2 - Algoritmi sulle Liste Inversione di una lista • Possiamo ripristinare una situazione simile a quella iniziale, ma più prossima all’obiettivo: T 2 ∅ 5 9 R 1 ∅ 7 L R = T; Informatica 2 - Algoritmi sulle Liste Inversione di una lista ListOfInt Reverse(ListOfInt L) { ListOfInt R = L, T; while(!IsEmpty(L)) { T = L; L = Tail(L); Tail(T) = R; R = T; } return R; } Informatica 2 - Algoritmi sulle Liste 6