O lista L e o secventa de zero sau mai multe elemente,
numite noduri, toate fiind de acelasi tip de baza T.
L=a1,a2,...,an (n>=0)
Daca n>=1, a1 se spune ca este primul nod al listei, iar an, ultimul nod. Daca n=0, lista este vida.
O proprietate importanta a unei liste este aceea ca nodurile sale pot fi ordonate liniar functie de pozitia lor in cadrul listei. Se spune ca ai precede pe ai+1 (i=1,2,...,n-1),iar ai succede pe ai-1 (i=2,3,...,n), ai aflindu-se pe pozitia i.
Se postuleaza existenta pozitiei urmatoare ultimului element al listei si se introduce functia FIN(L) ce va returna pozitia urmatoare pozitiei n din lista L de n elemente.
Folosind notatiile anterioare si notind x:T un nod al lis- tei, iar p fiind de tip pozitie, se introduce urmatorul set reprezentativ de operatori aplicabili obiectelor de tip lista:
INSEREAZA(L,x,p)-insereaza in lista L nodul x, in pozitia p; daca L=a1,a2,...,an, in urma insertiei: p < FIN(L),L=a1,...,ap-1,x,ap+1,...,an p=FIN(L),L=a1,...,an,x p > FIN(L),rezultatul insertiei este imprevi- zibil.
Tipul Lista se defineste ca un articol cu doua cimpuri:
-primul e un tablou cu elementele de tip Nod, cu lungimea aleasa
astfel incit sa poata acoperi cea mai mare dimensiune de lista ce
apare in respectiva aplicatie;
-al doilea e pozitia ultimului nod al listei
Functia FIN(l) va returna valoarea ultim+1.
Declaratiile cele mai importante intr-o astfel de implementare sint:
const LungMax=100; type Lista=record noduri:array [1..LungMax] of Nod; ultim:integer {0..lungmax} end; Pozitie=integer; function FIN(var l:Lista):Pozitie; begin FIN:=l.ultim+1 end;Cu declaratiile de mai sus, implementarea operatorilor prezentati anterior devine simpla.
type PointerNod=^Nod; Nod=record cheie:TipCheie; urmator:PointerNod; info:TipInfo end; var inceput:PointerNod;Caracteristica unei astfel de structuri consta in prezenta unei singure inlantuiri. Cimpul cheie serveste la identificarea nodului, cimpul urmator e pointer de inlantuire la nodul urmator, iar cel info contine informatia utila.
Variabila inceput indica spre primul nod al listei; in unele situatii in locul lui inceput se utilizeaza un nod fictiv, adica o variabila de tip nod cu cimpurile cheie si info neprecizate, dar cimpul urmator indicind spre primul nod al listei.
De asemenea uneori e util a se pastra pointerul spre ultimul nod al listei.
O varianta este a listelor circulare la care dispare notiunea de prim, ultim nod, lista fiind un pointer ce se plimba pe lista.
new(q); {creaza spatiu pentru un nou nod} q^.urmator:=inceput; {asignarea cimpurilor cheie si info} inceput:=q;Secventa e corecta si pentru insertia intr-o lista vida, caz in care inceput=nil (nil fiind pointerul vid, care nu se refera la nici o variabila indicata).
new(q); {creaza spatiu pentru noul nod ultim al listei} sfirsit^.urmator:=q; q^.urmator:=nil; {asignarea cimpurilor cheie si info} sfirsit:=q;Pentru insertia la sfirsitul listei e necesara existenta a cel putin un nod, care se creaza prin procedura de la paragraful anterior.
q^.urmator:=q^.urmator^.urmator;se exclud din lista legaturile la si de la nodul de suprimat.
Pentru suprimarea nodului anterior unuia precizat, se aduce nodul precizat in cel de suprimat si se suprima succesorul lui, deci cel indicat initial de variabila pointer q:
q^:=q^.urmator^.
Mai multe liste ce contin acelasi tip Nod de elemente se vor grupa intr-un tablou cu elemente articole cu doua cimpuri: primul de tip Nod, iar al doilea de tip intreg, folosit ca si cursor.
const LMax=1000; {valoare mai mare decit suma dimensiunilor maxime ale listelor} type Cursor=0..LMax; Articol=record nodl:Nod; urmator:Cursor end; Lista=cursor; var zona:array [1..LMax] of articol; l,disponibil:Lista;Pentru fiecare lista existenta in tabloul zona se declara o variabila intrega l (de tip Lista), reprezentind cursorul spre intrarea din tablou ce contine primul nod al listei (zona[l].nodl este primul nod al listei).Nodul succesor e indicat de cursorul prezent in cimpul urmator al nodului curent. Ultimul nod al listei e in elementul de tablou ce contine in cimpul urmator o valoare invalida (0, tabloul avind primul indice 1).
Analog se defineste o lista a liberilor, continind intrarile libere din tablou inlantuite, o variabila disponibil indicind spre prima intrare libera.
function gasit(val:TipCheie;var poz:PointerNod):boolean; var found:boolean; begin poz:=inceput;found:=false; while (poz<>nil) and not found do if poz^.cheie=val then found:=true else poz:=poz^.urmator; gasit:=found end;Cautarea se poate perfectiona prin utilizarea metodei fanionului, lista prelungindu-se cu un nod fictiv numit fanion, la creare lista continind acest unic nod. In functia gasit, inainte de baleierea listei, informatia cautata se introduce in cheia nodului fanion, astfel incit va exista cel putin un nod cu cheia cautata:
var fanion:PointerNod; ... function gasit(val:TipCheie;var poz:PointerNod):boolean; begin poz:=inceput;fanion^.cheie:=val; while poz^.cheie<>val do poz:=poz^.urmator; gasit:=poz<>fanion end;
var inceput, fanion:PointerNod; procedure init; begin new(inceput); new(fanion); inceput^.urmator:=fanion end;Pentru introducerea unei noi chei in lista, pastrind ordonarea, se va scrie o functie gasit, care daca gaseste cheia in lista returneaza valoarea true si pointerii p1 spre nodul gasit si p2 spre cel anterior, respectiv in cazul negasirii cheii, valoarea false si pointerii p1 si p2 spre nodurile intre care trebuie facuta insertia:
function gasit(val:TipCheie;var p1,p2:TipPointer):boolean; begin p2:=inceput; p1:=p2^.urmator; fanion^.cheie:=val; while p1^.cheiePentru o tiparire a cheilor dintr-o lista ordonata astfel creata, pointerul ce parcurge nodurile trebuie sa fie initializat cu valoarea pointerului spre primul nod efectiv al listei, urmator celui inceput, iar parcurgerea listei se face pina la intilnirea nodului fanion:fanion) end; Fragmentul de program ce insereaza o noua cheie este: var p1,p2,p3:PointerNod;val:TipCheie; ... if not gasit(val,p1,p2) then begin new(p3); p2^.urmator:=p3; with p3^ do begin cheie:=val; {info} urmator:=p1 end end;
var p:PointerNod; ... p:=inceput^.urmator; while p<>fanion do begin {prelucrare nod} p:=p^.urmator end;
Pornind de la acest principiu, s-a conceput metoda de cautare cu reordonare, care consta in aceea ca ori de cite ori un identificator se cauta si se gaseste in lista, el se aduce la inceputul listei, astfel incit la proxima aparitie, deci cautare, el se va gasi la inceputul listei, iar daca nu s-a gasit se insereaza la inceputul listei.