Sunteți pe pagina 1din 12

STIVA

Stiva este un caz particular al listei, pentru care se pstreaz principiul de funcionare
LIFO, adic, ultimul element intrat n list este i primul element extras din list. De remarcat
este faptul c, n cazul stivei, att operaia de adugare, ct i cea de extragere, se efectueaz
printr-un acelai cap.
Stiva poate fi de dou feluri:
1) Static, adic, pe vector
2) Dinamic, adic, nlnuit
//1. Stiva statica
#include<iostream>
using namespace std;
#define dim 30 //dimensiunea stabilita maximal pentru vector
typedef int stiva[dim]; // s-a construit un tip de date, cu numele 'stiva', dupa dimensiunea
stabilita anterior
stiva st; //st este variabila stiva de lucru
int vf; //ultimul numar de valori din stiva
//functie de testare pentru a afla daca stiva este vida
int empty()
{
if(vf==0) //nu sunt elemente in stiva
return 1;
return 0;
}
//functie de testare daca stiva este ocupata, adica, are toata memoria rezervata
int full()
{
if(vf==dim)
return 1;
return 0;
}
//functie pentru adaugarea unui element in stiva
void push(int e)
{
if(full()!=0)
{
cout<<"Stiva este plina. Nu se mai pot face adaugari\n";
return;
}
st[vf++]=e; //se mai putea scrie si asa: {st[vf]=e; vf++;}
}
//functie pentru extragerea unui element din stiva
int pop()
{
if(empty()!=0)

cout<<"Stiva este goala. Nu se mai pot face extrageri\n";


return 0;

}
return st[--vf]; //se mai putea scrie si asa: {vf--; st[vf]=e;}

//functie pentru afisarea stivei


void write()
{
cout<<"Stiva este: ";
for(int i=0;i<vf;i++)
cout<<st[i]<<' ';
cout<<'\n';
}
//functia principala in rulare
int main()
{
//adaugarea unui element in stiva
push(6);
write();
push(7);
write();
push(10);
write();
//extragerea unui element din stiva
int e=pop();
cout<<"Elementul extras este: "<<e<<". ";
write();
e=pop();
cout<<"Elementul extras este: "<<e<<". ";
write();
e=pop();
cout<<"Elementul extras este: "<<e<<". ";
write();
e=pop();

system("pause");
return (0);

COADA
Coada este un caz particular al listei, pentru care se pstreaz principiul de funcionare
FIFO, adic, primul element intrat n list este i primul element extras din list. De remarcat
este faptul c, n cazul stivei, operaiile de adugare i extragere se efectueaz cele dou capete
diferite ale sale.

Coada poate fi de dou feluri:


1) Static, adic, pe vector
2) Dinamic, adic, nlnuit

//2. Coada statica


#include<iostream>
using namespace std;
#define dim 30 //dimensiunea stabilita maximal pentru vector
typedef int coada[dim]; // s-a construit un tip de date, cu numele 'coada', dupa dimensiunea
stabilita anterior
coada cd; //cd este variabila coada de lucru
int vf; //ultimul numar de valori din coada
//functie de testare pentru a afla daca coada este vida
int empty()
{
if(vf==0) //nu sunt elemente in coada
return 1;
return 0;
}
//functie de testare daca coada este ocupata, adica, adre toata memoria rezervata
int full()
{
if(vf==dim)
return 1;
return 0;
}
//functie pentru adaugarea unui element in coada
void push(int e)
{
if(full()!=0)
{
cout<<"Coada este plina. Nu se mai pot face adaugari\n";
return;
}
cd[vf++]=e; //se mai putea scrie si asa: {cd[vf]=e; vf++;}
}
//functie pentru extragerea unui element din coada
int pop()
{
if(empty()!=0)
{
cout<<"Coada este goala. Nu se mai pot face extrageri\n";
return 0;
}
int e=cd[0]; //elementul ce va fi extras din coada
for(int i=0;i<vf-1;i++)
cd[i]=cd[i+1];
vf--; //reduc numarul de elemente ca acel ultim element sa nu apara de 2 ori
return e; //se extrage primul element din coada

}
//functie pentru afisarea coada
void write()
{
cout<<"Coada este: ";
for(int i=0;i<vf;i++)
cout<<cd[i]<<' ';
cout<<'\n';
}
//functia principala in rulare
int main()
{
//adaugarea unui element in coada
push(6);
write();
push(7);
write();
push(10);
write();
//extragerea unui element din coada
int e=pop();
cout<<"Elementul extras este: "<<e<<". ";
write();
e=pop();
cout<<"Elementul extras este: "<<e<<". ";
write();
e=pop();
cout<<"Elementul extras este: "<<e<<". ";
write();
e=pop();

system("pause");
return (0);

//3. Stiva inlantuita (in cazul de fata am optat pentru urmatoarea prelucrare: stiva
este o lista pentru care atat operatia de adaugare, cat sic ea de extragere se
efectueaza prin fata listei)
#include<iostream>
using namespace std;
//definirea structurii pentru reprezentarea unui nod al stivei inlantuite
struct nod{
int val;
//continutul elementului
nod *next; //legatura catre elementul vecin urmator
};
typedef struct nod stiva; //constructia unui tip de date, numit stiva, pentru operatiile de tipul
nod, definite mai sus

//adaugarea unui element in stiva


stiva* push(stiva* vf, int e) //e - o valoare numerica dorita ce va fi introdusa la utilizare
{
stiva* temp; //nu putem adauga un element direct pe stiva, pentru ca asta ar insemna
distrugerea stivei. Ca atare, se va apela la un element temporar, pe care, ulterior, il vom integra
in lista
//Etapa 1: rezervarea de memorie
temp=new(stiva); //sau: temp=(stiva*)malloc(sizeof(stiva));
//Etapa 2: popularea elementului de valoare cu o inregistrare, primita ca si
parametru
temp->val=e;
//Etapa 3: integrarea noului element in lista
if (vf==NULL) //situatia in care lista este vida
{
temp->next=NULL;
vf=temp;
}
else //situatia in care mai sunt elemente in lista
{
temp->next=vf;
vf=temp;
}
return vf;
}
//extragerea unui element din stiva
stiva* pop(stiva* vf)
{
//si in cazul extragerii, tot asa e nevoie de un temporar, deoarecere nu pot lucra direct pe
stiva initiala, dat fiind fapul ca as distruge-o pe aceasta
stiva* temp;
if (vf==NULL)
cout<<"\nLista este vida\n";
else
{
temp=vf;
vf=vf->next; //noul varf din fata al listei
delete temp; //sau: free(temp); - curatim vechiul varf al listei
}
return vf;
}
//afisarea componentelor stivei
void write(stiva* vf)
{
stiva* aux;
aux=vf;
cout<<"Elementele listei sunt: ";
while (aux!=NULL)
{
cout<<aux->val<<' ';
aux=aux->next;
}
cout<<'\n';
}
//functia principala

int main()
{
stiva* vf=NULL; //initializarea listei
//adaugarea unui element in lista
vf=push(vf,6);
write(vf);
vf=push(vf,7);
write(vf);
vf=push(vf,4);
write(vf);
//extragerea din lista
vf=pop(vf);
write(vf);
vf=pop(vf);
write(vf);
vf=pop(vf);
write(vf);
system("pause");
return (0);
}

OBS: Dac stiva este un caz perticular de list pentru care att operaia de
adugare, ct i cea de extragere, se efectueaz prin acelai cap, n cazul cozii,
aceasta este o list, pentru care operaia de adugare presupune introducerea unui
nou element prin spatele listei i extragerea prin faa listei.

//4. Coada ca si lista inlantuita


#include<iostream>
using namespace std;
//definirea structurii pentru reprezentarea unui nod al stivei inlantuite
struct nod{
int val;
//continutul elementului
nod *next; //legatura catre elementul vecin urmator
};
typedef struct nod coada; //constructia unui tip de date, numit COADA, pentru operatiile de tipul
nod, definite mai sus
//adaugarea unui element in coada
coada* push(coada* vf, int el)
{
nod *temp, *aux; //aux - folosit pentru parcurgerea pe lista
//Etapa 1. Etapa de alocare de memorie
temp=new (coada); // sau: temp=(coada*)malloc(sizeof(coada));

//Etapa 2: Etapa de populare cu inregistrari a valorii din nod


temp->val=el;
//Etapa 3. Etapa de integrare a nodului in lista
//se face testarea daca mai sunt elemente in lista
if (vf==NULL) //situatia in care lista este vida
{
temp->next=NULL;
vf=temp;
}
else //situatia in care mai sunt elemente in lista
{
aux=vf;
//parcurgerea listei pana la finalul acesteia
while(aux->next!=NULL)
aux=aux->next;
aux->next=temp;
temp->next=NULL;
}
return vf;
}
//extragerea unui element din stiva
coada* pop(coada* vf)
{
//si in cazul extragerii, tot asa e nevoie de un temporar, deoarece nu pot lucra direct pe
coada initiala, dat fiind fapul ca as distruge-o pe aceasta
coada* temp;
if (vf==NULL)
cout<<"\nLista este vida\n";
else
{
temp=vf;
vf=vf->next;
delete temp; //sau: free(temp);
}
return vf;
}
//afisarea componentelor stivei
void write(coada* vf)
{
coada* aux;
aux=vf;
cout<<"Elementele listei sunt: ";
while (aux!=NULL)
{
cout<<aux->val<<' ';
aux=aux->next;
}
cout<<'\n';
}
//functia principala
int main()
{
coada* vf=NULL; //initializarea listei
//adaugarea unui element in lista

vf=push(vf,6);
write(vf);
vf=push(vf,7);
write(vf);
vf=push(vf,4);
write(vf);
//extragerea din lista
vf=pop(vf);
write(vf);
vf=pop(vf);
write(vf);
vf=pop(vf);
write(vf);

system("pause");
return (0);

OBS: Dat fiind diferena dintre cele dou cazuri particulare de list, problema
rezolvrii stivei, respectiv, a cozii, difera doar prin funcia de adugare, (n cazul de
mai sus), care presupune adugarea prin faa listei, dac i extragerea se va face
tot prin faa listei, n cazul stivei, respective, prin spatele listei, iar, extragerea prin
faa listei, n cazul cozii.

ARBORELE DE CUTARE BINAR (BINARY SEARCH TREE)


Foarte important n cutare i sortare, este arborele de cutare binar. Un
arbore de cutare binar este un arbore binar vid sau n care fiecare nod conine o
cheie (informaie important dup care se face ordonarea) ce satisface urmtoarele
condiii:
i toate cheile din subarborele stng(dac exist) preced cheia din rdcin;
ii cheia din rdcin precede toate cheile din subarborele drept(dac exist);
iii subarborii stng i drept sunt la rndul lor arbori de cutare.

Observaie
a

Se observ c i definiia arborelui de cutare este recursiv.

Subarborii stng i drept sunt la rndul lor arbori de cutare.

D
C
Figur:

AE

10

3b
Arbori

M
D
A c F

9 12
11

de

B E

P
S
I R Z

cutare

binar

Pornim de la un exemplu, si anume citim de la tastatura numerele 7, 2, 4, 9,


5, 3 n aceasta ordine. Ele vor fi nregistrate ntr-o structur de tip arbore binar de
cutare.
#include<iostream>
using namespace std;
#define max(x,y) ((x<y)?(y):(x))
// reprezentarea structurii unui arbore binar
struct nod
{
int info;
nod *left,*right;
};
typedef struct nod arbore;
//1. CONSTRUCTIA ARBORELUI DE CAUTARE BINARA

//inserarea unui nou element in arbore


arbore* inserare(arbore* bt, int e)
{
//testarea daca arborele este gol
if (!bt)
{
bt=new(arbore); //sau: bt=(arbore*)malloc(sizeof(arbore));
if (!bt) //situatia in care alocarea de memorie nu reuseste
{
cout<<"Alocare de memorie esuata\n";
return NULL;
}
//introducerea informatiei in nodul arborelui
bt->info=e;
/*fiind doar un prim element introdus in arbore, subarborii stang si drept
vor fi pozitionati pe NULL*/

bt->left=bt->right=NULL;
}
else //situatia in care arborele mai continea si alte elemente
if(bt->info>e) /*verificam daca valoarea din radacina este mai mare ca cea
nou venita*/
bt->left=inserare(bt->left,e); /*daca valoarea nou intrata este mai
mica decat cea din radacina, pozitionarea se va face in stanga acesteia*/
else
bt->right=inserare(bt->right,e); /*daca valoarea nou intrata este
mai mare decat cea din radacina, pozitionarea se va face in dreapta acesteia*/
return bt;

//2. AFISAREA PRIN PARCURGEREA ARBORELUI


/* modul 1: traversarea in preordine, adica: mai intai se viziteaza nodul radacina, apoi
subarborele stang, apoi cel drept (RSD)
- in exemplul de mai sus: 7 2 4 3 5 9 */
void preordine(arbore *bt)
{
if(bt!=NULL)
{
cout<<bt->info<<' ';
preordine(bt->left);
preordine(bt->right);
}
}
/* modul 2: traversarea in inordine, adica: traversarea subarborelui stang, a radacinii si apoi a
celui drept (SRD)
- in exemplu: 2 3 4 5 7 9 . Dupa cum se poate observa rezultatul va da o lista sortata */
void inordine(arbore *bt)
{
if (bt!=NULL)
{
inordine(bt->left);
cout<<bt->info<<' ';
inordine(bt->right);
}
}
/* modul 3: traversarea in postordine, adica: traversarea subarborelui stang, a subarborelui drept
si apoi a radacinii (SDR)
- in exemplu: 3 5 4 2 9 7 */
void postordine(arbore *bt)
{
if (bt!=NULL)
{
postordine(bt->left);
postordine(bt->right);
cout<<bt->info<<' ';
}
}
//3. DETERMINAREA NUMARULUI DE NODURI, NUMARULUI DE NIVELE SI NUMARUL NODURILOR
TERMINALE (FRUNZE)
// numarul tuturor nodurilor (in exemplul nostru: 6)

int nod(arbore *bt)


{
if (bt==NULL) //situatia in care arborele este vid
return 0;
else
return 1+nod(bt->left)+nod(bt->right); //1 = nodul de radacina principala
}
// numarul de nivele (in exemplul nostru: 4)
int nivele(arbore *bt)
{
if (bt==NULL) //situatia in care arborele este vid
return 0;
else
return 1+max(nivele(bt->left),nivele(bt->right)); //1 = nivelul radacinii de baza
}
// numarul nodurilor terminale (frunze) (in exemplul nostru: 3)
int frunze(arbore *bt)
{
if (bt==NULL) //situatia in care arborele este vid
return 0;
if ((bt->right==NULL) && (bt->left==NULL)) //situatia in care nu mai exista noduri terminale
stanga/dreapta
return 1;
else
return frunze(bt->left)+frunze(bt->right);
}
/********************************************************/
//functia principala in rulare
int main()
{
arbore* x=NULL; //declarare cu initializare
//constructia arborelui din exemplul de intrare: 7,2,4,9,5,3
x=inserare(x,7);
x=inserare(x,2);
x=inserare(x,4);
x=inserare(x,9);
x=inserare(x,5);
x=inserare(x,3);
//afisarea dupa parcurgerea in preordine
preordine(x);
cout<<'\n';
//afisarea dupa parcurgerea in inordine
inordine(x);
cout<<'\n';
//afisarea dupa parcurgerea in postordine
postordine(x);
cout<<'\n';
//numarul de noduri din arbore
cout<<"Numarul de noduri: "<<nod(x)<<'\n';

//numarul de nivele din arbore


cout<<"Numarul de nivele: "<<nivele(x)<<'\n';
//numarul de frunze din arbore
cout<<"Numarul de noduri terminale: "<<frunze(x)<<'\n';

system("pause");
return 0;

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