Documente Academic
Documente Profesional
Documente Cultură
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*
// "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*
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);
}
//legatura
-3-
INFORMATIC*I*
}
}
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);
}
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.2
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*
-6-
INFORMATIC*I*
-7-
INFORMATIC*I*
}
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*
return *operand;
}
-9-
INFORMATIC*I*
{
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
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*
-11-
INFORMATIC*I*
sau astfel:
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*
#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
-13-
INFORMATIC*I*
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))
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*
p->succ=NULL;
if(IsEmptyQ(q)) {q->head=q->tail=p;}
else
{
q->tail->succ=p;
q->tail=p;
}
}
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:
-15-
INFORMATIC*I*
Descrierea metodei:
Se folosete o coad n care se plaseaz coordonate ale unor pixeli.
struct Pozitie {
int x,y;
};
typedef Pozitie Atom;
put(C, pi);
coloreaza pi;
}
IC.04.4
//pentru stiva
//pentru coada
INFORMATIC*I*
<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*
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-