Sunteți pe pagina 1din 7

191

5. STIVA I COADA

5. STIVA I COADA
5.1. Stiva
Stiva este o structur de date abstract pentru care att operaia de
inserare a unui element n structur, ct i operaia de extragere a unui
element se realizeaz la un singur capt, denumit vrful stivei.
Singurul element din stiv la care avem acces direct este cel de la vrf.
Operaii caracteristice

...

Singurele operaii ce pot fi executate cu o stiv sunt:


 crearea unei stive vide;
 inserarea unui element n stiv (operaie denumit n
literatura de specialitate PUSH1)
 extragerea unui element din stiv (operaie denumit n
termeni de specialitate POP2)
 accesarea elementului de la vrf (operaie denumit TOP3).

5
10
0
7

Vrf

Ca s ne imaginm mai bine funcionarea unei stive, s ne gndim cum lucrm cu un


teanc de farfurii. Cnd dorim s punem o farfurie n teanc, o punem deasupra, cnd dorim
s lum o farfurie din teanc, o lum tot pe cea de deasupra. Motivul este lesne de neles:
nu ne-am propus s spargem farfuriile!

Acest mod de funcionare face ca ultimul element inserat n stiv s fie primul
extras. Din acest motiv, stiva este definit i ca o structur de date care funcioneaz dup principiul LIFO (Last In First Out Ultimul Intrat Primul Ieit).

Care este utilitatea stivelor?


n informatic stiva joac un rol fundamental. Pentru a nelege mecanisme
fundamentale ale programrii (de exemplu, funciile sau recursivitatea) este
necesar cunoaterea noiunii de stiv. Pe scurt, stiva este util n situaii n care
este necesar memorarea unor informaii i regsirea acestora ntr-o anumit
1. n traducere exact, PUSH nseamn a mpinge. Termenul sugereaz o imagine plastic:
imaginndu-ne stiva ca un sac, PUSH ar nsemna c mpingem nuntru un element, prin captul
superior (nu prin mijloc sau pe la fundul sacului).
2. n traducere, POP nseamn a scoate cu zgomot (de exemplu dopul, etc), a descrca (pistolul,
etc), a iei repede sau pe neateptate (Levichi, Leon; Banta, Andrei Dicionar englez-romn).
Imaginea este de asemeni sugestiv: POP este operaia prin care primul element, cel de deasupra,
sare din structur (sau din sac, ca s pstrm analogia).
3. n traducere, TOP nseamn vrf.

Prof. E. Cerchez; prof. M. erban

192

5. STIVA I COADA

ordine, descris de principiul LIFO. Stiva este utilizat atunci cnd programul
trebuie s amne execuia unor operaii, pentru a le executa ulterior, n ordinea
invers a apariiei lor. Operaia curent este cea corespunztoare vrfului stivei, n
stiv fiind reinute toate informaiile necesare programului pentru a executa
operaiile respective.

Cum implementm o stiv?


Stiva este o structur de date abstract, ce poate fi implementat n diferite
moduri. De exemplu, putem implementa o stiv ca un vector n care reinem
elementele stivei. Pentru ca acest vector s funcioneze ca o stiv, singurele operaii
permise sunt operaiile caracteristice stivei.
Pentru exemplificare, s prezentm declaraiile necesare pentru implementarea
unei stive cu elemente de tip int:
#define DimMax 100
//numarul maxim de elemente din stiva
typedef int Stiva[DimMax];
//tipul Stiva implementat ca vector
Stiva S;
//stiva
int
vf;
//varful stivei

Crearea unei stive vide


Pentru a crea o stiv vid iniializm vrful stivei cu -1 (vrful stivei indic
ntotdeauna poziia ultimului element introdus n stiv; elementele sunt memorate
n vector ncepnd cu poziia 0):
vf=-1;

Inserarea unui element n stiv


Pentru a insera un element x n stiva S trebuie s verificm n primul rnd dac
avem loc, deci dac stiva nu este plin. Dac stiva este plin, inserarea nu se
poate face, altfel vom mri vrful stivei i vom plasa la vrf noul element.
De exemplu, dac dorim s inserm elementul x = 3 n stiva din figura
urmtoare, obinem:
...

...

5
10
0
7

3
5
10
0
7

vf

Prof. E. Cerchez; prof. M. erban

vf

193

5. STIVA I COADA

Stiva S nainte de inserare

Stiva S dup inserare

if (vf == DimMax-1)
//stiva este plina
cout<<"Eroare - stiva este plina\n";
else
//inseram elementul x in stiva S
S[++vf] = x;

Extragerea unui element din stiv


Pentru a extrage un element dintr-o stiv S trebuie s verificm n primul rnd
dac exist elemente n stiv (deci dac stiva nu este vid). Dac da, reinem
elementul de la vrful stivei ntr-o variabil (s o notm x), dup care micorm cu
o unitate vrful stivei. De exemplu, dac extragem un element din stiva din figura
urmtoare, obinem:
...

5
10
0
7

...

vf

Stiva S nainte de extragere

10
0
7

vf

Stiva S dup extragere

if (vf<0)
//stiva este vida
cout<<"Eroare - stiva este vida\n";
else
//extragem elementul de la varf
x = S[vf--];

Accesarea elementului de la vrf


Prin modul su restrictiv de funcionare, stiva permite numai accesarea elementului de la vrf. Dac dorim s aflm valoarea unui alt element al stivei, ar trebui s
golim stiva (deci s extragem succesiv elemente) pn la elementul dorit.
Accesarea elementului de la vrf presupune determinarea valorii acestuia, valoare
pe care noi o vom reine ntr-o variabil denumit x.
x = S[vf];

Observaii
1. Dezavantajul implementrii unei stive ca vector alocat static const n faptul c
indiferent de numrul de elemente existente n stiv, dimensiunea zonei de
memorie alocat stivei este aceeai (DimMax).
2. Pentru a executa operaii cu stiva alocat static este suficient s cunoatem
vrful stivei. Ca s reinem mai uor modul de funcionare a stivei, ne imaginm
c la inserare vrful stivei urc, iar la extragere vrful coboar.
Prof. E. Cerchez; prof. M. erban

194

5. STIVA I COADA

5.2. Coada
Coada este o structur de date abstract, pentru care operaia de inserare a
unui element se realizeaz la un capt, n timp ce operaia de extragere a
unui element se realizeaz la cellalt capt.
Singurul element din coad la care avem acces direct este cel de la nceput.
...

10

Inc

...

Sf

Operaii caracteristice
Singurele operaii ce pot fi executate cu o coad sunt:
 crearea unei cozi vide;
 inserarea unui element n coad;
 extragerea unui element din coad;
 accesarea unui element.
Executarea acestor operaii asupra unei cozi presupune cunoaterea nceputului
cozii (s-l notm Inc) i a sfritului acesteia (s-l notm Sf).
Modul de funcionare a unei cozi este foarte uor de intuit: toat lumea a stat la
coad, mcar o dat. Orice situaie n care sunt mai multe cereri de acces la o resurs
unic (de exemplu, mai muli clieni i o singur vnztoare; o singur pomp de benzin
i mai multe maini, un singur pod i mai multe capre, etc) necesit formarea unei linii de
ateptare. Dac nu apar alte prioriti, cererile sunt satisfcute n ordinea sosirii.

Datorit faptului c ntotdeauna este extras (servit) primul element din coad,
iar inserarea oricrui nou element se face la sfrit (la coad), coada este definit
ca o structur de date care funcioneaz dup principiul FIFO (First In First Out
Primul Intrat Primul Ieit).

Care este utilitatea unei cozi?


Utilitatea structurii de tip coad reiese din modul su de funcionare este necesar utilizarea unei cozi atunci cnd informaiile trebuie prelucrate exact n ordinea
n care au sosit i ele sunt reinute n coad pn cnd pot fi prelucrate. n informatic, cozile sunt utilizate frecvent. De exemplu, s considerm c avem o reea
de calculatoare i o singur imprimant. Cnd utilizatorii reelei vor da comenzi de
tiprire, imprimanta nu poate rspunde tuturor comenzilor n acelai timp
(imaginai-v ce-ar iei!). Prin urmare comenzile de tiprire primite sunt nregistrate ntr-o coad (Print Queue Coad de Tiprire). Imprimanta va tipri documentele pe rnd, n ordinea n care au fost nregistrate n coad. Un alt exemplu:
pentru a mri viteza de execuie, microprocesoarele Intel utilizeaz o coad de
instruciuni n care sunt memorate instruciunile care urmeaz a fi executate.
Prof. E. Cerchez; prof. M. erban

195

5. STIVA I COADA

Cum implementm o coad?


Coada este o structur de date abstract, care poate fi implementat n diferite
moduri. Ca i n cazul stivei, coada poate fi implementat static, reinnd
elementele sale ntr-un vector.
S considerm urmtoarele declaraii care reprezint o coad cu elemente de tip
int alocat static:
#define DimMax 100
//numarul maxim de elemente din coada
typedef int Coada[DimMax];
//tipul Coada implementat ca vector
Coada C;
//coada
int Inc, Sf;
//inceputul si sfarsitul cozii

Elementele cozii sunt memorate n vector de la poziia Inc pn la poziia Sf,


deci numrul lor este Sf-Inc+1.
Crearea unei cozi vide
Pentru a crea o coad vid trebuie s iniializm variabilele Inc i Sf astfel:
Inc = 0;
Sf = -1;

Observai c numrul de elemente din coad este 0, iar poziia pe care va fi


plasat primul element din coad este 0.
Inserarea unui element n coad
Pentru a insera un element x n coada C trebuie s verificm n primul rnd dac
avem loc, deci dac variabila Sf nu depete dimensiunea maxim a vectorului.
Dac inserarea se poate face, vom mri valoarea variabilei Sf cu o unitate (coada
crete) i vom plasa la sfrit noul element.
De exemplu, s inserm elementul x = 3 n coada din figura urmtoare:
...
5
10 4
2
...
Inc

Sf

Coada C nainte de inserare


...

10

Inc

...

Sf

Coada C dup inserare


if (Sf == DimMax-1)
cout<<"Eroare\n";
else
C[++Sf] = x;

Prof. E. Cerchez; prof. M. erban

//nu mai avem loc


//inseram elementul x in coada C

196

5. STIVA I COADA

Extragerea unui element din coad


Pentru a extrage un element dintr-o coad C trebuie s verificm n primul rnd
dac numrul de elemente din coad este diferit de 0 (coada nu este vid). Dac da,
reinem elementul de la nceputul cozii ntr-o variabil (s o notm x), dup care
mrim cu o unitate nceputul cozii.
De exemplu, s extragem un element din coada din figura urmtoare:
5

...

10

Inc

...

Sf

Coada C nainte de extragere


...

10
Inc

...

Sf

Coada C dup extragere


if (Inc > Sf)
cout<<"Eroare \n";
else
x = C[Inc++];

//coada este vida


//extragem primul element

Accesarea unui element


Singurul element al unei cozi care poate fi accesat direct este primul. Dac
dorim s aflm valoarea unui alt element, va trebui s extragem succesiv elemente
pn la cel dorit.
Accesarea primului element are ca scop determinarea valorii acestuia, valoare
pe care o vom reine ntr-o variabil denumit x.
x = C[Inc];

Observaie
n acest mod de alocare static a unei cozi observai c pe msur ce inserm i
extragem elemente, att sfritul, ct i nceputul cozii migreaz ctre limita
maxim a vectorului. Dezavantajul este c n vector rmn poziii neutilizate (de la
0 pn la Inc-1). De exemplu, ar putea s apar o situaie n care coada conine
un element, dar operaia de inserare s nu fie posibil pentru c
Inc=Sf=DimMax-1. O soluie mai bun ar fi de a reutiliza circular spaiul de
memorie alocat cozii. Pentru aceasta, urmtoarea poziie dup poziia i poate fi:
- i+1, dac i<DimMax -1
- 0, dac i=DimMax-1
Acest lucru se poate scrie concis: (i+1)%DimMax.
Prof. E. Cerchez; prof. M. erban

197

5. STIVA I COADA

Caroiaj
Se consider un caroiaj dreptunghiular cu m linii i n coloane, n care pe
anumite poziii sunt plasate obstacole. n poziia iniial (x0,y0) se afl plasat un
mobil. S se determine, pentru toate poziiile n care mobilul poate ajunge, distana
minim de la poziia iniial a mobilului, msurat n deplasri elementare. Prin
deplasare elementar se nelege deplasarea mobilului cu o poziie stnga, dreapta,
sus sau jos.
Labirint
Se d un labirint dreptunghiular de dimensiuni nxm (n,m100). Poziiile din
stnga sus i dreapta jos sunt marcate cu 0, celelalte conin unul dintre numerele 1,
2, 3, 4. Scopul este de a parcurge labirintul din colul stngasus pn la colul din
dreaptajos pe un drum de lungime minim, pe direcii paralele cu laturile sale.
Drumul urmat trebuie s plece din 0 n 1, apoi din 1 n 2, din 2 n 3 din 3 n 4, din
4 n 1 etc. Se poate ajunge n poziia final din oricare poziie vecin ei.
Din fiierul de intrare INPUT.TXT se vor citi de pe prima linie numerele
ntregi n i m, care reprezint dimensiunile labirintului, iar de pe urmtoarele n linii
cte m numere ntregi, separate prin spaiu, reprezentnd labirintul. n fiierul de
ieire OUTPUT.TXT se va afia pe prima linie numrul minim de pai, iar pe cea
de a doua linie un ir de caractere, care reprezint succesiunea de micri de pe cel
mai scurt drum din labirint, folosind codificarea: D (jos), U (sus), L (stnga)
respectiv R (dreapta).
Exemplu
INPUT.TXT
5 4
0 1 2 3
3 2 1 4
4 1 2 1
1 4 3 2
2 3 4 0

OUTPUT.TXT
7
RRRDDDD

(Balcaniada de Informatic, Cipru, 1996)

Romeo i Julieta:
http://campion.edu.ro/arhiva/index.php?page=problem&action=view&id=898
Alee
http://campion.edu.ro/arhiva/index.php?page=problem&action=view&id=831
Paianjen
http://campion.edu.ro/arhiva/index.php?page=problem&action=view&id=682
Bibliografie
E. Cerchez, M. erban Programarea n limbajul C/C++. Volumul I; Editura
Polirom
Prof. E. Cerchez; prof. M. erban