You are on page 1of 35

Clasa a XI-a

Coni Emilia-Felicia

Definiie. Un arbore binar este un


arbore orientat cu proprietatea c
pentru orice vrf v, od(v)2. Dac
od(v)=2, cei doi descendeni snt
desemnai ca descendent stng (fiu
stnga) respectiv descendent drept (fiu
dreapta). Pentru vrfurile cu od(v)=1,
unicul descendent este specificat fie ca
fiu stnga, fie ca fiu dreapta.
Definiie. Se numete arbore strict
binar un arbore binar cu poprietatea c
pentru orice vrf v, od(v)1.
Definiie. Se numete nod terminal
(sau frunz) orice vrf v al arborelui cu
od(v)=0. n caz contrar nodul v este
neterminal.

Reprezentarea Fiu-Frate
(N, R, Fiu, Frate, Inf)
Cu structuri dinamice
Structur nod: informaie,
adres fiu stng / drept

typedef struct nod {


int info;
struct nod* st,*dr;
}
TNOD;
Pentru a cunoate
arborele: rdcina
TNOD* r;

n lime
Pe niveluri

Pe niveluri

n adncime
Preordine

Preordine

Postordine

Postordine
Inordine

void preordine(TNOD* r)
{ if(r!=NULL)
{ //prelucrare r->info
preordine(r->st);
preordine(r->dr);
}
}

void postordine(TNOD* r)
{ if(r!=NULL)
{ postordine(r->st);
postordine(r->dr);
//prelucrare r->info
}
}
void inordine(TNOD* r)
{ if(r!=NULL)
{ inordine(r->st);
//prelucrare r->info
inordine(r->dr);
}
}

void niveluri(TNOD* r)
{ TNODC* c;
TNOD* p;
int er;
if(r != NULL)
{ c = NULL;
c = push(c,r);
while(c != NULL)
{ c=pop(c,&p,&er);
// prelucrare p>info
if(p->st!=NULL) c
= push(c,p->st);
if(p->dr!=NULL) c
= push(c,p->dr);
}
}
}

typedef struct nodc


{ TNOD* info;
struct nodc* next;
} TNODC;

int inaltime(TNOD* r)
{ int i,j,k;
if(r == NULL) i = 0;
else
{ j = inaltime(r->st);
k = inaltime(r->dr);
i = 1 + (j>k ? j : k);
}
return(i);
}

Definiie. Un arbore de cutare este


un arbore binar cu urmtoarele
proprieti
fiecrui nod i al arborelui i este
ataat o informaie INF(i) dintr-o
mulime ordonat de valori;
pentru fiecare nod i, INF(i) este mai
mare dect INF(j), pentru toate
nodurile j din subarborele stng al
arborelui cu rdcin i;
pentru fiecare nod i, INF(i) este mai
mic dect INF(j), pentru toate
nodurile j din subarborele drept al
arborelui cu rdcin i;
pentru orice vrfuri i i j daca i j
atunci INF(i) INF(j).

10
6

13

4
2
1

8
5

12
9

11

15
14

16

Operaii
Parcurgeri (pe niveluri, preordine, inordine, postordine)
Adugare informaie
tergere informaie

Preordine : 10, 6, 4, 2, 1, 3, 5, 8, 7, 9, 13, 12, 11, 15, 14, 16


Inordine : 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16
Postordine: 1, 3, 2, 5, 4, 7, 9, 8, 6, 11, 12, 14, 16, 15, 13, 10
Pe niveluri: 10, 6, 13, 4, 8, 12, 15, 2, 5, 7, 9, 11, 14, 16, 1, 3

TNOD* inserare(TNOD* r, int a, int* er)


{ *er=0;
if(r==NULL)
{ r=(TNOD*)malloc(sizeof(TNOD));
r->info=a;
r->dr=NULL;
r->st=NULL;
}
else if(r->info==a) *er=1;
else if(r->info>a) r->st=inserare(r->st, a, er);
else r->dr=inserare(r->dr,a,er);
return r;
}
10
6

13

4
2
1

8
5

12
9

11

15
12,5

14

16

10
6

13

4
2

8
5

12

15

11

14

16

7,2
7,1

7,3

10
5

12

4
2

7,2
3

11

7,1

9
7,3

15
14

16

TNOD* sterge(TNOD* r, int a, int*er)


{ TNOD* p, *q;
*er=0;
if(r == NULL) *er=1;
else if(r->info > a) r->st = sterge(r->st,a,er);
else if(r->info < a) r->dr = sterge(r->dr,a,er);
else if(r->st == NULL)
{ p = r; r = r->dr; free(p); }
else if(r->st->dr==NULL)
{ r->info = r->st->info; p = r->st; r->st = r->st->st;
free(p);
}
else
{ p = r->st;
while(p->dr != NULL)
{ q = p;
p = p->dr;
}
r->info = p->info;
q->dr = p->st;
free(p);
}
return r;
}

1. a) Creai arborele de cutare care are ataate cheile


7,2,8,1,5,3,0,4

b) Reprezentai grafic arborele de cutare obinut din


arborele de cutare creat anterior prin tergerea nodului
cu cheia 2
2. a) Creai arborele de cutare care are ataate cheile
9,3,7,1,2,8,10,5

b) Reprezentai grafic arborele de cutare obinut din


arborele de cutare creat anterior prin tergerea nodului
cu cheia 9.
3. a) Creai arborele de cutare care are ataate cheile
3,5,1,8,2,0,6,9,4

b) Reprezentai grafic arborele de cutare obinut din


arborele de cutare creat anterior prin tergerea nodului
cu cheia 5.

#include<iostream>
using namespace std;
struct nod
{int nr_o;
nod*st,*dr;
};
nod *v;
int n,k;
void inserare(nod *&c,int k)
{if(c)
if(c->nr_o==k)
cout<<"nr deja inserat "<<endl;
else
if(c->nr_o<k)
inserare(c->dr,k);
else
inserare(c->st,k);
else
{c=new nod;
c->nr_o=k;
c->st=c->dr=0;}
}
void svd(nod *c) //parcurgere in inordine
{if(c)
{svd(c->st);
cout<<c->nr_o<<" ";
svd(c->dr);
}
}

int cautare(nod *c,int k)


{if(c)
if(c->nr_o==k)
return 1;
else
if(c->nr_o<k)
cautare(c->dr,k);
else
cautare(c->st,k);
else
return 0;
}
int main()
{//v=0;
cout<<"nr de noduri ";
cin>>n;
for(int i=1;i<=n;i++)
{cout<<"valoarea de inserat ";
cin>>k;
inserare(v,k);}
cout<<endl<<"arborele are urmatoarele
noduri "<<endl;
svd(v);
cout<<endl<<"valoarea de cautat ";
cin>>k;
if(cautare(v,k))
cout<<"s-a gasit!";
else
cout<<"nu s-a gasit!";
}

Pentru evidena elevilor unei coli se


definete un arbore binar de cutare, n
care fiecare nod va memora numrul
matricol, numele i numrul de absene ale
unui elev. Cutarea n arbore se va face
dup numrul matricol al elevilor. Scriei un
program care, prin intermediul unui meniu,
selecteaz n mod repetat, atta timp ct
utilizatorul dorete acest lucru, una din
urmtoarele aciuni:
adugarea unui elev;
afiarea absenelor pentru numrul
matricol minim;
afiarea absenelor pentru numrul
matricol maxim;
modific numrul de absene al unui elev
pentru care se cunoate numrul
matricol;
afieaz toi elevii al cror nume ncepe
cu litera B.

Arbore de structur: arbore strict


binar folosit pentru a reprezenta
expresiile aritmetice care conin
numai operatori binari. Fiecare
nod conine ca informaie util:
un operand, dac este nod
frunz
un operator, dac nu e nod
frunz
Arborele se construiete acordnd
prioriti operanzilor i
operatorilor.
Parcurgerea arborelui n
preordine => forma polonez
direct a expresiei
Parcurgere arborelui n inordine
=> refacerea expresiei (cu sau
fr paranteze).

Arbori de structur
Exemplu: a*(b+c) (d+e)/(f+g)
-

Construire arbore:
1. Calculare prioriti pentru operanzi i operatori
2. Construire propriu-zis a arborelui

Arbori de structur
Exemplu: a*(b+c) (d+e)/(f+g)
1. Calculare prioriti pentru operanzi i operatori

operatorii aditivi primesc prioritatea 1

operatorii multiplicativi primesc prioritatea 10

prioritatea fiecrui operator se mrete cu 10 pentru


fiecare pereche de paranteze care l include

fiecare operand primete prioritatea maxim (maxint)

Prioritile snt nscrise ntr-un vector.

p[i]= prioritatea elementului i din expresie (operator sau


operand, n ordinea apariiei

Elemente expr. =(
Prioriti

a,

*,

b,

+,

c,

-,

d,

+,

e,

/,

f,

+,

g)

=(maxint,10,maxint,11,maxint,1,maxint,11,maxint,10,maxint,11,maxint)

Arbori de structur
Exemplu: a*(b+c) (d+e)/(f+g)
Elemente expr. =(
Prioriti

a,

*,

b,

+,

c,

-,

d,

+,

e,

/,

f,

+,

g)

=(maxint,10,maxint,11,maxint,1,maxint,11,maxint,10,maxint,11,maxint)

Construire arbore: algoritm recursiv.


1.

dac expresia curent este vid, subarborele curent este vid (nil)

2.

altfel se caut elementul cu prioritate minim din expresia curent

3.

se creeaz un nod rdcin pentru subarborele curent

4.

fiul stng este subarborele obinut prin reprezentarea subexpresiei din stnga
elementului curent

5.

fiul drept este subarborele obinut prin reprezentarea subexpresiei din dreapta
elementului curent

Arbori de structur
Exemplu: a*(b+c) (d+e)/(f+g)
Elemente expr. =(
Prioriti

a,

*,

b,

+,

c,

-,

d,

+,

e,

/,

f,

+,

g)

=(maxint,10,maxint,11,maxint,1,maxint,11,maxint,10,maxint,11,maxint)

a*(b+c)

a
a
*
b
+
c
(maxint, 10, maxint, 11, maxint)

(d+e)/(f+g)

(d+e)/(f+g)

a
(maxint)

b+c

Arbori de structur
Exemplu: a*(b+c) (d+e)/(f+g)
Elemente expr. =(
Prioriti

a,

*,

b,

+,

c,

-,

d,

+,

e,

*
()

()

()

+,

g)

(d+e)/(f+g)
b+c

()

f,

=(maxint,10,maxint,11,maxint,1,maxint,11,maxint,10,maxint,11,maxint)

/,

b
+
c
(maxint, 11, maxint)

(d+e)/(f+g)
+

Arbori de structur
Exemplu: a*(b+c) (d+e)/(f+g)
Elemente expr. =(
Prioriti

a,

*,

b,

+,

c,

-,

d,

+,

e,

+,

g)

(d+e)/(f+g)
+

f,

=(maxint,10,maxint,11,maxint,1,maxint,11,maxint,10,maxint,11,maxint)

/,

a
c

d
+
e
/
f +
g
(maxint,11,maxint,10,maxint,11,maxint)

/
+

d+e
c

f+g

Arbori de structur
Parcurgerea arborelui n preordine => forma polonez direct a
expresiei:

-*a+bc/+de+fg

Parcurgere arborelui n inordine => refacerea expresiei (cu sau


fr paranteze SRD sau (S)R(D) ):

a*b+cd+e/f+g
((a)*((b)+(c)))-(((d)+(e))/((f)+(g)))

Arbori de structur
Evaluare expresie: prin parcurgere n postordine.
Prelucrarea fiecrui nod r const n
dac e nod frunz nu se schimb nimic
altfel se nlocuiete informaia r->inf cu rezultatul expresiei
ss r->inf sd
unde ss i sd snt informaiile din fiul stng respectiv drept al
nodului curent

a = 3, b = 4, c = 6, d = 10, e = 5, f = 2, g = 1

25
-

Arbori de
structur
5/

30
*
3

+
10
4

+
15
6

10

+
3
5

#include <stdio.h>
#include <malloc.h>
#include <string.h>
#include <math.h>
#define MAXINT 10000
/* reprezentarea unei expresii prin arbore de structura si
evaluarea ei
restrictii:
- numai operatori aritmetici + - * /
- identificatorii operanzilor formati din numai o litera
- fara spatii
*/
typedef struct nod{ char inf;
float v;
struct nod *s,*d;
} TNOD;

char* prioritati(char *s, int p[], int* n)


{ int i,j,crt,l;
char* r;
//i - caracterul curent
//j - proritatea curenta
//crt - elementul curent
//r - expresia fara paranteze
//calcul prioritati
l = strlen(s);
for(i=j=crt=0; i<l; i++)
switch(s[i])
{ case ')': j-=10;break;
case '(': j+=10;break;
case '+': ;
case '-': p[crt]=j+1;crt++;break;
case '*': ;
case '/': p[crt]=j+10;crt++;break;
default : p[crt++]=MAXINT;
}

//eliminare paranteze
r=(char*)malloc(strlen(s));
strcpy(r,s);
i=0;
while(i<l)
if( (r[i]==')') || (r[i]=='(') )
{ for(j=i+1; j<l; j++)
r[j-1]=r[j];
r[l]='\0';
l--;
}
else i++;
*n=crt;
return r;
}

TNOD* construire_arbore(int p, int u, char *r, int pr[])


{ TNOD *a;
int min, poz;
min = pr[p];
poz = p;
for(int i=p+1; i<=u; i++)
if(min >= pr[i])
{ min=pr[i];
poz=i;
}
a=(TNOD*)malloc(sizeof(TNOD));
a->inf = r[poz];
if(p == u)
a->s = a->d = NULL;
else
{ a->s = construire_arbore(p,poz-1,r,pr);
a->d = construire_arbore(poz+1,u,r,pr);
}
return a;
}

void forma_poloneza(TNOD* rad, char* exp)


{ int l;
if(rad)
{ l = strlen(exp);
exp[l] = rad->inf;
exp[l+1] = '\0';
forma_poloneza(rad->s, exp);
forma_poloneza(rad->d, exp);
}
}

float evaluare(TNOD* rad)


{ if(rad)
if(rad->s)
switch (rad->inf)
{ case '+': rad->v =
break;
case '-': rad->v =
break;
case '*': rad->v =
break;
case '/': rad->v =
}
return rad->v;
}

evaluare(rad->s) + evaluare(rad->d);
evaluare(rad->s) - evaluare(rad->d);
evaluare(rad->s) * evaluare(rad->d);
evaluare(rad->s) / evaluare(rad->d);

void citire_valori_operanzi(TNOD* rad)


{ if(rad)
if(rad->s == NULL)
{ printf("%c=", rad->inf);
scanf("%f",&(rad->v));
}
else
{ citire_valori_operanzi(rad->s);
citire_valori_operanzi(rad->d);
}
}

void main()
{ char expresie[100], *efp, *fpd;
int p[100],n;
TNOD* radacina_arbore_structura;
printf("\nExpresia de analizat (corecta, conform restrictiilor):\n");
gets(expresie);
radacina_arbore_structura=NULL;
//calcul prioritati
efp=prioritati(expresie,p,&n);
//construire arbore
radacina_arbore_structura=construire_arbore(0,n-1,efp,p);
//determinarea formei poloneze a expresiei
fpd=(char*)malloc(strlen(efp));
fpd[0]='\0';
forma_poloneza(radacina_arbore_structura,fpd);
printf("\nForma poloneza directa: %s",fpd);
//evaluare expresie
printf("\nValorile operanzilor:\n");
citire_valori_operanzi(radacina_arbore_structura);
evaluare(radacina_arbore_structura);
printf("\nValoare expresiei este: %7.3f\n",radacina_arbore_structura>v);
}

Atenie:
Dac mai multe elemente au
aceeai prioritate minim, se
alege ultimul pentru a fi rdcin
Exemplu:
a-b*c+d
a=100, b=2, c=5, d=10

Probleme de rezolvat
Eliminarea spaiilor
Utilizarea altor operatori
Utilizarea de identificatori mai
lungi