Sunteți pe pagina 1din 18

INFORMATIC*I*

IC.04. Tipurile abstracte de date stiv i coad

Capitolul IC.04. Tipurile abstracte de date stiv i coad


Cuvinte-cheie
Stiv ordonat, stiv nlnuit, coad ordonat, coad liniar, coad circular,
Coad nluit, inserare, tergere, evaluare expresii aritmetice
IC.04.1

Stive. Operaii caracteristice. Implementri de stive

IC.04.1.1

Introducere

O stiv este o structura de date de tip container (depoziteaz obiecte de un anumit tip)
organizat dup principiul LIFO (Last In First Out). Operaiile de acces la stiv (push adaug un element n stiv i pop - scoate un element din stiv) sunt create astfel nct pop
scoate din stiv elementul introdus cel mai recent.

Dup tablou, stiva este probabil cea mai important structur de date. Majoritatea
sistemelor de calcul pun la dispoziia programatorului instruciuni implementate direct n
hardware pentru manipularea stivelor.
O stiv este un caz particular de list, i anume este o list pentru care operaiile de
acces (inserare, tergere, accesare element) se efectueaz la un singur capt al listei.
Daca STACK este tipul stiv i ATOM tipul obiectelor coninute n stiv, atunci
operaiile care definesc tipul structur de stiva pentru tipul STACK sunt:
CREATE() -> STACK
Operaia CREATE nu primete parametri i creeaz o stiv care pentru nceput este
vid (nu conine nici un obiect).
PUSH(STACK, ATOM) -> STACK
Operaia PUSH primete ca parametri o stiv i un obiect i produce stiva modificat
prin adugarea obiectului n stiv.
POP(STACK) -> STACK, ATOM
Operaia POP primete ca parametri o stiv pe care o modific scond un obiect. De
asemenea, produce ca rezultat obiectul scos din stiv.
TOP(STACK) -> ATOM
Operaia TOP ntoarce ca rezultat obiectul din vrful stivei pe care o primete ca
parametru.

-1-

INFORMATIC*I*

IC.04. Tipurile abstracte de date stiv i coad

ISEMPTY(STACK) -> boolean


Operaia ISEMPTY este folosita pentru a testa daca stiva este vida.
IC.04.1.2

Implementri ale conceptului de stiv n C/C++

Toate tipurile de implementri pentru tipul abstract de date stiv au la baz


implementrile caracteristice listelor, deoarece stiva este ea nsi o list.
A) Stiv ordonat
O stiva poate fi organizata pe un spaiu de memorare de tip tablou (vector). Astfel, o
stiv va fi format dintr-un vector de elemente de tip Atom i un indicator (index) al vrfului
stivei.
struct Stack{
int sp;
Atom vect[DIMSTACK];
};

// "stack pointer"

Operaiile care definesc structura de stiv vor fi implementate prin urmtoarele funcii:
void initStack(Stack& S);
void push(Stack& S, Atom a);
Atom pop(Stack& S);
Atom top(Stack S);
int isEmpty(Stack S);

Observaie:
Un obiect Stack este un obiect de dimensiuni mari, fapt pentru care nu este eficient
pasarea obiectelor de acest tip prin valoare. Este indicat folosirea parametrilor referin
pentru pasarea stivei chiar daca procedura nu are intenia de a o modifica (cazul funciilor top
si isEmpty).
Funciile date mai sus pot avea implementarea urmtoare:
void initStack(Stack& S)
{
S.sp=-1;
}
void push(Stack& S, Atom val)
{
if(S.sp> DIMSTACK-1)
printf("Eroare! Stiva plina!");
else
S.vect[++S.sp]=val;
}
Atom pop(Stack& S)
{
if(isEmpty(S)==1)
{printf("Eroare! Stiva vida!"); return 0;}
else
return(S.vect[S.sp--]);
}

-2-

INFORMATIC*I*

IC.04. Tipurile abstracte de date stiv i coad

Atom top(Stack& S)
{
if(isEmpty(S)==1)
{printf("Eroare! Stiva vida!"); return 0;}
else return(S.vect[S.sp]);
}
int isEmpty(Stack& S)
{
return(S.sp==-1);
}

Tema 1: S se scrie un program care implementeaz operaiile ce definesc structura de stiv


ordonat (funciile initStack, push, pop, top si isEmpty).
B) Stiv nlnuit
O stiv poate fi implementata ca o list nlnuit pentru care operaiile de acces se fac
numai asupra primului element din list. Deci operaia PUSH va nsemna inserare n prima
poziie din list (n fa) iar POP va nsemna tergerea primului element din list. Pentru a
manevra o stiv vom avea nevoie de un pointer la primul element din nlnuire, deci vom
echivala tipul Stack cu tipul "pointer la element de lista", iar funciile care implementeaz
operaiile de acces vor avea aceleai prototipuri cu cele date mai sus.
struct Element {
Atom data;
Element* next;
};

//legatura

typedef Element* Stack;

Funciile pentru stiva nlnuit pot fi implementate astfel:


void initStack(Stack& S)
{
S=0;
}
void push(Stack& S, Atom val)
{
Element *p;
p=new Element;
p->data=val;
p->next=S;
S=p;
}
Atom pop(Stack& S)
{
Atom aux;
Element *p;
p=S;
if(isEmpty(S)==1)
{printf("Eroare!Stiva vida!"); return 0;}
else
{
aux=p->data;
S=S->next;
delete p;

-3-

INFORMATIC*I*

IC.04. Tipurile abstracte de date stiv i coad


return aux;

}
}
Atom top(Stack& S)
{
if(isEmpty(S)==1)
{printf("Eroare!Stiva vida!"); return 0;}
else
return S->data;
}
int isEmpty(Stack& S)
{
return(S==0);
}

Tema 2: S se scrie un program ce implementeaz operaiile care definesc structura de stiv


nlnuit (initStack, push, pop, top i isEmpty).
C) Stiv generic
Operaiile de acces la o stiv sunt aceleai indiferent de tipul obiectelor coninute n
stiv. Ar fi normal s folosim codul scris pentru a implementa procedurile push i pop pentru
operaiile de acces la orice tip particular de stiv (stiv de ntregi, stiv de ferestre, etc.). Acest
lucru nu este posibil n implementrile date mai sus, unde procedurile care implementeaz
operaiile de acces la stiv sunt particularizate pentru tipul Atom.
Ilustrm o soluie care permite definirea operaiilor de acces la stiv independent de
tipul informaiei care se depune n stiva. Vom folosi o stiv nlnuit de pointeri fr tip.
Astfel, fiecare element din list va memora adresa unui bloc de memorie n care este
memorat informaia util.

Acest tip de implementare se obine definind tipul Atom drept "pointer" n definiia
stivei nlnuite de mai sus.
O astfel de definiie are avantajul c o aceeai stiv pstreaz elemente de tipuri
diferite, tipul pointer nsemnnd tocmai "pointer la orice". Rmne n sarcina programatorului
s defineasc un mecanism prin care s recunoasc tipul elementului scos din stiv.
Funciile generice pentru stive implementate prin liste nlnuite pot fi:
typedef struct Element
{
void *info;
Element *succ;
} *STIVA;
STIVA InitS(void);
int IsEmptyS(STIVA);
void *Pop(STIVA &);

-4-

INFORMATIC*I*

IC.04. Tipurile abstracte de date stiv i coad

void Push(void*, STIVA &);


void *Top(STIVA);
STIVA InitS(void)
{
return NULL;
}
int IsEmptyS(STIVA s)
{
return s == NULL;
}
void* Pop(STIVA &s)
{
STIVA p; void* aux;
if(IsEmptyS(s)) {printf("Pop -- stiva vida\n");}
p = s;
aux = p->info;
s = s->succ;
delete p;
return(aux);
}
void Push(void *x, STIVA &s)
{
STIVA p;
if((p=new Element)==NULL)
printf("Push - eroare alocare");
p->info = x;
p->succ = s;
s =p;
}
void* Top(STIVA s)
{
if(IsEmptyS(s))
return s->info;
}

IC.04.2

printf("Top -- stiva vida\n");

Aplicaie. Evaluarea expresiilor aritmetice

Expresiile aritmetice n forma uzual, form n care operatorii sunt lsai ntre
operanzii, se numesc expresii n forma infixat. Pentru evaluare, aceste expresii se convertesc
n aa numita form postfixat (numit i forma polonez invers dup naionalitatea
matematicianului Lukasiewicz). O expresie postfixat nu conine paranteze i poate fi
evaluat foarte uor folosind o stiv. ntr-o expresie postfixat nu este necesar specificarea
precedenei operatorilor.
De exemplu, expresia infixat:
a+b/c+(d*e-f)*g
admite scrierea postfixat:
abc/+de*f-g*+
Se observ c forma postfixat a unei expresii aritmetice se caracterizeaz prin aceea
c operatorii apar n ordinea n care se execut operaiile la evaluarea expresiei. De aceea,
evaluarea unei expresii n forma polonez se face parcurgnd ntr-un singur sens expresia i
executnd operaiile innd seama de paritatea lor.

-5-

INFORMATIC*I*

IC.04. Tipurile abstracte de date stiv i coad

Definirea recursiva a expresiilor in forma poloneza (FP) este urmtoarea:


- Pentru orice operand (constant sau variabila) E, E este forma polonez a operandului E
- Dac E este o expresie de forma E1 op E2 , FP a expresiei este E1' E2' op unde E1' si E2'
sunt respectiv FP ale expresiilor E1 si E2
- Dac E este o expresie de forma (E1). FP a expresiei E1 este de asemenea FP a expresiei E.
Exemple:
(9-5)+2 are f.p. 95-2+
9-(5+2) are f.p. 952+Un algoritm simplu de evaluare a expresiilor n forma polonez este urmtorul:
// Expresia se afl ntr-un tablou s cu elemente simboluri de
// tip operand sau operator binar
i=0
while (nu s-a terminat sirul s) do
if (s[i] este operand) then
depune s[i] in stiva
else if (s[i] este operator) then
extrage din stiva doua simboluri t1 si t2;
executa operatia s[i] asupra lui t1 si t2;
depune rezultatul in stiva
else semnalizeaza eroare
endif
endif
i=i+1
endwhile
Obs. Algoritmul presupune c expresiile conin doar operatori binari.
Tema 3: S se scrie un program C (C++) care evalueaz o expresie dat n forma polonez.
O alt form fr paranteze a unei expresii aritmetice este forma prefixat. n acest tip
operatorii preced operanzii.
Exemplu: (9-5)+2 are forma prefixata +-952
Exemplu de conversie i evaluare
n cele ce urmeaz prezentm un exemplu de conversie a unei expresii din forma
infixat (normal) n forma postfixat i apoi evaluarea expresiei. n acest scop (conversie i
evaluare) folosim o stiv implementat cu funciile generice prezentate anterior.
Pentru conversie utilizm o stiv de operatori (M. D. Zaharia, Structuri de date i
algoritmi n limbajele C i C++). Algoritmul prelucreaz expresia dat dintr-un ir de
caractere (banda de intrare) i genereaz un ir de caractere (banda de ieire) care va
constitui forma postfixat. Paii algoritmului sunt:
1. La ntlnirea unui operand acesta este plasat pe banda de ieire.

-6-

INFORMATIC*I*

IC.04. Tipurile abstracte de date stiv i coad

2. La ntlnirea unei paranteze deschise aceasta este transferat pe stiv.


3. La ntlnirea unei paranteze nchise se extrag simbolurile din stiv i sunt transferate
pe banda de ieire. Extragerea continu pn la ntlnirea unei paranteze deschise
(inclusiv paranteza) dar aceasta nu va fi pus pe banda de ieire.
4. La ntlnirea unui operator sau a unei paranteze deschise:
- se extrag din stiv toi operatorii de prioritate mai mare sau egal cu
prioritatea operatorului ntlnit i se transfer pe banda de ieire.
- dac n urma procesului de extragere n vrful stivei va ajunge o parantez
deschis, procesul de extragere se oprete. O parantez deschis nu poate fi
extras din stiv dect n cazul cnd pe banda de intrare se ntlnete o parantez
nchis.
5. Dac s-a ajuns la sfritul benzii de intrare se vor copia pe banda de ieire toi operatorii
rmai n stiv.
n cazul evalurii expresiei se utilizeaz o stiv n care se stocheaz operanzii
expresiei. Se parcurg urmtorii pai:
1. Dac prin parcurgerea de la stnga la dreapta a secvenei de simboluri ce reprezint
expresia postfixat se ntlnete un operand (numr) acesta este stocat n stiva de
operanzi.
2. Dac prin parcurgerea de la stnga la dreapta a secvenei de simboluri ce reprezint
expresia postfixat se ntlnete un operator atunci:
- se extrag doi operanzi din vrful stivei.
- se aplic operatorul celor doi operanzi (dac operaia nu este comutativ trebuie
inut cont de ordinea operanzilor).
- rezultatul aplicrii operatorului se pune n stiv.
Etapele anterioare se repet pn la epuizarea simbolurilor (operatori sau operanzi) de pe
banda de intrare.
n implementarea prezentat se consider c operatorii sunt numere ntregi iar
operatorii sunt +,-, *, /. Operanzii i operatorii sunt separai prin iruri nevide de blancuri sau
caractere TAB. Banda de intrare i banda de ieire sunt iruri de caractere referite prin
pointerii bufi respectiv bufo. Mai jos listm fiierul coninnd funciile suplimentare folosite
i fiierul cu programul principal.
FUNCTII.H
#ifndef _FUNCTII_H_
#define _FUNCTII_H_
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int IsNumber(char*);
int IsOperator(char);
int Priorit(char*);
int IsNumber(char* sir)
{
int i=0;
while(sir[i] != '\0')
{
if(isdigit(sir[i])) i++;
else
break;

-7-

INFORMATIC*I*

IC.04. Tipurile abstracte de date stiv i coad

}
if(i == strlen(sir))
return 1;
else
return 0;
}
int Priorit(char* c)
{
if((*c == '*') || (*c == '/')) return 2;
else return 1;
}
int IsOperator(char c)
{
if((c == '*') || (c == '/') || (c == '+') || (c == '-'))
return 1;
else
return 0;
}
int EvalPolon(char *bufi)
{
//evaluarea unei expresii postfixate
STIVA sarg;
//stiva de operanzi
int a1, a2, *operand, *rezp;
char *ci;
sarg = InitS();
ci = strtok(bufi, " ");
while(ci != NULL)
//bucla de analiza a sirului de intrare
{
if(IsNumber(ci))
{
//aloc spatiu pt operandul pus pe stiva
operand = new int;
sscanf(ci, "%d", operand);
//conversia de la sir de
//caractere la formatul intern
Push((void*)operand, sarg);
}
else
//verifica daca atomul lexical este un operator
if(strlen(ci) == 1 && ((*ci == '+')||(*ci == '-')||
(*ci =='*')||(*ci == '/')) )
{
rezp = (int*)Pop(sarg); a2 = *rezp;
delete rezp;
rezp = (int*)Pop(sarg); a1 = *rezp;
delete rezp;
operand = new int;
if(*ci == '+')
*operand = a1 + a2;
if(*ci == '-')
*operand = a1 - a2;
if(*ci == '*')
*operand = a1 * a2;
if(*ci == '/')
*operand = a1 / a2;
//rezult. evaluarii este pus pe stiva dupa ce se aloca
//spatiu
Push((void*)operand, sarg);
}
else
//nu avem nici numar nici operator;
printf("EvalPol- expresie incorecta");
ci = strtok(NULL, " ");
//cauta urmatorul atom lexical
} //while
*operand = *((int*)Pop(sarg));
//in final stiva trebuie contina un singur element

-8-

INFORMATIC*I*

IC.04. Tipurile abstracte de date stiv i coad

return *operand;
}

void InfixToPostfix(char *bufi, char* bufo)


// conversia din forma infixata in forma postfixata
{
STIVA s;
//stiva de operatori
char *ci, *co, *ch;
//ci -indica caracterul curent de pe banda de intrare
//co -indica caracterul curent de pe banda de iesire
co = bufo;
*co='\0'; //initial banda de iesire este sirul vid
s = InitS();
ci = strtok(bufi, " ");
while(ci!=NULL)
{
//atomul lexical curent poate fi numar intreg sau operator
if(IsNumber(ci))
{
strcat(co, ci);
//un operand trece pe banda de iesire
strcat(co, " ");
}
else
{
if(strlen(ci) == 1 && IsOperator(*ci) )
{
while(!IsEmptyS(s))
{
ch = (char*)Top(s);
if(Priorit(ch) < Priorit(ci)) break;
if( *ch == '(' ) break;
ch = (char*)Pop(s);
strcat(co, ch);
strcat(co, " ");
}
Push((void*)ci, s);
}
else
if(strlen(ci)==1 && *ci=='(') Push((void*)ci, s);
else
if(strlen(ci) == 1 && *ci==')')
{
while(!IsEmptyS(s))
{
ch = (char*)Top(s);
if(*ch == '(' ) break;
ch = (char*)Pop(s);
strcat(co, ch);
strcat(co," ");
}
ch = (char*)Pop(s);
}
else
printf("InfixtoPostfix -- expresie eronata");
}
ci=strtok(NULL, " ");
}
//while (ci!=NULL)
//se copie pe banda de iesire toti operatorii ramasi in stiva
while(!IsEmptyS(s))

-9-

INFORMATIC*I*

IC.04. Tipurile abstracte de date stiv i coad

{
ch=(char*)Pop(s);
strcat(co, ch);
strcat(co, " ");
}
bufo=co;
// printf("in conversie\n");
// puts(bufo);
}
#endif
MAIN.CPP
#include <stdio.h>
#include <string.h>
#include <conio.h>
#include "stivag.h" //contine fuciile pentru implementarea stivei
#include "functii.h"
void main()
{
//clrscr();
char bufi[128], buffer_intermediar[128];
printf("Introduceti forma infixata, numerele separate de spatii\n");
gets(bufi);
puts(bufi);
InfixToPostfix(bufi, buffer_intermediar);
printf("dupa conversie\n");
puts(buffer_intermediar);
printf("Valoarea Expresiei este: %d\n",
EvalPolon(buffer_intermediar));
getch();
}

Tema 4:
a) Dai o definiie recursiv pentru forma prefixat a unei expresii aritmetice.
b) Scriei un program C (C++) de conversie a unei expresii din forma postfixat n forma
prefixat.
c) Scriei un program C (C++) care s evalueze o expresie dat n forma prefixat.
IC.04.3

Cozi. Operaii caracteristice. Implementri de cozi

IC.04.3.1

Introducere

Coada este o list n care operaiile de acces sunt restricionate la inserarea la un capat i
extragerea de la cellalt capt. Coada este o structur de date de tip FIFO (First In First Out)
n care elementul care este extras este ntotdeauna cel care a stat cel mai mult n coad.

-10-

INFORMATIC*I*

IC.04. Tipurile abstracte de date stiv i coad

Principalele operaii de acces sunt:


PUT(Coada, Atom) --> Coada
Adaug un element la coada.
GET(Coada)
--> Coada, Atom
Scoate un Atom din coada. Returneaz atomul scos.
IC.04.3.2

Implementri ale conceptului de coad n C/C++

A) Coad ordonat liniar


O coada poate fi organizat pe un spaiu de memorare de tip tablou (vector).

Sunt necesari doi indicatori:


head - indic primul element care urmeaz s fie scos.
tail - indic locul unde va fi pus urmtorul element adugat la coad.
Condiia "coad vida" este echivalenta cu: head = tail
Indicatorii vor fi iniializati astfel nct s indice ambii primul element din vector.
Operaia PUT nseamn:
- V[tail] primete Atomul adugat
- incrementeaz tail
Operata GET nseamn:
- ntoarce V[head]
- incrementeaz head
Se observ ca adugri i tergeri repetate n coada deplaseaz coninutul cozii la
dreapta, fa de nceputul vectorului. Pentru a evita acest lucru ar trebui ca operaia GET s
deplaseze la stnga coninutul cozii cu o poziie. Primul element care urmeaz s fie scos va fi
ntotdeauna n prima poziie, indicatorul head pierzndu-i utilitatea. Dezavantajul acestei
soluii const n faptul c operaia GET necesit o parcurgere a coninutului cozii.
B) Coad ordonat circular
Pentru a obine o coad ordonat circular se pleac de la o coada liniara ordonat
simpl (cu doi indicatori) i se face n aa fel nct la incrementarea indicatorilor head si tail,
cnd acetia ating ultima poziie din vector s se continue cu prima poziie din vector. Funcia
urmtoare realizeaz aceasta cerin:

-11-

INFORMATIC*I*

IC.04. Tipurile abstracte de date stiv i coad

int nextPoz(int index)


{
if (index<DIMVECTOR-1) return index+1;
else return 0;
}

unde DIMVECTOR este dimensiunea vectorului in care se memoreaz elementele cozii.


Coninutul cozii va arta astfel:

sau astfel:

Conditia "coada vida" rmne echivalent cu: head = tail.


Coada va fi plin dac: head=1 i tail=DIMVECTOR

sau dac: tail+1 = head

Ambele situaii sunt coninute in conditia:


nextPoz(tail) = head

// conditia "coada plina"

Tema 5
S se construiasc fiierul QUEUE1.CPP care sa conin implementarea unei cozi circulare,
respectnd specificaiile din fiierul QUEUE1.H i s se testeze implementarea realizat.
QUEUE1.H

-12-

INFORMATIC*I*

IC.04. Tipurile abstracte de date stiv i coad

#ifndef _QUEUE_H_
#define _QUEUE_H_
#define DIMMAX 4000
typedef int Atom;
struct Queue {
int head,tail;
Atom vect[DIMMAX];
};
void initQueue(Queue& Q);
void put(Queue& Q, Atom a);
Atom get(Queue& Q);
Atom front(Queue& Q);
// coada este pasata prin referinta din motive
int isEmpty(Queue& Q);
// de eficienta
#endif

C) Coad nlnuit liniar


O coada poate fi implementat printr-o list liniar simplu nlnuit n care operaiile
de acces sunt restricionate corespunztor.

Este nevoie de doi indicatori (pointeri):


head - indic primul element din coad (primul care va fi scos);
tail - indic ultimul element din coada (ultimul introdus).
O coad vid va avea: head=tail=nil.
n mod obinuit adugarea unui element n coad modific numai tail iar tergerea
unui element numai head. ntr-un mod special trebuie sa fie tratate cazurile:
- adugare ntr-o coada vid:
Initial: head=tail=nil
Final: Coad cu un element:

- tergere dintr-o coad cu un element:


Initial: Coad cu un element
Final: head=tail=nil

-13-

INFORMATIC*I*

IC.04. Tipurile abstracte de date stiv i coad

n aceste cazuri se modific att head ct i tail.


Funciile generice de mai jos implementeaz o coad nlnuit liniar.
typedef struct El
{
void *info;
struct El *succ;
} ELEMENT;
typedef struct Queue
{
ELEMENT *head, *tail;
} COADA;

//pointeri la primul si ultimul element

COADA *InitQ(void)
{
COADA *q=(COADA*)malloc(sizeof(COADA));
if(q==NULL) {printf("eroare alocare"); exit(1);}
q->head = q->tail = NULL;
return q;
}
int IsEmptyQ(COADA *q)
{
return (q->head == 0 && q->tail==0);
}
void* Front(COADA *q)
{
if(IsEmptyQ(q))
{printf("Front -- coada vida\n"); exit(1);}
return q->head->info;
}
void* Get(COADA *q)
{
void *temp;
if(IsEmptyQ(q))

{printf("Get -- coada vida\n"); exit(1);}

temp = q->head->info;
if(q->head==q->tail)
{
q->head = q->tail = 0;
return temp;
}
else
{
ELEMENT *p;
p=q->head;
q->head=p->succ;
free(p);
return temp;
}
}
void Put(COADA *q, void *x)
{
ELEMENT *p;
if((p=(ELEMENT*)malloc(sizeof(ELEMENT)))==0)
{printf("Put -- eroare alocare"); exit(1);}
p->info=x;

-14-

INFORMATIC*I*

IC.04. Tipurile abstracte de date stiv i coad

p->succ=NULL;
if(IsEmptyQ(q)) {q->head=q->tail=p;}
else
{
q->tail->succ=p;
q->tail=p;
}
}

D) Coad nlnuit circular


Dac reprezentm coada printr-o structur nlnuit circular este nevoie de un singur
pointer prin intermediul cruia se pot face ambele operaii de adugare i tergere din coada:

Tema 6
S se construiasc fiierele QUEUE2.H si QUEUE2.CPP coninnd implementarea unei cozi
nlnuite (n una din cele doua variante) i s se testeze implementarea realizat.
Problem propus
Definim "domeniu" ca fiind o zona din ecranul grafic care conine pixeli nvecinai direct sau
indirect, pe vertical sau orizontal, i care au aceeai culoare. De exemplu:

Mai sus sunt definite trei domenii:


-cel colorat cu negru;
-cel colorat cu alb, aflat n exterior;
-cel colorat cu alb, n interiorul zonei negre (insula).
S se scrie un program care schimb culoarea unui domeniu, pornind de la un pixel oarecare
din acel domeniu.
Indicaii

-15-

INFORMATIC*I*

IC.04. Tipurile abstracte de date stiv i coad

Descrierea metodei:
Se folosete o coad n care se plaseaz coordonate ale unor pixeli.
struct Pozitie {
int x,y;
};
typedef Pozitie Atom;

//elementele cozii sunt de


//tip Pozitie

Se coloreaz i se pune n coad mai nti poziia pixelului iniial. Se prelucreaz pe


rnd elementele scoase din coada. Pentru fiecare element scos din coad se pun n coad i se
coloreaz toi vecinii si care aparin domeniului i nu au fost atini (nu au fost colorai).
Astfel vor trece prin coada toate poziiile incluse n domeniu.
Pseudocod:
coloreaza_domeniu(pozitie_initiala)
{
memoreaza culoarea domeniului (culoarea pozitiei initiale)
put(C, pozitie_initiala);
coloreaza pozitia_initiala;
WHILE not isEmpty(C) DO

p := get(C); // scoate in p urmatoarea pozitie din coada


FOR pi:=toate pozitiile invecinate lui p DO
IF pi nu iese in afara ecranului si

pi are culoarea domeniului THEN

put(C, pi);

coloreaza pi;

}
IC.04.4

Utilizarea stivei i cozii n aplicaii generice C++

Limbajul C++ (standardul ANSI/ISO al acestui limbaj) ofer programatorului o bibliotec de


rutine ce conin implementri generice ale operaiilor de manipulare caracteristice
principalelor tipuri abstracte de date. Aceast bibliotec se numete STL (Standard Template
Library). Stiva i coada sunt specificate ca i clase ablon. Definiia stivei sau cozii poate fi
utilizat de programator folosind directivele:
#include <stack>
#include <queue>

//pentru stiva
//pentru coada

De exemplu, cele mai folosite metode pentru stiv sunt:


void push(const item& entry); -pune un element de tip item n vrful stivei
bool empty() const; - returneaz adevrat dac stiva este vid
value_type& top(); - returneaz elementul din vrful stivei.
-16-

INFORMATIC*I*

IC.04. Tipurile abstracte de date stiv i coad

Pentru coad, cele mai folosite metode pentru sunt:


void pop(); - extrage un element din coad
void push(const item& entry); - adaug un element n coad
bool empty() const; - returneaz adevrat dac coada este vid
value_type& front(); - returneaz primul element din coad, fr a-l scoate din
coad.
n continuare prezentm un exemplu de utilizare a celor dou clase descrise anterior. Se
dorete s se determine dac un ir de caractere citit de la tastatur este sau nu palindrom (la
parcurgerea stnga-dreapta respectiv dreapta-stnga se obine aceeai secven de caractere).
Nu se consider diferenele dintre literele mari i mici. Dac irul nu este palindrom se
afieaz poriunea de la nceputul irului pn la apariia primei diferene ntre cele dou
parcurgeri.
#include
#include
#include
#include
using

<stack>
<queue>
<iostream>
<conio.h>

namespace std;

void main()
{
queue<char> q, q1;
stack<char> s;
char c;
queue<char>::size_type nr=0;
while(cin.peek() !='\n')
{
cin >> c;
if(isalpha(c))
{
q.push(toupper(c));
s.push(toupper(c));
}
}
while(!q.empty() && !s.empty())
{
if((c=q.front()) != s.top()) {nr++; break;}
q.pop();
s.pop();
q1.push(c);
}
if(nr)
{
cout << "Nu este palindrom\n";
while(!q1.empty())
{
cout << q1.front();
q1.pop();
}
}
else cout << "Este palindrom\n";
getch();
}

-17-

INFORMATIC*I*

IC.04. Tipurile abstracte de date stiv i coad

Bibliografie
[C01] Craus M., Brsan C., Structuri de date i algoritmi, Editura Gh. Asachi, Iai, 2002
[U02] Ungureanu F., Structuri de date i algoritmi Note de curs, Universitatea Tehnic
Gheorghe Asachi din Iai, Facultatea de Automatic i Calculatoare
[Z03] Zaharia M. D., Structuri de date i algoritmi n limbajele C i C++, Editura Albastr,
Cluj-Napoca, 2002
[I04] Ignat I., Ignat C., Structuri de date i algoritmi, Editura Albastr, Cluj-Napoca, 2007

-18-

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