Sunteți pe pagina 1din 45

Universitatea Constantin Brncui Trgu-Jiu

Facultatea de Inginerie
Departamentul de Automatic, Energie i Mediu

PROIECTAREA
ALGORITMILOR
Lect. univ. dr. Adrian Runceanu
1

Curs 4

Liste simplu nlnuite

Proiectarea Algoritmilor - curs

Coninutul cursului
4. Structuri implementate dinamic:
4.1. Stiva
4.2. Coada
4.3. Lista simplu nlnuit
4.4. Lista dublu nlnuit

Proiectarea Algoritmilor - curs

4.2. Coada

O structur de date care respect regula FIFO se numete


coad.

FIFO (First In First Out)


Primul-intrat-primul-iesit

Pentru a respecta aceast regul, vom efectua adugarea n


coada listei, iar extragerea din captul cozii.
O coad este un tip de date cu operaii caracteristice
comportrii primul venit / primul servit.
Elementul care poate servit este cel care a sosit n coad cel
mai devreme.
Dac acesta a fost scos din coad, atunci urmtorul element
care a sosit cel mai devreme devine elementul care va putea
fi servit n continuare.
Proiectarea Algoritmilor - curs

4.2. Coada

n cazul implementrii dinamice, un element al cozii


conine dou tipuri de informaii:
informaia util (inf)
i informaia de legtur (leg) - care este de fapt un pointer
ce conine adresa urmtorului element din coad.

Ultimul element al cozii nu mai are succesor, deci


informaia sa de legtur are valoarea NULL.
De asemenea, avnd n vedere c structura de coad are
dou capete (primul i ultimul) sunt necesare dou
variabile de tip referin care s indice primul element din
coad (prim) i ultimul element din coad (ultim).
n cazul n care coada este vid, prim i ultim au valoarea
NULL.
Proiectarea Algoritmilor - curs

4.2. Coada
Astfel, o reprezentare grafic a structurii de tip
coad poate arta n felul urmtor:
<- Extragere elemente

<- Adaugare elemente


NULL

prim

ultim

Proiectarea Algoritmilor - curs

4.2. Coada
Pentru implementarea dinamic a cozii, sunt
necesare urmtoarele declaraii:
typedef struct tnod
{
tip inf;
//
informatia propriu-zisa
struct tnod *leg; //
informatia de legatura
} TNOD;
TNOD *prim,*ultim; /* adresa primului, respectiv a ultimului
element din coada */

Proiectarea Algoritmilor - curs

4.2. Coada
Avnd aceste date, operaiile cu coada
folosind alocarea dinamic a memoriei, n limbajul
C++ se pot implementa astfel:
1) Iniializarea cozii:
void Creare_vida (TNOD *prim, TNOD *ultim)
{
prim=ultim=NULL;
}
Proiectarea Algoritmilor - curs

4.2. Coada
2) Adugarea unui element x n coad:
Avnd n vedere definiia structurii de coad,
se poate face observaia c adugarea unui
element se efectueaz numai la sfritul cozii,
dup ultimul element.
Dac coada este vid, atunci la inserarea unei
valori se creeaz de fapt primul element al cozii.
n acest caz, prim i ultim indic acelai
element (au aceeai valoare).
Proiectarea Algoritmilor - curs

4.2. Coada
Astfel etapele acestei operaii sunt:
Alocarea unei zone de memorie pentru noul element -(a)
Se introduce informaia util pentru acest element - (b)
Informaia de legatur a elementului creat se
completeaz cu NULL - (c)
Se reiniializeaz informaia de legatur a elementului
indicat de ultim cu adresa noului element - (d)
Se modific valoarea pointerului ultim dndu-i ca
valoare adresa noului element introdus - (e)
Proiectarea Algoritmilor - curs

10

void adaug(tip x, TNOD *ultim)


{
TNOD *p;
// pointer de lucru
if (prim==NULL)
{
prim=ultim=new TNOD;
prim->inf=x;
prim->leg=NULL;
}
else
{
p=new TNOD;
// (a)
p->inf=x;
// (b)
p->leg=NULL;
// (c)
ultim->leg=p;
// (d)
ultim=p;
// (e)
}
}
Proiectarea Algoritmilor - curs

11

4.2. Coada
Adugarea unui element ntr-o coad nevid
se poate reprezenta grafic astfel:
NULL

prim

NULL

ultim

Proiectarea Algoritmilor - curs

12

4.2. Coada
Dac coada era iniial vid, dup adugarea
unui element arat astfel:
NULL

prim

ultim

Proiectarea Algoritmilor - curs

13

4.2. Coada
3) Extragerea unui element din coad (a
primului element)
Operaia de extragere se poate face doar asupra
primului element din coad.
Bineneles, putem extrage un element numai
dintr-o coad care nu este vid.
Se observ c primul element din coad fiind
eliminat, va fi nlocuit de cel care iniial era al
doilea.
Proiectarea Algoritmilor - curs

14

4.2. Coada
Deci, se pot deduce urmtoarele etape ale extragerii
din coad:
Se reine ntr-o variabil (*q) informaia util din primul
element al cozii - (a)
Se reine ntr-un pointer de lucru adresa acestui element
(s numim pointerul de lucru p) - (b)
Se actualizeaz valoarea pointerului prim cu adresa
urmtorului element din coad - (c)
Se elibereaz zona de memorie ce fusese alocat iniial
primului element din coad (acum indicat de pointerul p) (d)
Proiectarea Algoritmilor - curs

15

4
void extrag(TNOD *prim, tip *q)
{
TNOD *p;
// pointer de lucru
*q=prim->inf;
// (a)
p=prim;
// (b)
prim=prim->leg; // (c)
delete p;
// (d)
}
Operaia de tergere, se poate
reprezenta grafic astfel:
NULL

ultim

prim

Proiectarea Algoritmilor - curs

16

4
4) Verificarea dac coada este vid
int cvida (TNOD *prim)
{
return (prim==NULL);
}
5) Numrarea elementelor din coad
int cardinal (TNOD *prim)
{
int m=0;
// contorizeaz elementele cozii
TNOD *p;
// pointer de lucru
p=prim;
while(p != NULL)
{
m++;
p=p->leg;
}
return m;
}
Proiectarea Algoritmilor - curs

17

Coninutul cursului
4. Structuri implementate dinamic:
4.1. Stiva
4.2. Coada
4.3. Lista simplu nlnuit
4.4. Lista dublu nlnuit

Proiectarea Algoritmilor - curs

18

4.3. Lista simplu nlnuit


Lista simplu nlnuit este structura de
reprezentare a informaiilor cea mai cunoscut
i implicit cea mai utilizat atunci cnd ne
referim la alocarea dinamic a memoriei.

O list simplu nlnuit este format


dintr-o colecie de elemente de acelai tip.

Proiectarea Algoritmilor - curs

19

4.3. Lista simplu nlnuit


Fiecare element conine n afar de elementul
propriu-zis i o legatur care ne spune unde
putem gsi un alt element din mulime.
Elementele listei vor fi numite i noduri.
Ideea este c fiecare nod dintr-o list simplu
nlnuit conine informaii despre cum putem
localiza un alt nod dintr-o mulime de noduri.
Accesul imediat la fiecare nod din mulime nu
este necesar pentru c fiecare nod conduce la un
altul.
Proiectarea Algoritmilor - curs

20

4.3. Lista simplu nlnuit


Acest tip de element se numeste NOD.

inf

leg

Prin inf nelegem informaia ataat


elementului respectiv, i care poate fi de orice
tip de date cunoscut de ctre limbajul C++,
iar prin leg nelegem un cmp de tip referin
care va conine adresa urmtorului element
din mulimea de elemente.
Proiectarea Algoritmilor - curs

21

4.3. Lista simplu nlnuit


Pentru a putea construi i a folosi ct mai eficient
o list simplu nlnuit este necesar o variabil
de tip referin care s indice primul element din
list.
Convenim s notm cu prim adresa primului
nod.
Uneori, ntlnim aplicaii care necesit i
folosirea adresei ultimului nod, notat cu ultim.
Proiectarea Algoritmilor - curs

22

4.3. Lista simplu nlnuit


O form grafic sugestiv pentru o list
simplu nlnuit ar fi urmtoarea:

Inf1

Inf2

Inf3

Infn

NULL

ultim

prim
Proiectarea Algoritmilor - curs

23

Avantaje

Listele simplu nlnuite reprezint o utilizare


foarte importanta a alocarii dinamice a memoriei
deoarece:
1. Sunt mai flexibile dect stiva i coada (care
restricioneaz operaiile de adugare, acces i
tergere a elementelor conform definiiilor lor)
2. Se recomand folosirea listelor simplu nlnuite n
rezolvarea problemelor specifice vectorilor, deoarece
se utilizeaz eficient memoria care poate fi alocat
sau eliberat n funcie de cerinele programatorului
3. Anumite genuri de probleme (cum ar fi operaiile cu
matrici rare; respectiv polinoame rare) i gsesc o
rezolvare mai rapid, eficient i util folosind listele
Proiectarea Algoritmilor - curs

24

4.3. Lista simplu nlnuit


Declaraiile necesare lucrului cu o list
simplu nlnuit sunt:
typedef struct tnod
{
tip inf;
// informatia propriu-zisa
struct tnod *leg;
// informatia de legatura
} LISTA;
LISTA *prim,*ultim; /* adresa primului, respectiv a
ultimului element din lista */
Proiectarea Algoritmilor - curs

25

4.3. Lista simplu nlnuit


Cu listele simplu nlnuite se pot face
urmtoarele operaii:
1) Iniializarea listei (crearea unei liste vide)
void init(TNOD *prim)
{
prim=NULL;
}

Proiectarea Algoritmilor - curs

26

4.3. Lista simplu nlnuit


2) Adugarea unui element n list
Aceasta operaie se poate face n trei
moduri, n funcie de locul unde se insereaz
elementul n list.
Astfel putem avea:
a) Inserarea unui element la nceputul listei
b) Inserarea unui element la sfritul listei
c) Inserarea unui element n interiorul listei

Proiectarea Algoritmilor - curs

27

4.3. Lista simplu nlnuit


a) Adugarea unui element la nceputul listei
se poate reprezenta grafic astfel:

nou

Inf1

Inf2

Inf3

prim

Infn

NULL

ultim

Proiectarea Algoritmilor - curs

28

4
Etapele adugarii unui element la nceputul listei:
alocarea zonei de memorie necesare noului element (Se
folosete un pointer de lucru p) - (a)
completarea informaiei utile pentru noul element (notat
cu nou) - (b)
completarea informaiei de legtur cu adresa coninut
n variabila prim (innd cont c acesta va deveni primul
element al listei i, conform definirii acesteia, trebuie s
conin adresa elementului urmtor din list, deci cel
care era primul nainte de a face inserarea) - (c)
Actualizarea variabilei referin prim cu adresa
elementului creat, care n acest moment devine primul
element al listei - (d)
Proiectarea Algoritmilor - curs

29

4.3. Lista simplu nlnuit


void adaug_la_inceput( tip x, LISTA *prim )
// x reprezinta informatia ce se adauga la nceputul listei

{
LISTA *p;
p=new LISTA;
p->inf=x;
p->leg=prim;
prim=p;

// pointerul de lucru
// (a)
// (b)
// (c)
// (d)

}
Proiectarea Algoritmilor - curs

30

4.3. Lista simplu nlnuit


b) Adugarea unui element la sfritul listei,
presupune inserarea acestuia dup ultimul nod
al listei.
n acest caz avem nevoie de variabila ultim
care indic nodul dup care se va insera.

Proiectarea Algoritmilor - curs

31

4.3. Lista simplu nlnuit


Descrierea operaiilor necesare se pot
deduce i de aceast dat folosind o
reprezentare grafic a listei:
Inf1

Inf2

Inf3

prim

Infn

NULL

nou

NULL

ultim

Proiectarea Algoritmilor - curs

32

Paii algoritmului de adugare a unui element


la sfritul listei:
Alocarea zonei de memorie necesar pentru noul
element - (a)
Completarea informaiei de legtur a elementului
creat cu NULL, deoarece el va deveni ultim
element - (b)
Completarea informaiei utile - (c)
Informaia de legatur a celui ce a fost nainte
ultimul element al listei i schimb valoarea cu
adresa noului element (l va indica pe acesta) - (d)
Se actualizeaz pointerul ultim cu adresa nodului
adugat listei - (e)
Proiectarea Algoritmilor - curs

33

4.3. Lista simplu nlnuit


void adauga_la_sfarsit( tip x, LISTA *ultim )
// realizeaza adaugarea valorii x la sfaritul listei

LISTA *p;
p=new LISTA;
p->leg=NULL;
p->inf=x;
ultim->leg=p;
ultim=p;

// pointer de lucru
// (a)
// (b)
// (c)
// (d)
// (e)

}
Proiectarea Algoritmilor - curs

34

4
c) Adugarea unui element n interiorul listei
Aceast operaie se poate face naintea sau
dup un element al listei.
Cel mai comod se face inserarea dup un
element specificat al listei.

Deoarece se realizeaz o inserare dup un nod,


acest lucru poate determina o adugare la
sfritul listei n cazul n care nodul respectiv
este ultimul nod din aceast list, operaie
descris anterior n funcia adaug_la_sfarsit.
Proiectarea Algoritmilor - curs

35

4
Sunt necesari doi pointeri de lucru:
q indic nodul dup care este facut
inserarea
p pointer de lucru necesar pentru crearea
unui nou element

Presupunem c avem o list cu cel puin dou


elemente, unde dup nodul indicat de q vom
aduga un nou element cu valoarea
informaiei propriu-zise x.

Proiectarea Algoritmilor - curs

36

4.3. Lista simplu nlnuit

Inf1

Inf2

Inf3

nou

prim
q

Infn

NULL

ultim

Proiectarea Algoritmilor - curs

37

4.3. Lista simplu nlnuit


Succesiunea logic a etapelor necesare inserrii dup
un nod (indicat de q) este urmtoarea:
alocarea zonei de memorie necesar noului element
(folosirea pointerului p) - (a)
iniializarea informaiei utile ( cu valoarea notat nou ) - (b)
iniializarea informaiei de legtur cu adresa urmtorului
nod (cu adresa reinut n acest moment n variabila q->leg)
- (c)
actualizarea informaiei de legatur din nodul dup care s-a
inserat noul element cu adresa zonei de memorie alocat
pentru acesta (p) - (d)

Proiectarea Algoritmilor - curs

38

4.3. Lista simplu nlnuit


void adaug_dupa_o_valoare( int x, LISTA *q)
{ // adauga valoarea lui x ntr-un nod ce urmeaza nodului
indicat de q n lista

LISTA *p;
p=new LISTA;
p->inf=x;
p->leg=q->leg;
q->leg=p;

// pointer de lucru
// (a)
// (b)
// (c)
// (d)

}
Proiectarea Algoritmilor - curs

39

4.3. Lista simplu nlnuit


Cealalt situaie de inserare a unui nod n interiorul listei
este de a realiza aceasta naintea unui nod indicat de q.
Pentru aceast situaie putem folosi urmtoarea solutie,
care este cea mai utilizat fiind mai rapid i eficient i va fi
descris n urmtorii pai:
- alocarea unei zone de memorie pentru noul element, dar cu
scopul de face inserare dup nodul referit de q (folosind pe
p) - (a)
- se completeaz acest nod cu informaia *q (se realizeaz o
dublur a informaiei propriu-zise din nodul indicat de q) (b)
- se actualizeaz cmpurile inf i leg din nodul q - (c,d)
Proiectarea Algoritmilor - curs

40

4.3. Lista simplu nlnuit


Reprezentarea grafic corespunztoare
este urmtoarea:
Inf1

Inf2

prim

nou

Inf3

Infn

NULL

ultim
q

Proiectarea Algoritmilor - curs

41

4.3. Lista simplu nlnuit


void adaug_inainte_de_o_valoare( tip x, LISTA *q )
{
LISTA *p;
// pointer de lucru
p=new LISTA; // (a)
p->inf=q->inf;
// (b)
p->leg=q->leg; // (b)
q->inf=x;
// (c)
q->leg=p;
// (d)
}
Proiectarea Algoritmilor - curs

42

3. Traversarea ( parcurgerea ) listei


Reprezint o operaie necesar pentru afiarea sau
prelucrarea elementelor listei, ce const n trecerea prin
fiecare element al listei o singur dat.
Se folosete un pointer de lucru pe care-l voi nota cu p i
care va fi iniializat cu valoarea prim, iar apoi i va
schimba valoarea cu adresa nodului urmtor (folosind
atribuirea p=p->leg), ceea ce se va repeta pn cnd p va
avea valoarea NULL (ceea ce nseamn c a fost prelucrat
i ultimul nod).
La fiecare schimbare a valorii pointerului p, se va afia
informaia util din nodul indicat de p.
Bineneles, lista nu trebuie s fie vid.
Parcurgerea unei liste simplu nlnuite se face secvenial,
ntr-un singur sens, de la primul ctre ultimul nod.
Proiectarea Algoritmilor - curs

43

4.3. Lista simplu nlnuit


Afiarea elementelor listei pentru exemplificarea
procedurii de parcurgere a listei:

void parcurgere ( LISTA *prim )


{
LISTA *p;
p=prim;
while (p!=NULL)
{
cout<<p->inf;
p=p->leg;
}
}
Proiectarea Algoritmilor - curs

44

ntrebri?

Proiectarea Algoritmilor - curs

45

S-ar putea să vă placă și