Sunteți pe pagina 1din 5

Laborator 8.

Liste
1. Scopul lucrrii practice
Aceast lucrare practic familiarizeaz studenii cu tipul abstract de date - liste,
prezentnd n acelai timp i cteva aplicaii practice ale acestora.
2. Mod de desfurare a lucrrii
n prima parte, se vor prezenta aspecte teoretice legate de tipul abstract de date liste. e
va prezenta implementarea listelor cu a!utorul irurilor i a pointerilor. e vor implementa
principalele operaii pe liste. "a aplicaii ale listelor, se vor considera stivele i cozile.
tudenii trebuie sa implementeze practic toi algoritmii i metodele enunate n aceast
lucrare. #e asemenea, se vor prezenta cteva probleme propuse spre rezolvare.
3. Liste aspecte teoretice
"istele sunt secvene de $ sau mai multe elemente de acelai tip. "istele pot fi
reprezentate ca i o secven de elemente separate de virgul% n
a a a ,..., ,
& ' .
n este lungimea listei ( $ n ). #ac ' n , atunci
'
a este primul element al listei iar
n
a
este ultimul element. #ac n = 0 se spune c lista este vid. #e asemenea, se spune
c
i
a
il precede pe
' + i
a
i
i
a
il succede pe
' i
a
.
"istele sunt structuri fle*ibile, deoarece pot crete i se pot micora la cerere, ocupnd
doar spaiul necesar de memorie, spre deosebire de siruri, pentru care trebuie alocat un
spaiu de memorie initial, fr ca acesta s fie folosit n totalitate. #e asemenea, listele
pot fi concaternate, imprite n subliste, i sunt folosite n aplicaii precum memorarea i
e*tragerea rapid a informaiilor, translatoare, simulatoare etc.
+iind dat o list L, un obiect x de tipul obiectelor din list i o poziie p, definim
urmtoarele operaii pe list%
'. insert(x,p,L)% insereaz elementul x pe poziia p n lista L, mutnd elementele de pe
poziii mai mari sau egale cu p pe poziia imediat urmtoare. Astfel, dac lista este%
n p p
a a a a a ,..., , ,..., ,
' & ' , dup inserare lista devine% n p p
a a x a a a ,..., , , ,..., ,
' & '
&. locate(x,L)% aceast funcie returneaz poziia elementului x n list. #ac x apare de
mai multe ori n list se returneaz poziia primei apariii. n cazul n care elementul
cutat nu apare n list, se va returna ,-"".
.. retrieve(p,L)% returneaz elementul de la poziia p din list. n cazul n care rspunsul
e nedefinit, se returneaz ,-"". #e obicei, se va returna un pointer la elementul de
pe poziia p.
/. delete(p,L)% terge elementul de la poziia p din list. 0ezultatul e nedefinit (eroare),
dac lista nu are poziia p dprit a se terge. #up o stergere reuit, lista " devine%
n p p
a a a a a ,..., , ,..., ,
' ' & ' + .
1. next(p,L) i previous(p,L)% returneaz elementul urmtor (respectiv precedent) din
lista ".
2. makenull(L): determin creerea unei liste vide.
3. first(L): returneaz prima poziie din list. #ac lista e vid se returneaz null.
4. printlist(L): afieaz lista.
5oate aceste operaii abstracte trebuiesc definite n cazul diverselor tipuri de implementri
a listelor. 6mplementrile specifice ale acestor operaii difer, n funcie de cazul tipul
concret de implementare a listei, considerat. Aceste operaii pot fi folosite pentru a defini
operaii mai comple*e pe liste.
3.1 Implementarea listelor folosind iruri
7lementele listei sunt stocate n celule contigue (succesive) ale unui ir. +olosind aceast
implementare, traversarea listei i adugarea elementelor la sfrit devin operaii foarte
facile. 6nserarea unui element la mi!locul listei devine o operaie foarte costisitoare
deoarece presupune mutarea tuturor celorlalte elemente cu o poziie mai !os. 8tergerea
unui element (cu e*cepia ultimului) devine de asemenea, costisitoare.
' +irst element
& econd element
"ast element
9a*lengt:
Fig. 1. 6mplementarea listelor cu iruri
#eci, se folosete pentru implementare un ir pentru care se aloc maxlength elemente.
"ista e o structur care conine spaiul alocat irului i un inde* care va memora poziia n
ir a ultimului element al listei. #e asemenea, avem o funcie care returneaz poziia din
ir unde se va memora ultimul element al irului. e observ limitarea mrimii listei de
spaiul de memorie alocat irului care implementeaz lista.
e vor consulta implementrile furnizate pentru aceast poriune de seminar.
3.2 Implementarea listelor folosind pointeri i alocare dinamic
Aceast implementare folosete celule legate ntre ele prin pointeri. Astfel, fiecare celul
a listei conine un cmp care memoreaz valoarea elementului listei, i un cmp care
conine un pointer ctre urmtoarea celul a listei (liste simplu nlnuite).
,u mai e necesar alocarea unui spaiu contiguu de memorie (ca n implementarea cu
iruri), i nu vom mai fi nevoii s mutm elemente pentru a face o inserare ; tergere de
la mi!locul listei. 9emoria se aloc dinamic, pe msur ce e nevoie de noi elemente n
list. <reul pe care l pltim pentru aceast facilitate, e creterea spaiului necesar
lista
paiu liber
memorrii unui element, prin nevoia de a memora pointerul de legtur. +igura & prezint
o asemenea list simplu inlnuit.
'
a
&
a =
n
a

Fig. 2. "ista simplu nlnuit
A se vedea implementrile operaiilor pe liste simplu nlnuite.
e vor vizualiza operaiile sensibile pe liste% inserarea i tergerea elementelor.
Obsera!ie"
"ista e un tip abstract de date. Aceasta nseamn definirea listei, precum i a operaiilor
pe liste. #eci, indiferent de modul de implementare, funcionalitatea definit pentru
operaii trebuie s rmn aceeai. #eci, dac scriem un program care folosete definiia
listei i definiiile operaiilor pe liste, acesta trebuie sa funcioneze corect, indiferent de
implementarea furnizata funciilor.
#in programele furnizate de observ urmtoarele%
- fiierul list.: definete lista i operaiile pe liste. n acest fiier se dau dou definiii
pentru list, corespunztor celor & moduri de implementare. 5ot n acest fiier, se
definesc operaiile pe liste, prin prototipuri de funcii. A se observa modul de utilizare
a instruciunilor ctre preprocesor (>define, >ifndef, >ifdef).
- +iierul client"ist.c folosete interfaa definit de fiierul list.:. deci, acest fiier,
poate fi scris fr s avem la dispoziie implementarea operaiilor definite n fiierul
list.:. ?odul va compila, (comanda% gcc c client"ist.c), dar pentru a obine un fiier
e*ecutabil, trebuie s se furnizeze fiierul cu implementarea tuturor funciilor utilizate
- +iierele listsir.c i listpointer.c realizeaz cele dou tipuri de implementri. Acestea
trebuiesc furnizate pentru a obine fiierele e*ecutabile.
?omanda pentru obinerea e*ecutabilelor este%
gcc o listir listsir.c client"ist.c
gcc o list<ointer listpointer.c client"ist.c
Inconenient provenit din deficienele limba!ului ?% n fisierul client"ist.c trebuie s se
indice la nceput (linia >define) care implementare e utilizat, pentru c sunt necesare n
acest fiier definirile de tipuri din fiierul list.:, iar ? nu permite amnarea realizrii
acestora. Astfel, nu se pot defini tipuri abstracte, care sa fie efectiv definite ulterior
(implementare), deci aceste definiri trebuiesc realizate efectiv. Aceasta spre deosebire de
definirea funciilor, care poate fi amnata (n fiierul list.: se furnizeaz doar prototipul,
implementarea funciilor este furnizata abia la compilare).
e observ n aceast te:nic de organizare a programului un e*emplu :ibrid de client-
server. Adic, fiierul (surs) client"ist.c reprezint un client care utilizeaz serviciile
:eader
list
(funciile) oferite de fiierele de implementare (listsir.c respectiv listpointer.c), prin
intermediul interfeei din list.:.
3.3 Liste dublu #nlan!uite
7lementele listelor dublu nlnuite conin referine att ctre elementul urmtor din list ct i
ctre elementul precedent. Astfel, se permite o parcurgere uoar a acestor liste n ambele direcii.
#e asemenea, pentru a indica elementul i din list, n acest caz e suficient s avem un pointer la
acest element, spre deosebire de listele simplu nlnuite, unde era nevoie s avem un pointer la
elementul anterior elementului i. +igura . reprezint sc:ematic acest tip de liste.
= =
Fig. 3. "ista dublu nlnuit
3.$ Liste circulare
"istele circulare prezint urmtoarea caracteristic% ultimul element va referi ntotdeauna
primul element al listei. "istele circulare pot fi simplu sau dublu nlnuite. @peraiile pe
liste circulare sunt similare cu cele pe liste simple.
$. %ficien!a listelor
e pune intrebarea care implementare a listelor e preferatA
0spunsul la aceast intrebare depinde foarte mult de frecvena operaiilor asupra listelor,
anume, ce operaii sunt mai des folositeA #e asemenea, numrul elementelor pe care le
vom stoca n liste influeneaz eficiena acestora.
Bom reine urmtoarele aspecte%
- la implementarea cu iruri, e necesar s se specifice la compilare dimensiunea
ma*im a listei. #ac n problema concret, nu cunoatem mrimea listei pe care
dorim s o folosim, acest aspect reprezint un dezavanta!, i va trebui s folosim
implementarea cu pointeri.
- @peraiile de insert i delete pe implementrile cu pointeri necesit un numr relativ
constant de pai, deci acestea se vor e*ecuta cam cu aceasi vitez. "a implementarea
cu iruri, pe lng operaia de localizare a poziiei de inserare;tergere e necesar
mutarea tuturor elementelor care urmeaz acelei poziii, deci timpul e proporional cu
distana elementului modificat fa de captul listei. n sc:imb, operaiile de
localizare sunt mult mai rapide cu implementarea cu siruri. #eci, dac avem o
frecven mare a operaiilor insert-delete, se va considera implementarea cu pointeri,
dac avem o frecven mare a operaiilor de regsire aleatoare se va considera
implementarea cu iruri.
- 6mplementarea cu siruri de obicei gestioneaz ineficient memoria alocat, deoarece
nu se foloseste n mod util intreg spaiul alocat pentru lista.
&em"
'. e vor implementa operaiile de baz pentru liste dublu inlnuite i liste circulare.
&. se scrie un program care realizeaz operaiile insert, delete, locate pentru o lista
simplu inlnuit, avnd n fiecare moment elementele ordonate cresctor. e va
considera implementarea cu pointeri.
.. se scrie un program care unete dou liste ordonate, rezultatul fiind tot o list
ordonat (liste simplu inlnuite, implementare cu pointeri).
/. se scrie un program care inverseaz o list simplu inlnuit implementat prin
pointeri dintr-o singur parcurgere a listei.