Sunteți pe pagina 1din 22

1

Limbaje evoluate de

programare

1 Limbaje evoluate de programare 1 11/4/2013 4:59 PM
1 Limbaje evoluate de programare 1 11/4/2013 4:59 PM

2

Arbori

2 Arbori 2 11/4/2013 4:59 PM
2 Arbori 2 11/4/2013 4:59 PM
Arbori 3 3  Arborii sunt, ca și listele, colecții de noduri de natură dinamică

Arbori

Arbori 3 3  Arborii sunt, ca și listele, colecții de noduri de natură dinamică și
Arbori 3 3  Arborii sunt, ca și listele, colecții de noduri de natură dinamică și

3

3

Arborii sunt, ca și listele, colecții de noduri de natură dinamică și recursivă, dar spre deosebire

de acestea au o structură neliniară. Modul de organizare a nodurilor:

un singur nod al arborelui nu are ascendenți - rădăcina arborelui;

toate nodurile formează subarbori disjuncți între ei

Arbori 4 4

Arbori

Arbori 4 4
Arbori 4 4

4

4

Arbori 4 4
Arbori binari 5 5  Sunt arbori în care fiecare nod are cel mult doi

Arbori binari

Arbori binari 5 5  Sunt arbori în care fiecare nod are cel mult doi fii,
Arbori binari 5 5  Sunt arbori în care fiecare nod are cel mult doi fii,

5

5

Sunt arbori în care fiecare nod are cel mult doi

fii, denumiți

fiul

stâng

și

fiul

drept.

Aceștia

formează, la rândul lor, subarborele stâng și

subarborele drept. Implementarea unui nod:

struct Nod { int cheie; // declaratii date nod Nod *st,*dr; // adresele fiilor stang si drept

};

Arborele va fi gestionat printr-un pointer ce va conține adresa rădăcinii:

Nod *rad;

Arbori binari 6 6

Arbori binari

Arbori binari 6 6
Arbori binari 6 6

6

6

Arbori binari 6 6
Arbori binari 7 7  Operații fundamentale pe arborii binari: – parcurgerea arborelui – inserarea

Arbori binari

Arbori binari 7 7  Operații fundamentale pe arborii binari: – parcurgerea arborelui – inserarea unui
Arbori binari 7 7  Operații fundamentale pe arborii binari: – parcurgerea arborelui – inserarea unui

7

7

Operații fundamentale pe arborii binari:

parcurgerea arborelui

inserarea unui nod frunză

accesarea unui nod

ștergerea unui nod

ștergerea arborelui

Arbori binari  Parcurgerea arborelui: 8 – parcurgerea în inordine (SRD) void ParcurgereSRD(Nod *rad) {

Arbori binari

Arbori binari  Parcurgerea arborelui: 8 – parcurgerea în inordine (SRD) void ParcurgereSRD(Nod *rad) { //
Arbori binari  Parcurgerea arborelui: 8 – parcurgerea în inordine (SRD) void ParcurgereSRD(Nod *rad) { //

Parcurgerea arborelui:

8

parcurgerea în inordine (SRD)

void ParcurgereSRD(Nod *rad) {

// parcurgere in inordine

if (rad) {

ParcurgereSRD(rad->st);

cout<<rad->cheie<<" ";

ParcurgereSRD(rad->dr);

}

}

parcurgerea în preordine (RSD)

void ParcurgereRSD(Nod *rad) {

// parcurgere in preordine

if (rad){

cout<<rad->cheie<<" ";

ParcurgereRSD(rad->st);

ParcurgereRSD(rad->dr);

}

}

8

Arbori binari 9 9 – parcurgerea în postordine (SDR) void ParcurgereSDR(Nod *rad){ if (rad){

Arbori binari

Arbori binari 9 9 – parcurgerea în postordine (SDR) void ParcurgereSDR(Nod *rad){ if (rad){
Arbori binari 9 9 – parcurgerea în postordine (SDR) void ParcurgereSDR(Nod *rad){ if (rad){

9

9

parcurgerea în postordine (SDR)

void ParcurgereSDR(Nod *rad){

if (rad){

ParcurgereSDR(rad->st);

ParcurgereSDR(rad->dr);

cout<<rad->cheie<<" ";

}

}

Ștergerea arborelui:

void StergereArbore(Nod*&rad){

if (rad){

StergereArbore(rad->st);

StergereArbore(rad->dr);

delete rad;

}

}

10 10 Arbori binari de căutare  Sunt arbori binari cu următoarea proprietate: cheia oricărui

10

10

Arbori binari de căutare

10 10 Arbori binari de căutare  Sunt arbori binari cu următoarea proprietate: cheia oricărui nod
10 10 Arbori binari de căutare  Sunt arbori binari cu următoarea proprietate: cheia oricărui nod

Sunt arbori binari cu următoarea proprietate:

cheia oricărui nod tată este mai mare decât

oricare cheie din subarborele stâng și mai mică decât oricare cheie a subarborelui drept. În plus,

cheile nodurilor sunt distincte.

Crearea unui arbore de căutare se realizează prin inserarea repetată a nodurilor într-un arbore

inițial vid. Deci la început, pointerul prin care este

gestionat arborele trebuie inițializat cu 0

( rad=NULL ;)

11 11 Arbori binari de căutare  Inserarea unei frunze: - se pornește din rădăcina

11

11

Arbori binari de căutare

11 11 Arbori binari de căutare  Inserarea unei frunze: - se pornește din rădăcina arborelui
11 11 Arbori binari de căutare  Inserarea unei frunze: - se pornește din rădăcina arborelui

Inserarea unei frunze:

- se pornește din rădăcina arborelui

- dacă nodul curent nu este nul, se compară cheia de inserat cu cheia nodului curent:

- dacă sunt egale, se renunță la inserare

- dacă este mai mică, se face inserarea în subarborele stâng urmând același procedeu

- dacă este mai mare, se face inserarea în subarborele drept după

aceeași metodă

- dacă nodul curent este nul, aici se va face inserarea: se alocă memorie pentru noul nod și se încarcă cu datele nodului, respectiv NULL pentru cei doi fii ai săi.

12 12 Arbori binari de căutare  Inserarea unei frunze: void Inserare(Nod*&rad, int info){ if

12

12

Arbori binari de căutare

12 12 Arbori binari de căutare  Inserarea unei frunze: void Inserare(Nod*&rad, int info){ if (rad==NULL){
12 12 Arbori binari de căutare  Inserarea unei frunze: void Inserare(Nod*&rad, int info){ if (rad==NULL){

Inserarea unei frunze:

void Inserare(Nod*&rad, int info){

if (rad==NULL){

rad=new Nod;

rad->cheie=info;

rad->st=NULL;

rad->dr=NULL;

}

else

if (info==rad->cheie)

cout<<"Nodul deja exista";

else if (info<rad->cheie)

Inserare(rad->st,info);

else

Inserare(rad->dr,info);

}

13 13 Arbori binari de căutare  Accesarea (căutarea) unui nod de cheie dată :

13

13

Arbori binari de căutare

13 13 Arbori binari de căutare  Accesarea (căutarea) unui nod de cheie dată : int
13 13 Arbori binari de căutare  Accesarea (căutarea) unui nod de cheie dată : int

Accesarea (căutarea) unui nod de cheie dată:

int Cautare(Nod *rad, int info){

if (rad==NULL) return 0;

else

if (info==rad->cheie)

return 1;

else if (info<rad->cheie)

return Cautare(rad->st,info);

else

return Cautare(rad->dr,info);

}

14 14 Arbori binari de căutare  Alte operații legate de parcurgere: – determinarea numărului

14

14

Arbori binari de căutare

14 14 Arbori binari de căutare  Alte operații legate de parcurgere: – determinarea numărului de
14 14 Arbori binari de căutare  Alte operații legate de parcurgere: – determinarea numărului de

Alte operații legate de parcurgere:

determinarea numărului de noduri din arbore

int NumarNoduri(Nod *rad) { // numara nodurile arborelui if (rad!=NULL) return 1+ NumarNoduri(rad->st)+ NumarNoduri(rad->dr else return 0;

}

determinarea înălțimii arborelui

int Inaltime(Nod *rad) { // calculeaza inaltimea arborelui if (rad!=NULL) return 1+ max(Inaltime(rad->st),Inaltime(rad->dr)); else return 0;

}

15 15 Arbori binari de căutare – afișarea nodurilor de pe un anumit nivel void

15

15

Arbori binari de căutare

15 15 Arbori binari de căutare – afișarea nodurilor de pe un anumit nivel void AfisareNivel(Nod
15 15 Arbori binari de căutare – afișarea nodurilor de pe un anumit nivel void AfisareNivel(Nod

afișarea nodurilor de pe un anumit nivel

void AfisareNivel(Nod *rad, int nivel) {

// afisarea nodurilor unui nivel

if (rad!=NULL)

if (nivel==0)

cout<<rad->cheie;

else {

AfisareNivel(rad->st,nivel-1);

AfisareNivel(rad->dr,nivel-1);

}

}

16 16 Arbori binari de căutare – afișarea frunzelor arborelui void AfisareFrunze(Nod *rad) { //

16

16

Arbori binari de căutare

16 16 Arbori binari de căutare – afișarea frunzelor arborelui void AfisareFrunze(Nod *rad) { // afisarea
16 16 Arbori binari de căutare – afișarea frunzelor arborelui void AfisareFrunze(Nod *rad) { // afisarea

afișarea frunzelor arborelui

void AfisareFrunze(Nod *rad) {

// afisarea frunzelor

if (rad!=NULL)

if (rad->st==NULL && rad->dr==NULL)

cout<<rad->cheie;

else {

AfisareFrunze(rad->st);

AfisareFrunze(rad->dr);

}

}

17 17 Arbori binari de căutare  Ștergerea unui nod de cheie dată : –

17

17

Arbori binari de căutare

17 17 Arbori binari de căutare  Ștergerea unui nod de cheie dată : – se
17 17 Arbori binari de căutare  Ștergerea unui nod de cheie dată : – se

Ștergerea unui nod de cheie dată:

se identifică nodul de șters:

- se pornește din rădăcina arborelui

- dacă nodul curent nu este nul, se compară valoarea căutată cu

cheia nodului curent:

- dacă sunt egale, a fost identificat nodul de șters

- dacă este mai mică, se continuă căutarea în subarborele stâng urmând același procedeu

- dacă este mai mare, se continuă căutarea în subarborele drept după același algoritm

- dacă nodul curent este nul, valoarea căutată nu există în arbore.

18 18 Arbori binari de căutare – d acă nodul de șters a fost identificat,

18

18

Arbori binari de căutare

18 18 Arbori binari de căutare – d acă nodul de șters a fost identificat, putem
18 18 Arbori binari de căutare – d acă nodul de șters a fost identificat, putem

dacă nodul de șters a fost identificat, putem avea următoarele situații:

- nodul ce urmează a fi șters este nod terminal (frunză): în acest caz se face ștergerea, iar adresa sa se înlocuiește cu NULL, ceea ce înseamnă ca părintele acestuia va avea legătura către el înlocuită cu 0.

- nodul de șters are doar subarbore drept, caz în care părintelui său i se va înlocui adresa către el cu adresa subarborelui drept

respectiv, după care se șterge nodul.

- nodul de șters are doar subarbore stâng, caz în care părintelui său i se va înlocui adresa către el cu adresa subarborelui stâng

respectiv, după care se șterge nodul.

19 19 Arbori binari de căutare - nodul de șters are ambii subarbori: în acest

19

19

Arbori binari de căutare

19 19 Arbori binari de căutare - nodul de șters are ambii subarbori: în acest caz,
19 19 Arbori binari de căutare - nodul de șters are ambii subarbori: în acest caz,

- nodul de șters are ambii subarbori: în acest caz, el se șterge

logic (se modifică valoarea cheii) și un alt nod se șterge fizic:

- se identifică nodul cu cea mai mare valoare din subarborele stâng; acesta va fi nodul șters fizic; el are doar subarbore stâng

- în locul informației nodului curent se copiază cheia nodului

de șters fizic (găsit anterior)

- apar următoarele situații:

- dacă nodul de șters fizic e descendent direct al celui curent, atunci

subarborele său stâng devine subarbore stâng al nodului curent

- în caz contrar, subarborele stâng al nodului de șters fizic devine subarbore drept al părintelui său

- în cele din urmă se eliberează memoria nodului care se

șterge fizic

20 20 Arbori binari de căutare void StergereNod(Nod* &rad, int info) { // stergerea unui

20

20

Arbori binari de căutare

20 20 Arbori binari de căutare void StergereNod(Nod* &rad, int info) { // stergerea unui nod
20 20 Arbori binari de căutare void StergereNod(Nod* &rad, int info) { // stergerea unui nod

void StergereNod(Nod* &rad, int info) {

// stergerea unui nod dupa cheie

if (rad) {

if (info<rad->cheie) StergereNod(rad->st,info);

else if (info>rad->cheie) StergereNod(rad->dr,info);

else {

// trebuie stres nodul curent, a fost identificat

if (rad->st==NULL && rad->dr==NULL) {

// daca este un nod terminal

delete rad;

rad=NULL;

}

else if (rad->st==NULL){

// daca nodul are doar subarbore drept

Nod *temp=rad;

rad=rad->dr;

delete temp;

}

else if (rad->dr==NULL) {

// daca nodul are doar subarbore stang

Nod *temp=rad;

rad=rad->st;

delete temp;

}

21 21 Arbori binari de căutare else { // daca nodul are ambii subarbori //

21

21

Arbori binari de căutare

21 21 Arbori binari de căutare else { // daca nodul are ambii subarbori // caut
21 21 Arbori binari de căutare else { // daca nodul are ambii subarbori // caut

else {

// daca nodul are ambii subarbori

// caut cel mai din dreapta nod al subarborelui stang

Nod *d=rad->st, *td=rad; // nodul de sters fizic si tatal sau

while (d->dr) {

if (d->dr->dr==NULL) td=d;

d=d->dr;

}

rad->cheie=d->cheie;

}

}

else

Nod *temp=d;

if (td==rad)

td->st=d->st;

else

td->dr=d->st;

delete temp;

}

cout<<"Nod inexistent. Stergere esuata\n";

}

END 2 2 22
END 2 2 22
END 2 2 22

END

22

22