1 / 31

Arbori binari. Aplica ţii

Arbori binari. Aplica ţii. Arbori binari.

cherie
Download Presentation

Arbori binari. Aplica ţii

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Arbori binari. Aplicaţii

  2. 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 • Definiţie. Se numeşte arbore strict binarun arbore binar cu poprietatea că pentru orice vîrf v, od(v)≠1. • Definiţie. Se numeşte nod terminal (sau frunză) orice vîrf v al arborelui cu od(v)=0. În caz contrar nodul v este neterminal.

  3. Arbori binari. Subarbori

  4. Arbori binari. Reprezentare. • Reprezentarea Fiu-Frate (N, R, Fiu, Frate, Inf) • Cu structuri dinamice • Structură nod: informaţie, adresă fiu stîng / drept typedef struct nod { int info; struct nod* st,*dr; } TNOD; • Pentru a cunoaşte arborele: rădăcina TNOD* r;

  5. Arbori binari. Parcurgere • În lăţime • Pe niveluri  Pe niveluri • În adîncime • A-Preordine  Preordine • A-Postordine  Postordine •  Inordine void inordine(TNOD* r) { if(r!=NULL) { inordine(r->st); //prelucrare r->info inordine(r->dr); } } 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 } }

  6. Arbori binari. Parcurgere typedef struct nodc {TNOD* info; struct nodc* next; } TNODC; 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); } } }

  7. Arbori binari. Calculul înălţimii 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); }

  8. Arbori de sortare (căutare) • Definiţie. Un arbore de sortare este un arbore binar cu următoarele proprietăţi • fiecărui nod i al arborelui îi este ataşată o informaţie INF(i) dintr-o mulţime ordonată de valori; • pentru fiecare nod i, INF(i) este mai mare decît INF(j), pentru toate nodurile j din subarborele stîng al arborelui cu rădăcină i; • pentru fiecare nod i, INF(i) este mai mică decît INF(j), pentru toate nodurile j din subarborele drept al arborelui cu rădăcină i; • pentru orice vîrfuri i şi j daca ij atunci INF(i)INF(j).

  9. 9 16 14 12 15 11 6 7 13 5 3 1 8 2 10 4 Arbori de sortare (căutare) • Operaţii • Parcurgeri (pe niveluri, preordine, inordine, postordine) • Adăugare informaţie • Ştergere informaţie • 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

  10. 7 14 12 15 11 6 9 4 13 3 1 8 2 10 16 5 12,5 Arbori de sortare. Adăugare informaţie 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; }

  11. 6 13 7 1 5 16 14 12 15 11 9 5 7,3 3 8 2 10 4 7,1 10 7,3 7,2 16 14 12 15 11 7,2 9 4 3 8 2 7,1 Arbori de sortare. Ştergere informaţie

  12. 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; }

  13. Arbori de structură • Arbore de structură:arbore strict binar folosit pentru a reprezenta expresiile aritmetice care conţin numai operatori binari. Fiecare nod conţine ca informaţie utilă: • un operand, dacă este nod frunză • un operator, dacă nu e nod frunză • Arborele se construieşte acordînd priorităţi operanzilor şi operatorilor. • Parcurgerea arborelui în preordine => forma poloneză directă a expresiei • Parcurgere arborelui în inordine => refacerea expresiei (cu sau fără paranteze).

  14. - + b c a * e d + + f g / Arbori de structură Exemplu: a*(b+c) –(d+e)/(f+g) • Construire arbore: • Calculare priorităţi pentru operanzi şi operatori • Construire propriu-zisă a arborelui

  15. Arbori de structură Exemplu: a*(b+c) –(d+e)/(f+g) • 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)

  16. 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) • Construire arbore: algoritm recursiv. • dacă expresia curentă este vidă, subarborele curent este vid (nil) • altfel se caută elementul cu prioritate minimă din expresia curentă • se creează un nod rădăcinăpentru subarborele curent • fiul stîng este subarborele obţinut prin reprezentarea subexpresiei din stînga elementului curent • fiul drept este subarborele obţinut prin reprezentarea subexpresiei din dreapta elementului curent

  17. - 1 - - (d+e)/(f+g) a*(b+c) (d+e)/(f+g) * a 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) a * b + c (maxint, 10, maxint, 11, maxint) a * b + c (maxint, 10, maxint, 11, maxint) a (maxint) a (maxint)

  18. - - (d+e)/(f+g) * * a a + b c (d+e)/(f+g) 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) ( ) ( ) ( ) ( ) b + c (maxint, 11, maxint) b + c (maxint, 11, maxint)

  19. - (d+e)/(f+g) * - a + + * / b b c c a d+e f+g 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 (maxint,11,maxint,10,maxint,11,maxint) d + e / f + g (maxint,11,maxint,10,maxint,11,maxint)

  20. Arbori de structură Parcurgerea arborelui în preordine=> forma poloneză directă a expresiei: - * a + b c / + d e + f g Parcurgere arborelui în inordine=> refacerea expresiei (cu sau fără paranteze – SRD sau (S)R(D) ): a * b + c – d + e / f + g ((a)*((b)+(c)))-(((d)+(e))/((f)+(g)))

  21. Arbori de structură • Evaluare expresie: prin parcurgere în postordine. • Prelucrarea fiecărui nod r constă în • dacă e nod frunză nu se schimbă nimic • altfel se înlocuieşte informaţia r->inf cu rezultatul expresiei • ss r->inf sd • unde ssşi sd sînt informaţiile dinfiul stîng respectiv drept al nodului curent

  22. - * / 3 + + + 4 10 2 5 1 6 Arbori de structură a = 3, b = 4, c = 6, d = 10, e = 5, f = 2, g = 1 25 30 5 10 15 3

  23. 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 operatori aritmetici + - * / - identificatorii operanzilor formati din numai o litera - fara spatii */ typedef struct nod{ char inf; float v; struct nod *s,*d; } TNOD;

  24. Arbori de structură - implementare 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; }

  25. 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; }

  26. 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; }

  27. 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); } }

  28. 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; }

  29. 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); } }

  30. 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); }

  31. 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

More Related