Sunteți pe pagina 1din 32

Arbori binari.

Aplicaii

Arbori binari
Definiie. Un arbore binar este un arbore orientat cu proprietatea c pentru orice vrf v, () 2. Dac () = 2, cei doi descendeni snt desemnai ca descendent stng (fiu stnga) respectiv descendent drept (fiu dreapta). Pentru vrfurile cu () = 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, () 1. Definiie. Se numete nod terminal (sau frunz) orice vrf v al arborelui cu () = 0. n caz contrar nodul v este neterminal.

Arbori binari. Subarbori


1 2 3

4 8

5 9

6 10

2 6

3 7

4 8

5 9

10 Subarbore drept

Subarbore stng

Arbori binari. Reprezentare.


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

nod rdcin
typedef struct nod { int info; i struct nod* st,*dr; } TNOD;

adresa nodului rdcin

Pentru a cunoate arborele: rdcina


TNOD* r;

Arbori binari. Parcurgere


n lime
Pe niveluri Pe niveluri
Preordine Postordine Inordine

n adncime
A-Preordine A-Postordine

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

Arbori binari. Parcurgere


typedef struct nodc void niveluri(TNOD* r) { TNOD* info; { TNODC* c; struct nodc* next; TNOD* p; } TNODC; 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); } } }

Arbori binari. Calculul nlimii


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 (cutare)


Definiie. Un arbore de sortare 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).

Arbori de sortare (cutare)


Operaii 10 Parcurgeri (pe niveluri, preordine, inordine, postordine) Adugare informaie tergere 6 informaie 13
4 8 12 15

11

14

16

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

Arbori de sortare. Adugare informaie


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; 10 } 12.1? else if(r->info==a) *er=1; else if(r->info>a) r->st=inserare(r->st, a, er); 6 13 else r->dr=inserare(r->dr,a,er); return r; 10 } 4 8 12 15
6 13

7
2

49

11
5 7

12.1

12 14

15

16
16

11

12.1

14

3
1 3

Arbori de sortare. tergere informaie


10 6 5 13 12

12

15

5 5

7 7.2

11

14

16

3 7.1

10

7.3
5 12

11

15

7.2

14

16

7.1

7.3

Arbori de sortare. tergere informaie


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) // 1, 7 { p = r; r = r->dr; free(p); } else if(r->st->dr==NULL) // 13 { r->info = r->st->info; p = r->st; r->st = r->st->st; free(p); } else // 6 { 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
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 Parcurgerea arborelui n preordine forma polonez direct a expresiei Parcurgere arborelui n inordine refacerea expresiei (cu sau fr paranteze) Parcurgere arborelui n postordine evaluarea expresiei

Arbori de structur
Exemplu: ( + ) ( + )/( + )

* /

Construire arbore:

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

Arbori de structur
Exemplu: ( + ) ( + )/( + ) 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) []= prioritatea elementului din expresie (operator sau operand, n ordinea apariiei
a, *, b, +, c, -, d, +, e, /, f, +, g)

Prioritile snt nscrise ntr-un vector.

Elemente expr. =( Prioriti

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

Arbori de structur
Exemplu: ( + ) ( + )/( + )
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.
2.

dac expresia curent este vid, subarborele curent este vid


altfel, se caut elementul cu prioritate minim din expresia curent 3. 4. 5. se creeaz un nod rdcin pentru subarborele curent fiul stng este subarborele obinut prin reprezentarea subexpresiei din stnga elementului curent fiul drept este subarborele obinut prin reprezentarea subexpresiei din dreapta elementului curent

Arbori de structur
Exemplu: ( + ) ( + )/( + )
Elemente expr. =(

Prioriti

--, d, +, e, /, f, +, g) =(maxint,10,maxint,11,maxint,1,maxint,11,maxint,10,maxint,11,maxint) 1
a, *, b, +, c,

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

* + ( + )/( + )

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

Prioriti

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

*
a
() () () ()

( + )/( + ) +
b + c (maxint, 11, maxint)

*
a +

( + )/( + )

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

Prioriti

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

*
a b + c

( + )/( + ) a

*
+ b c +

/
+

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

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

+ / + +
Parcurgere arborelui n inordine => refacerea expresiei (cu sau fr paranteze SRD sau (S)R(D) ):

+ + / +

(() (() + ())) ((() + ())/(() + ()))


( ( + )) (( + )/( + ))

Arbori de structur
Evaluare expresie: n nodurile frunz se nscriu valorile operanzilor, apoi se parcurge arborele n postordine. Prelucrarea fiecrui nod const n dac e nod frunz nu se schimb nimic altfel se nlocuiete informaia > inf cu rezultatul expresiei > inf unde i snt informaiile din fiul stng respectiv drept al nodului curent . La terminarea parcurgerii, nodul rdcin conine valoarea expresiei.

Arbori de structur
a = 3, b = 4, c = 6, d = 10, e = 5, f = 2, g = 1
25 -

30 *
3

5 / + 10 + 15 6 10 5 2 + 3 1

Arbori de structur - implementare


#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 operatorii aritmetici + - * / - identificatorii operanzilor formati din numai o litera - fara spatii */

typedef struct nod{ char inf; float v; struct nod *s,*d; } TNOD;

Arbori de structur - implementare


//calcul prioritati si separare elemente expresie char* prioritati(char *s, int p[], int* n) { int i,j,crt,l; char* r; //i - caracterul curent j efectul curent //crt - elementul curent r - expresia fara paranteze 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; }

Arbori de structur - implementare


//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;
}

Arbori de structur - implementare


TNOD* construire_arbore(int p, int u, char *r, int pr[]) { TNOD *a; > int min, poz; sau 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 = 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);

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


Atenie:
La construirea arborelui, dac mai multe elemente au aceeai prioritate minim, se alege ultimul pentru a fi rdcin Exemplu:
+ a=100, b=2, c=5, d=10

alegnd primul, valoarea expresiei este 80, alegnd ultimul, valoarea expresiei este 100

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

Spor la nvat!