Professional Documents
Culture Documents
Aplicaţii
Arbori binari
• Definiţie. Un arbore binar este un arbore orientat cu
proprietatea că pentru orice vîrf v, od(v)2. Dacă od(v)=2,
cei doi descendenţi sînt desemnaţi ca descendent stîng (fiu
stînga) respectiv descendent drept (fiu dreapta). Pentru
vîrfurile cu od(v)=1, unicul descendent este specificat fie ca
fiu stînga, fie ca fiu dreapta
2 3
4 5 6 7
8 9 10
2 3
6 7
4 5
8 9 10
Subarbore stîng Subarbore drept
Arbori binari. Reprezentare.
• Cu structuri dinamice
– Structură nod: informaţie, adresă fiu stîng / drept
TNOD* r;
Arbori binari. Parcurgere
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);
}
Arbori de sortare (căutare)
6 13
4 8 12 15
2 5 7 9 11 14 16
1 3
4 8 12 15
2 5 7 9 11 12,5 14 16
1 3
Arbori de sortare. Ştergere informaţie
10
6 13
4 8 12 15
2 5 7 9 11 14 16
1 3 7,2
7,1 7,3
10
5 12
4 8 11 15
2 7,2 9 14 16
3 7,1 7,3
Arbori de sortare. Ştergere informaţie
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;
}
Arbori de structură
* /
a + + +
b c d e f g
Construire arbore:
1. Calculare priorităţi pentru operanzi şi operatori
2. Construire propriu-zisă a arborelui
Arbori de structură
Exemplu: a*(b+c) –(d+e)/(f+g)
1. Calculare priorităţi pentru operanzi şi operatori
• operatorii aditivi primesc prioritatea 1
• operatorii multiplicativi primesc prioritatea 10
• prioritatea fiecărui operator se măreşte cu 10 pentru
fiecare pereche de paranteze care îl include
• fiecare operand primeşte prioritatea maximă (maxint)
Priorităţile sînt înscrise într-un vector.
• p[i]= prioritatea elementului i din expresie (operator sau
operand, în ordinea apariţiei
Elemente expr. =( a, *, b, +, c, -, d, +, e, /, f, +, g)
Priorităţi =(maxint,10,maxint,11,maxint,1,maxint,11,maxint,10,maxint,11,maxint)
Arbori de structură
Priorităţi =(maxint,10,maxint,11,maxint,1,maxint,11,maxint,10,maxint,11,maxint)
1. dacă expresia curentă este vidă, subarborele curent este vid (nil)
4. fiul stîng este subarborele obţinut prin reprezentarea subexpresiei din stînga
elementului curent
5. fiul drept este subarborele obţinut prin reprezentarea subexpresiei din dreapta
elementului curent
Arbori de structură
Exemplu: a*(b+c) –(d+e)/(f+g)
Elemente expr. =( a, *, b, +, c, --, d, +, e, /, f, +, g)
Priorităţi 1
=(maxint,10,maxint,11,maxint,1,maxint,11,maxint,10,maxint,11,maxint)
- -
Priorităţi =(maxint,10,maxint,11,maxint,1,maxint,11,maxint,10,maxint,11,maxint)
- -
* (d+e)/(f+g) * (d+e)/(f+g)
a b+c a +
() () b + c
(maxint, 11, maxint) b c
() ()
Arbori de structură
Exemplu: a*(b+c) –(d+e)/(f+g)
Elemente expr. =( a, *, b, +, c, -, d, +, e, /, f, +, g)
Priorităţi =(maxint,10,maxint,11,maxint,1,maxint,11,maxint,10,maxint,11,maxint)
- -
* (d+e)/(f+g) * /
a + a + d+e f+g
b c b c
d + e / f + g
(maxint,11,maxint,10,maxint,11,maxint)
Arbori de structură
-*a+bc/+de+fg
a*b+c–d+e/f+g
((a)*((b)+(c)))-(((d)+(e))/((f)+(g)))
Arbori de structură
Evaluare expresie: prin parcurgere în postordine.
a = 3, b = 4, c = 6, d = 10, e = 5, f = 2, g = 1
25
-
30
* 5/
3 +
10 +
15 +
3
4 6 10 5 2 1
Arbori de structură - implementare
#include <stdio.h>
#include <malloc.h>
#include <string.h>
#include <math.h>
#define MAXINT 10000
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;
}
Arbori de structură - implementare
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;
}
Arbori de structură - implementare
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);
}
}
Arbori de structură - implementare
float evaluare(TNOD* rad)
{ if(rad)
if(rad->s)
switch (rad->inf)
{ case '+': rad->v = evaluare(rad->s) + evaluare(rad->d);
break;
case '-': rad->v = evaluare(rad->s) - evaluare(rad->d);
break;
case '*': rad->v = evaluare(rad->s) * evaluare(rad->d);
break;
case '/': rad->v = evaluare(rad->s) / evaluare(rad->d);
}
return rad->v;
}
Arbori de structură - implementare
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);
}
}
Arbori de structură - implementare
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);
}
Arbori de structură - implementare
• Atenţie:
– Dacă mai multe elemente au aceeaşi prioritate
minimă, se alege ultimul pentru a fi rădăcină
– Exemplu:
– a-b*c+d
– a=100, b=2, c=5, d=10
• Probleme de rezolvat
– Eliminarea spaţiilor
– Utilizarea altor operatori
– Utilizarea de identificatori mai lungi