Programmazione Mod. B - prof.
Burattini - Cap 17
1
LISTE E PUNTATORI
Una lista può essere vista come un array.
Una lista può anche essere vista come una serie di elementi gli uni
collegati agli altri attraverso un sistema di puntatori.
a
b
c
d
e
Le strutture a,b,…., possono essere di type integer, stringa, record, etc.
Programmazione Mod. B - prof.
Burattini - Cap 17
2
Una linear linked list ( o lista legata lineare) è una collezione di variabili dinamiche
formate da un campo item e un campo puntatore. Ogni puntatore punta alla
variabile successiva nell’ambito della struttura considerata.
item puntatore
puntatore
Variabile dinamica
Pt
Emma
P1
Luca
P2
Ugo
P3
?
nodo
Lista Ind. Nome
Mem
puntatore
10000100
11100100
10000110
Pt
P1
P2
Type
Programmazione Mod. B - prof.
Burattini - Cap 17
rec
rec
rec
Nome
valore
Variabile
Pt^
P1^
P2^
Emma P1
Luca P2
Ugo P3
3
Pt
Item
Emma Px
Next
?
Stringa di 20 caratteri
CONST
NullItem= ' ' ;
{controllo di eventuali errori }
TYPE
ItemType= STRING20[20]
LNodeP=^LNodeType
{puntatore a un nodo della lista}
LNodeType = RECORD
Item:ItemType;
Notare che l’identificatore
Next:LNodeP
LNodeP è definito prima del
END;
record dinamico LNodeType.
VAR
Px:LNodeP;
Questa è una eccezione rispetto
allo standard del Pascal in cui si
riferimento a un Type che 4
Programmazione Mod. Bfa
- prof.
Burattini - Cap 17precede e non che segue.
Next
Px
Emma
P1
Luca
P2
Ugo
P3
NIL
Item
Px^.Item
Emma
Px^.Next^.Item
Luca
Px^.Next^.Next^.Item
Ugo
Px^.Next^.Next ^.Next^.NextNIL
Item
CONST
NullItem= ' ' ;{controllo di eventuali errori }
TYPE
ItemType= STRING20[20]
LNodeP=^LNodeType
LNodeType = RECORD
Item:ItemType;
Next:LNodeP
END;
Next
VAR
Programmazione Mod. B - prof.
Px:LNodeP;
Burattini - Cap 17
5
ESERCIZIO
Assegnata due liste legate L1 e L2 contenenti numeri interi, fondere le
due liste in un’unica lista in cui nella prima parte ci siano solo i numeri
dispari e nella seconda parte solo i numeri pari.
Es.
L1=[2,5,1,6,8]
L2=[12,3,10,7,9]
L3=[5,1,3,7,9,2,6,8,12,10]
Programmazione Mod. B - prof.
Burattini - Cap 17
6
LISTE GENERALIZZATE
Vediamo come è possibile aggiungere o eliminare nodi dalla lista in un qualunque suo
punto.
Programmazione Mod. B - prof.
Burattini - Cap 17
7
CONST
NullItem= ' ' ;
{controllo di eventuali errori }
TYPE
ItemType= STRING[20]
LNodeP=^LNodeType
LNodeType = RECORD
Item:ItemType;
Next:LNodeP
END;
ListType = RECORD
First:LNodeP
END;
VAR AList:ListType;
Programmazione Mod. B - prof.
Burattini - Cap 17
8
PROCEDURE MakeList(VAR AList:ListType);
{Crea una nuova lista vuota}
PROCEDURE InsertNode(AnItem:ItemType; PrevNodeP:LNodeP; VAR AList:ListType);
{Inserisce un Node con campo AnItem nella lista Alist. Il nodo è inserito subito dopo il nodo che ha
come puntatore PrevNodeP. Se AListFirst=NIL allora il nodo sarà il primo della lista}
PROCEDURE DeleteNode(PrevNodeP:LNodeP; VAR AList:ListType);
{Cancella il Nodo che nella lista segue quello puntato da PrevNodeP . Se PrevNodeP è Alist.First,
viene cancellato il primo nodo. Se la lista è vuota o PrevNodeP=NIL allora non succede nulla }
PROCEDURE KillNode(VAR Node:LNodeP);
{Constructor :se Node non è NIL, dispose la memoria allocata per il Node e poi pone il Node a NIL. }
Alist
First
Alist.First
CONST
NullItem= ' ' ;
{controllo di eventuali errori }
ListType
TYPE
ItemType= STRING[20]
LNodeP=^LNodeType
LNodeType = RECORD
NullItem
Next
Item:ItemType;
Next:LNodeP
END;
ListType = RECORD
First:LNodeP
LNodeType
END;
Programmazione Mod.
B
prof.
9
VAR
Burattini - Cap 17
AList:ListType;
FUNCTION FirstNode(AList:ListType) :LNodeP;
{ritorna il puntatore del primo nodo della lista }
FUNCTION EmptyList(AList:ListType) :boolean;
{ritorna TRUE se la lista è vuota }
FUNCTION CercaPrevP(Px:LNodeP; AList:ListType):LNodeP;
{dato il puntatore di un nodo Px fornisce il valore del puntatore del nodo che lo precede}
FUNCTION LPos(AList:ListType; SearchItem:ItemType):LNodeP;
{Fornisce il puntatore di un preassegnato nodo SearchItem}
FUNCTION Seleziona(AList:ListType;Index:integer):ItemType;
{Fornisce il nome del nodo che si trova al posto Index}
Alist
First
Alist.First
CONST
NullItem= ' ' ;
{controllo di eventuali errori }
TYPE
ItemType= STRING[20]
ListType
LNodeP=^LNodeType
LNodeType = RECORD
Item:ItemType;
Next:LNodeP
NullItem
Next
END;
ListType = RECORD
First:LNodeP
END;
Programmazione VAR
Mod. B - prof.
10
LNodeType
AList:ListType;
Burattini - Cap 17
PROCEDURE MakeList(VAR AList:ListType);
{Crea una nuova lista vuota mettendo nei campi di First
rispettivamente NullItem e NIL }
BEGIN
Alist.First:=NIL
END;
PROCEDURE KillNode(VAR Node:LNodeP);
BEGIN
IF Node <> NIL THEN
BEGIN
dispose(Node);
Node:=NIL
END
END;
FUNCTION FirstNode(AList:ListType) :LNodeP;
{ritorna il puntatore del primo nodo della lista }
BEGIN
FirstNode:=AList.First
END;
CONST
NullItem= ' ' ;{controllo di eventuali errori }
TYPE
ItemType= STRING[20]
LNodeP=^LNodeType
LNodeType = RECORD
Item:ItemType;
Next:LNodeP
END;
ListType = RECORD
First:LNodeP
END;
VAR
AList:ListType;
Alist
First
Alist.First
FUNCTION EmptyList(AList:ListType) :boolean;
{ritorna TRUE se la lista è vuota }
BEGIN
EmptyList:=AList.First=NIL
Programmazione Mod. B - prof.
END;
Burattini - Cap 17
ListType
NullItem
Next
LNodeType
11
PROCEDURE InsertNode(AnItem:ItemType;VAR PrevNodeP:LNodeP;VAR AList:ListType);
{Inserisce un Node con campo AnItem nella lista Alist. Il nodo è inserito subito dopo il nodo che ha
come puntatore PrevNodeP. Se PrevNodeP=NIL allora il nodo sarà il primo della lista}
VAR
Temp:LNodeP;
Temp
BEGIN
MakeNode(AnItem,Temp);
IF PrevNodeP=NIL THEN
BEGIN
PrevNodeP:=Temp;
Temp^.Next:=AList.First;
AList.First:=Temp;
END
ELSE
BEGIN
Temp^.Next:=PrevNodeP^.Next;
PrevNodeP^.Next:=Temp;
PrevNodeP:=Temp;
END;
Item
Next
AList.First
NIL
Temp
Item
Temp
Item
NIL
Next
END;
PrevNodeP
AListFirst
Item
Item
Next
Next
Item
Programmazione Mod.Item
B - prof.
PrevNodeP
Burattini - Cap 17
PrevNodeP
Next
Next
Item
Item
Next
Next
12
Pseudo codice per cancellare un nodo
• Controllare se la lista è vuota.
• Controllare che non si cerchi di cancellare un puntatore che vale NIL.
• Cancellare il nodo indicato dal puntatore del nodo che lo precede, e far puntare
quest’ultimo sul nodo succesivo a quello da cancellare.
AListFirst
NullItem Next
Item
Next
Item
Next
Item
Next
PrevNodeP
Programmazione Mod. B - prof.
Burattini - Cap 17
13
PROCEDURE DeleteNode(PrevNodeP:LNodeP;VAR AList:ListType);
VAR
Temp:LNodeP;
BEGIN
IF PrevNodeP<>NIL THEN
Temp:=PrevNodeP^.Next { il nodo da cancellare non è il primo}
ELSE
Temp:=AList.First; { il nodo da cancellare è il primo}
IF Temp<>NIL THEN
IF PrevNodeP<>NIL THEN
PrevNodeP^.Next:=Temp^.Next
ELSE
AList.First:=Temp^.Next;
KillNode(Temp)
END;
END;
Programmazione Mod. B - prof.
Burattini - Cap 17
14
PrevNodeP
AListFirst
PrevNodeP
<>
NIL
NullItemNext
Item Next
<>
Item Next
Item Next
Temp= PrevNodeP^.Next
PrevNodeP.Next
=
Potrebbe essere un qualunque
nodo o l’ultimo nodo
Temp= Alist.First
Potrebbe essere un qualunque
nodo o il primo della lista
lista vuota
Ultimo nodo
<>
Temp
<>
NIL
PrevNodeP
<>
NIL
E’ un nodo qualunque
<>
PrevNodeP^.Next:=Temp^.Next
=
=
AList.First:=Temp^.Next
E’ il primo della lista
Programmazione Mod. B - prof.
KillNode(Temp)
Burattini - Cap
17
15
FUNCTION CercaPrevP(Px:LNodeP; VAR AList:ListType):LNodeP;
{dato il puntatore di un nodo Px fornisce il valore del puntatore del nodo che lo precede}
VAR
CandP,Temp:LNodeP;
BEGIN
IF Px=AList.First THEN
CercaPrevP:=NIL
ELSE
BEGIN
CandP:=Alist.First;
WHILE (CandP <> Px) AND (CandP<>NIL) DO
BEGIN
Temp:=CandP;
CandP:=CandP^.Next
END;
CercaPrevP:=Temp
END
END;
Programmazione Mod. B - prof.
Burattini - Cap 17
16
Introduciamo due funzioni che permettono la gestione delle liste invece che attraverso i
puntatori, attraverso la posizione dei singoli nodi nella lista.
FUNCTION Seleziona(AList:ListType;Index:integer):ItemType;
{Data una lista resituisce l'Item che si trova nella posizione Index}
BEGIN
CONST
IF Index<=0 THEN Seleziona:=NullItem
NullItem= ' ' TYPE
ELSE
ItemType= STRING[20]
Seleziona:=Ennesimo(AList.First^.Next,Index)
LNodeP=^LNodeType
END;
LNodeType = RECORD
Item:ItemType;
Next:LNodeP
END;
ListType =
RECORD
First:LNodeP
END;
VAR
AList:ListType;
FUNCTION Ennesimo(P:LNodeP;n:integer):ItemType;
{ricorsivamente cerca l'ennesimo elemento della lista}
VAR
AnItem:ItemType;
BEGIN
IF n=1 THEN
BEGIN
ItemValue(P,AnItem);
Ennesimo:=AnItem;
END
ELSE
Ennesimo:= Ennesimo(NextNode(P),n-1)
{funzione ricorsiva}
Programmazione Mod. B - prof.
END;
Burattini - Cap 17
17
Introduciamo una funzione che permette la ricerca del puntatore di un nodo di cui è noto l’item.
FUNCTION LPos(List:ListType; SearchItem:ItemType):LNodeP;
VAR
CandNode: LNodeP;
CandItem:ItemType;
BEGIN
CandNode:=FirstNode(List); {il primo item nella lista o NIL}
ItemValue(CandNode,CandItem);
WHILE (CandItem <> NullItem) AND (CandItem <> SearchItem) DO
BEGIN
CandNode:=NextNode(CandNode);
ItemValue (CandNode,CandItem);
END;
IF CandItem=SearchItem THEN
Lpos:=CandNode
ELSE
Lpos:=NIL ;
END;
Riscrivere questa funzione in forma ricorsiva
Programmazione Mod. B - prof.
Burattini - Cap 17
18
PROGRAM TestListe;
VAR
Lista:ListType;
Nome,Nome2:ItemType;
Indice:integer;
Nodo,Nodo1, Px,PrevPx,LastNode:LNodeP;
BEGIN
writeln(' CREA LISTA');
MakeList(Lista);
writeln;
{Inserisci Dati}
Nodo1:=Lista.First;
writeln(' Dammi un nome');
readln(Nome);
WHILE Nome<> NullItem DO
BEGIN
InsertNode(Nome,Nodo1,Lista);
writeln(' Dammi un nome');
readln(Nome);
END;
writeln('Lista iniziale');
ShowList(FirstNode(Lista));
Programmazione Mod. B - prof.
Burattini - Cap 17
19
{CancellaNome}
writeln(' Quale nome vuoi cancellare ');
readln(Nome);
writeln;
Px:=Lpos(Lista,Nome);
PrevPx:=CercaPrevP(Px,Lista);
DeleteNode(PrevPx,Lista);
writeln('Lista dopo la cancellazione');
ShowList(FirstNode(Lista));
readln;
{InserisciRandom}
writeln('Inserisci un nodo dopo l''item ');
readln(Nome);
writeln('Nuovo nodo ');
readln(Nome2);
Nodo1:=LPos(Lista,Nome);
InsertNode(Nome2,Nodo1 ,Lista);
writeln('Lista dopo inserimento di un nodo');
ShowList(FirstNode(Lista));
readln;
Programmazione Mod. B - prof.
Burattini - Cap 17
20
{CancellaPos}
writeln('Cancella il nodo n. ');
readln(Indice);
Nome:=Seleziona(Lista,Indice);
Px:=Lpos(Lista,Nome);
PrevPx:=CercaPrevP(Px,Lista);
DeleteNode(PrevPx,Lista);
writeln('Lista dopo la cancellazione del nodo n. ',Indice);
ShowList(FirstNode(Lista));
readln;
END.
Programmazione Mod. B - prof.
Burattini - Cap 17
21
Programmazione Mod. B - prof.
Burattini - Cap 17
22
Scarica

LEZIONE liste