Algoritmi elementari sulle liste Prescindiamo dalla realizzazione

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