PROGRAMMA GESTIONE LISTE
CODICE:
program liste_completo;
{
Creato da Marcello Marchese aka MaRcIo
compilatore Lazarus
http://www.marcio3000.net/marcio/
licenza GNU
}
{$mode objfpc}{$H+}
uses crt;
type
TIPOEL = STRING;
LISTA = ^CELLA;
CELLA = RECORD
inf : tipoel;
next : lista;
end;
var
p:lista;
choice : INTEGER;
n : INTEGER; {numero di elementi della lista}
PROCEDURE CREA_LISTA(var p:lista);
var
aus : lista;
i : INTEGER;
exitflag : BOOLEAN;
elemento : TIPOEL;
begin
n:=1;
new(p); {crea il primo elemento}
p^.next := NIL;
writeln('Inserisci una stringa');
readln(p^.inf); {inserisce il contenuto del primo elemento}
aus:=p; {il puntatore aus punta anche a p}
exitflag := FALSE;
while (exitflag=FALSE) do begin
writeln('Inserisci una stringa (oppure $ per uscire)');
readln(elemento);
if (elemento<>'$') then
begin
new(aus^.next); {crea l'elemento successivo ad aus}
aus:=aus^.next; {aus scorre}
aus^.inf := elemento;
aus^.next := NIL;
n:=n+1;
end
else
exitflag:=TRUE;
end;
writeln('Lista creata! <<INVIO>>');
readln;
end;
PROCEDURE INS_TESTA(var p:lista);
VAR
elemento : TIPOEL;
aus : lista;
begin
writeln('Scrivi l''elemento da inserire in testa');
readln(elemento);
new(aus); {Crea il nuovo elemento separatamente}
aus^.inf := elemento; {Inserisce il valore elemento nella casella inf}
aus^.next:=p; {Collega la casella al vecchio primo elemento della lista}
p:=aus; {il nuovo primo elemento diventa aus}
n:=n+1;
writeln('Elemento inserito! <<INVIO>>');
readln;
end;
PROCEDURE INS_CODA(var p:lista);
VAR
elemento : TIPOEL;
aus , ultimo : lista;
begin
writeln('Scrivi l''elemento da inserire in coda');
readln(elemento);
new(aus); {Crea il nuovo elemento separatamente}
aus^.inf := elemento; {Inserisce il valore elemento nella casella inf}
aus^.next := NIL; {essendo l'ultimo elemento deve puntare a NIL}
ultimo:=p; {utilizziamo ultimo per cercare l'ultimo valore quindi lo -}
{eguagliamo a p che è il primo elemento (essendo passato per indirizzo -}
{p verrebbe modificato}
if (p=NIL) then p:=aus {questo controllo sarebbe inutile perchè questa funzione è visibile solo}
else begin {dopo che si è creata una lista}
while (ultimo^.next <> NIL) do {ricerca l'ultimo valore}
ultimo:=ultimo^.next;
ultimo^.next := aus; {linka l'ultimo valore ad aus}
end;
n:=n+1;
writeln('Elemento inserito! <<INVIO>>');
readln;
end;
procedure ins_pos(var p:lista);
VAR
posizione , i : INTEGER;
aus , precedente , successivo : LISTA;
BEGIN
writeln('In che posizione vuoi inserirlo? [1-',n,']');
posizione:=0;
while ((posizione<1) OR (posizione>n)) do {controlla che inserisca un numero valido}
readln(posizione);
if posizione=1 then
ins_testa(p)
else if posizione=n then
ins_coda(p)
else begin
new(aus);
writeln('Inserisci il valore');
readln(aus^.inf);
precedente:=p;
successivo:=p;
for i:=1 to (posizione-1) do {posizione-1 perchè già al primo cliclo successivo diventa successivo^.next}
begin {cioè si sposta sempre di i+1 posizioni}
successivo:=successivo^.next;
if (i>=2) then
precedente:=precedente^.next;
end;
aus^.next := successivo;
precedente^.next := aus;
n:=n+1;
writeln('Elemento inserito! <<INVIO>>');
readln;
end;
END;
procedure VISUALIZZA_LISTA(p:lista);
BEGIN
while (p <> NIL) do begin
writeln(p^.inf);
p:=p^.next;
END;
writeln('Fine! <<INVIO>>');
readln;
end;
PROCEDURE cancella_elem(var p:lista);
VAR
elemento : TIPOEL;
aus , precedente : LISTA;
i : INTEGER;
BEGIN
writeln('Quale elemento vuoi cancellare? (Scrivi il suo contenuto)');
readln(elemento);
aus:=p;
precedente:=p;
i:=1;
while ((aus<>NIL) AND (aus^.inf<>elemento)) do
begin
aus:=aus^.next;
if (i>=2) then {per conservare l'elemento precedente facciamo partire lo scorrimento al 2° ciclo}
precedente:=precedente^.next;
i:=i+1;
end;
if (aus<>NIL) AND (aus^.inf = elemento) then {se siamo usciti dal while perchè abbiamo trovato un'occorrenza}
begin
if i=1 then begin {L'elemento da eliminare è il primo}
p:=aus^.next;
dispose(aus);
aus:=NIL;
precedente:=NIL;
end
else if i=n then begin {L'elemento da eliminare è l'ultimo}
precedente^.next := NIL;
dispose(aus);
aus:=NIL
end
else begin
//Successivo aus^.next
precedente^.next := aus^.next;
dispose(aus);
aus:=NIL;
end;
n:=n-1;
end
else
writeln('L''elemento non esiste!');
writeln('Fine! <<INVIO>>');
readln;
END;
PROCEDURE SEARCH(p:lista);
VAR elemento : TIPOEL;
i : INTEGER;
BEGIN
writeln('Che elemento vuoi cercare?');
readln(elemento);
i:=1;
while (p<>NIL) AND (p^.inf<>elemento) do begin
p:=p^.next;
i:=i+1;
end;
if (p<>NIL) then
writeln(elemento,' si trova alla posizione ',i,' della lista')
else writeln('Elemento non trovato!');
writeln('Fine! <<INVIO>>');
readln;
END;
BEGIN
writeln('Benvenuto nel programma ''Liste Completo''');
crea_lista(p);
repeat
clrscr;
writeln('''Liste Completo''');
writeln('1. Inserisci un elemento in testa');
writeln('2. Inserisci un elemento in coda');
writeln('3. Inserisci un elemento in un''altra posizione');
writeln('4. Cancella un elemento dalla lista');
writeln('5. Ricerca un elemento');
writeln('6. Visualizza l''intera lista');
writeln('Fai la tua scelta (Scrivi 0 per uscire):');
readln(choice);
case choice of
1: ins_testa(p);
2: ins_coda(p);
3: ins_pos(p);
4: cancella_elem(p);
5: search(p);
6: visualizza_lista(p);
end;
clrscr;
until choice = 0;
readln;
end.
PROCEDURE DEL PROGRAMMA:
INS_TESTA(var p:lista); : Inserisce un elemento in testa
INS_CODA(var p:lista); : Inserisce un elemento in coda
INS_POS(var p:lista); : Inserisce un elemento in una posizione scelta dall'utente
VISUALIZZA_LISTA(p:lista); : Elenca tutti gli elementi della lista
cancella_elem(var p:lista); : Cancella un elemento scelto dall'utente
SEARCH(p:lista); : Permette di trovare la posizione di un elemento nella lista
NOTE SULL'IMPLEMENTAZIONE DELLE SOLUZIONI:
Per la procedura
cancella_elem(var p:lista) si è scelto di utilizzare questa soluzione per
trovare l'elemento da eliminare e conservare il precedente:
aus:=p;
precedente:=p;
i:=1;
while ((aus<>NIL) AND (aus^.inf<>elemento)) do
begin
aus:=aus^.next;
if (i>=2) then {per conservare l'elemento precedente facciamo partire lo scorrimento al 2° ciclo}
precedente:=precedente^.next;
i:=i+1;
end;
cioè si fa scorrere il puntatore 'aus' fino a quando la lista finisce o si trova l'elemento da cancellare,mentre il puntatore 'precedente' (che parte sempre dalla testa della lista) viene fatto partire solo al secondo ciclo in modo da conservare sempre il puntatore precedente ad aus.
Un'altra soluzione possibile sarebbe stato quella di controllare direttamente 'aus^.next' in modo che se "aus^.next^.inf = elemento" avremmo saputo che 'aus^.next' è il puntatore da cancellare e 'aus' quello precedente,ma sarebbe stato necessario scrivere un controllo preventivo per il primo elemento che proprio per il metodo di ricerca che parte da 'aus^.next' verrebbe saltato.
Non ci sono commenti in questa pagina. [Scrivi commento]