P. 1
Arbori de Grad Oarecare. Arbori Binari

Arbori de Grad Oarecare. Arbori Binari

|Views: 454|Likes:
Published by C_O_D2006

More info:

Published by: C_O_D2006 on Sep 01, 2010
Copyright:Attribution Non-commercial

Availability:

Read on Scribd mobile: iPhone, iPad and Android.
download as PDF, TXT or read online from Scribd
See more
See less

11/06/2013

pdf

text

original

Laborator de Structuri de Date si Algoritmi – Lucrarea nr.

5

Arbori de grad oarecare. Arbori binari
I. Arbori de grad oarecare I.1. Reprezentarea standard I.2. Reprezentarea FIU-FRATE I.3. Reprezentarea prin noduri de dimensiune variabila II. Arbori binari II.1. Reprezentarea standard II.2. Parcurgeri II.3. Exemplu: calcularea valorii maxime dintr-un arbore binar

I. Arbori de grad oarecare
I.1. Reprezentarea "standard"
In reprezentarea standard in fiecare nod al arborelui, pe linga informatia utila se memoreaza informatii de inlantuire care indica descendentii. Intr-o prima varianta de reprezentare, fiecare nod este compus din informatia utila si un vector de dimensine fixa, in care se memoreaza legaturilor de tip pointer la descendenti. Dimensiunea acestui vector este data gradul maxim al nodurilor arborelui. Declaratiile de tip folosite de aceasta reprezentare sint: struct Nod{ Atom data; Nod* vDesc[GRMAX]; }; Un nod va ocupa o zona de memorie de dimensiune fixa:

In figura de mai jos am reprezentat inlantuirile pentru arborele:

pot fi utilizate listele de descendenti. Fiecare nod va contine pe linga informatia utila. Se obtine raportul: N −1 1 = N * GRMAX GRMAX care indica gradul de utilizare eficienta a memoriei.2. . Nod* desc. daca p este un pointer la un nod. In consecinta aceasta reprezentare este acceptabila numai pentru arbori de grad mic.Laborator de Structuri de Date si Algoritmi – Lucrarea nr. doi pointeri: unul va indica lista cu descendentii sai iar cel de-al doilea urmatorul nod din lista de descendenti din care face parte. struct Nod { Atom data. Reprezentarea "FIU-FRATE" Pentru a obtine o utilizare mai eficienta a memoriei. Nod* next. 5 In aceasta reprezentare. descendentul i al nodului va fi identificat direct prin pointerul p->vDesc[i] Intr-un arbore cu un numar N de noduri vor exista N-1 muchii. deci in total N-1 elemente din vectorii de pointeri la descendenti sint ocupate cu informatie utila. }. I.

}. Iata cum vor arata: . Nod* vDesc[GRMAX]. Aceasta solutie se bazeaza pe posibilitatea de a aloca blocuri de memorie de lungime precizata. struct Nod{ Atom data. lista care incepe cu: p->desc I.Laborator de Structuri de Date si Algoritmi – Lucrarea nr. identificarea descendentul i al nodului va necesita parcurgerea listei inlantuite a descendentilor. Vom considera aceeasi declaratie pentru tipul Nod ca si in prima varinata de reprezentare. Economia de memorie se va realiza prin alocarea unor zone de memorie de lungime variabila. int grad. 5 In aceasta varianta arborele de mai sus va avea urmatoarea reprezentare: Avind in vedere semnificatia pointerilor continuti intr-un nod aceasta reprezentare se mai numeste "reprezentarea FIU-FRATE".3. Reprezentarea prin noduri de dimensiune variabila O a treia solutie de reprezentare combina economia de memorie cu avantajele accesarii descendentilor pe baza de index.Un nod de grad 3: . adugind in plus un cimp in care sa se memoreze gradul nodului. adaptata gradului fiecarui nod. In aceasta reprezentare. daca p este un pointer la un nod.

Un nod terminal: Pentru a realiza economia de memorie este necesar ca la alocarea spatiului pentru un nod sa se cunoasca numarul de descendenti si in functie de acest numar sa se aloce spatiul necesar pentru vectorul de descendenti. reprezentarea arborelui dat: TEMA 1 Functia Nod* creareArbore(). . } Utilizind operatorul new. specific limbajului C++. p->grad = grad.Laborator de Structuri de Date si Algoritmi – Lucrarea nr. 5 . in aceasta varianta. Iata cum trebuie scrisa functia make_nod care aloca spatiu pentru un nod de grad dat: Nod* make_nod(int grad) { Nod *p=(Nod*)malloc(sizeof(Nod)-(GRMAX-grad)*sizeof(Nod*)).Un nod de grad 1: . return p. Iata cum va arata. alocarea va avea forma: Nod* p = (Nod*) new char[sizeof(Nod)-(GRMAX-grad)*sizeof(Nod*)].

De exemplu: 1+2*3+4*(5+6) i se asociaza arborele: Arborele este reprezentat dupa metoda 3. Reprezentarea standard In reprezentarea standard. Nod* stg. ■ Sa se evalueze expresia si sa se afiseze rezultatul. II. un nod al arborelui este o structura cu un cimp continind eticheta nodului (data) si doua cimpuri pointeri la cei doi descendenti (lchild si rchild): struct Nod { type data. *drt. Se cere: ■ Sa se determine si sa se afiseze gradul arborelui. tipul Atom fiind echivalat cu tipul int (vezi Anexa A).Laborator de Structuri de Date si Algoritmi – Lucrarea nr. Arbori binari 1. }. 5 din AnexaA citeste de la intrare o expresie aritmetica. cu paranteze. care contine operanzi de o cifra si operatorii + si *. arborele: va avea urmatoarea reprezentare: . ■ Sa se afiseze valoarea tuturor operanzilor utilizati in expresie (fara operatori). Astfel. si creaza arborele de grad oarecare asociat expresiei.

se prelucreaza radacina si apoi se parcurge in inordine subarborele drept. POSTORDINE : SAS SAD rad Se parcurg mai intii in postordine subarborii sting si drept apoi se prelucreaza radacina.Laborator de Structuri de Date si Algoritmi – Lucrarea nr. Valoarea nil pentru acest pointer va semnifica un arbore vid. Pacurgeri Un arbore binar poate fi privit conform urmatoarei scheme recursive: rad = radacina SAS = SubArbore Sting SAD = SubArbore Drept Pe aceasta schema se definesc cele trei moduri de parcurgere a arborelui: PREORDINE : rad SAS SAD Se prelucreaza mai intii radacina apoi se parcurg in preordine subarborii sting si drept. Pentru arborele: . 5 Pentru a putea prelucra un arbore este suficient sa cunostem un pointer la nodul radacina.2. INORDINE : SAS rad SAD Se parcurge in inordone subarborele sting. II.

in schimb executa un apel recursiv in plus pentru fiecare legatura care este NULL. // max este variabila globala void CautaMax(Nod* p) {/* ----------------Parcurgere preordine Varianta 2*/ if (p!=NULL){ if (p->data>max) max=p->data. │ └──────────────────┘ if(p->stg!=NULL) PREORDINE(p->stg). { if (p!=NULL){ ┌───────────────────┐ │ prelucreaza(*p).3.Laborator de Structuri de Date si Algoritmi – Lucrarea nr.Calcularea valoarii maxime dintr-un arbore binar Varianta 1 char max . Exemplu . De exemplu: void PREORDINE(pNod p). . PREORDINE(p->rchild). } A doua varianta nu poate fi aplicata unui arbore vid. │ └───────────────────┘ PREORDINE(p->lchild). if(p->drt!=NULL) PREORDINE(p->drt). } } sau void PREORDINE(Nod* p). in timp ce prima trateaza corect arborele vid. II. { ┌──────────────────┐ │ prelucreaza(*p). 5 cele trei parcurgeri prelucreaza nodurile in ordinea: PREORDINE: INORDINE: POSTORDINE: ABDCEF BDAECF DBEFCA Putem realiza aceste parcurgeri utilizind subrutine recursive.

variabila "max". care este o variabila globala (externa) pentru procedura recursiva.char v2) { if(v1>=v2) return v1. CautaMax(rad). va contine valoarea maxima a etichetelor din arbore. si care a fost initializata cu cea mai mica valoare de tip char. Iata implementarea: char max(char v1. 5 CautaMax(p->stg). } } char ValMax(Nod* p) { max = 0. ValMax(SAD)) Apelurile ValMax(SAS) si ValMax(SAD) se vor executa numai daca subarborii nu sint vizi. } char ValMax(pNod rad) { char vmax. . } Functia Valmax apeleaza o procedura recursiva CautaMax care face o parcurgere prin arbore testind valoarea fiecarui nod. else return v2.Laborator de Structuri de Date si Algoritmi – Lucrarea nr. ValMax(SAS). return max. Varianta 2 Pornind de la schema: stabilim urmatoarea definitie recursiva: ValMax(arbore) = max(rad. La sfirsitul parcurgerii. CautaMax(p->drt).

CPP (vezi ANEXA B) contine declaratiile tipurilor: struct Nod { char data.Laborator de Structuri de Date si Algoritmi – Lucrarea nr. return vmax. *drt. Modulul ARBORE_BINAR. Exemple: Arborele vid: - . if rad->rchild!=NULL vmax = max(vmax. dar are avantajul ca se poate aplica si in cazuri in care nu exista o valoare de eticheta pentru nod mai mica decit toate etichetele posibile (cum am folosit mai sus. } si functia: Nod* creareArboreB(). struct Nod *stg. TEMA 2 1. si intoarce pointer la radacina arborelui citit. } Aceasta varianta nu se poate aplica unui arbore vid.ValMax(rad->lchild)). 5 vmax = rad->data. valoarea 0). In diagrama: '-' -semnifica un arbore vid. if rad->lchild!=NULL vmax = max(vmax. nume -este eticheta unui nod formata dintr-o litera.ValMax(rad->rchild)). care citeste un arbore specificat conform urmatoarei diagrame de sintaxa.

Sa se afiseze toate nodurile pentru care toate valorile continute in subarborele sting sint mai mici decit toate valorile continute in subarborele drept. Incercati pe rind. Creeaza arborele expresiei si calculeaza valoarea expresiei pe arbore. Sa se afiseze toate nodurile care au valoarea din radacina mai mare decit toate valorile din subarborii descendenti. numere intregi de o cifra. Pentru fiecare nod sa se comute subarborele sting cu cel drept si sa se afiseze continutul arborelui in forma cu paranteze. 2. pentru fiecare. Sa se afiseze continutul arborelui in POSTORDINE. O functie pentru determinarea numarului de noduri din arbore. Sa se scrie un program care citeste expresii formate din operanzi. si operatorii + si *.Laborator de Structuri de Date si Algoritmi – Lucrarea nr. De exemplu expresia: (1+3)*4*(5+6) este citita in arborele: . O functie pentru determinarea adincimii arborelui. O functie pentru determinarea numarului de frunze ale arborelui. cele doua variante de abordare prezentate in exemplul cu aflarea valorii maxime): Sa se afiseze continutul arborelui in INORDINE. 5 Sa se scrie si sa se testeze urmatoarele subrutine.

#endif Fisierul Arbore.h> Nod* parse(char buffer[].Laborator de Structuri de Date si Algoritmi – Lucrarea nr.cpp #include #include #include #include #include #include #include "arbore. int grad.h> <ctype. 5 Anexa A Fisierul Arbore.h" <string. return n. Nod* vDesc[GRMAX]. }. length-1). cin >> buffer. Nod* creareArbore() { char buffer[DIM_EXPR].h> <conio. int end).h #ifndef _ARBORE_H_ #define _ARBORE_H_ #define DIM_EXPR 100 #define GRMAX #define Atom 20 int struct Nod { Atom data. int start. 0. Nod* creareArbore(). } .h> <stdlib.h> <stdio.h> <iostream. Nod* n = parse(buffer. int length = strlen(buffer).

start. int start. indici[k++] = i. if ( buffer[i]=='*' ) { if ( openP > 0) continue. indici[0]-1). } } if ( k > 0 ) { Nod *p=(Nod*) new char[sizeof(Nod)-(GRMAX-k+1)*sizeof(Nod*)]. . end). int end) openP = 0. indici[p->grad-2]+1. indici[j-1]+1. i <= end. j < p->grad . p->vDesc[0] = parse(buffer. 5 Nod* { int int int parse(char buffer[]. for (int i = start. indici[GRMAX]. i++) { if ( buffer[i]=='(' ) openP ++.Laborator de Structuri de Date si Algoritmi – Lucrarea nr. p->grad = k+1. for (int j = 1. if ( buffer[i]==')' ) openP --.1. if ( buffer[i]==')' ) openP --. k = 0. indici[k++] = i. p->grad = k+1. indici[j]-1). } openP = 0. } } if ( k > 0 ) { Nod *p=(Nod*) new char[sizeof(Nod)-(GRMAX-k+1)*sizeof(Nod*)]. return p. for (i = start. j++) { p->vDesc[j] = parse(buffer. p->data='+'. i <= end. if ( buffer[i]=='+' ) { if ( openP > 0) continue. openP = 0. i++) { if ( buffer[i]=='(' ) openP ++. } p->vDesc[p->grad-1] = parse(buffer.

indici[j]-1). start. indici[j-1]+1. j < p->grad . } if ( buffer[start] == '(' && buffer[end] == ')' ) return parse(buffer. end-1). } . j++) { p->vDesc[j] = parse(buffer. exit(1). } printf("\nExpresia de intrare este eronata.Laborator de Structuri de Date si Algoritmi – Lucrarea nr. p->data = buffer[start]. 5 p->data='*'. end). return p. start+1. for (int j = 1. Apasati o tasta"). p->vDesc[0] = parse(buffer. getch(). indici[p->grad-2]+1. indici[0]-1). return p. } p->vDesc[p->grad-1] = parse(buffer. p->grad = 0.1. if ( start==end ) if ( isdigit(buffer[start]) ) { Nod* p = (Nod*) new char[sizeof(Nod)-(GRMAX)*sizeof(Nod*)].

Nod* stg. return c.h> "arbore_binar. . c = car.Laborator de Structuri de Date si Algoritmi – Lucrarea nr. readchar().h> <stdlib.h> <conio.h> <stdio."). 5 ANEXA B Arbore_binar. citesteNume(). getch(). printf("Apasati tasta o tasta. }. do c=getchar(). } <alloc. } char readchar() { char c. exit(1).h struct Nod{ char data.cpp #include #include #include #include #include #include char car.h> <ctype.. citesteArboreB(). void char char Nod* Nod* eroare().. *drt. char citesteNume() { char c. creareArboreB(). if(!isalpha(car)) eroare(). Arbore_binar. void eroare() { printf("Sirul de intrare este eronat!\n").h" while(c==' ').

return citesteArboreB().Laborator de Structuri de Date si Algoritmi – Lucrarea nr. rad->data = citesteNume(). if( car!='(' ) { rad->stg = 0. } if( car!=')' ) eroare(). } Nod* citesteArboreB() { Nod* rad. car = readchar(). 5 car = readchar(). } else { car = readchar(). rad->drt = citesteArboreB(). rad->stg = citesteArboreB(). return c. if( car=='-' ) { rad=0. else { car = readchar(). } else { rad = (Nod*) malloc(sizeof(Nod)). } Nod* creareArboreB() { printf("\nIntroduceti arborele:"). } } return rad. if( car!='. rad->drt = 0. } . car = readchar().' ) rad->drt = 0. car = readchar().

You're Reading a Free Preview

Download
scribd
/*********** DO NOT ALTER ANYTHING BELOW THIS LINE ! ************/ var s_code=s.t();if(s_code)document.write(s_code)//-->