Sunteți pe pagina 1din 7

5.

STIVA I COADA

191

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

5. STIVA I COADA

192

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: ... ... 3 5 10 0 7 vf

5 10 0 7

vf

Prof. E. Cerchez; prof. M. erban

5. STIVA I COADA

193 Stiva S dup inserare

Stiva S nainte de 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 10 0 7 vf

Stiva S nainte de extragere

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

5. STIVA I COADA

194

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. ... 5
Inc

10

2
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

5. STIVA I COADA

195

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 ... Coada C dup inserare


if (Sf == DimMax-1) cout<<"Eroare\n"; else C[++Sf] = x; //nu mai avem loc //inseram elementul x in coada C

5
Inc

10

3
Sf

...

Prof. E. Cerchez; prof. M. erban

5. STIVA I COADA

196

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
Inc

10

2
Sf

...

Coada C nainte de extragere ... Coada C dup extragere


if (Inc > Sf) cout<<"Eroare \n"; else x = C[Inc++]; //coada este vida //extragem primul element

10
Inc

2
Sf

...

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

5. STIVA I COADA

197

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