Microsoft PowerPoint - Curs_SDA_10_RO_2019_v1.pptx

Documente similare
Microsoft PowerPoint - Curs_SDA_9_RO_2019_v2.pptx

Slide 1

ALGORITMII ŞI REPREZENTAREA LOR Noţiunea de algoritm Noţiunea de algoritm este foarte veche. Ea a fost introdusă în secolele VIII-IX de către Abu Ja f

E_d_Informatica_sp_MI_2015_bar_02_LRO

Microsoft PowerPoint - Curs_SDA_4_RO_2019_v2.pptx

Microsoft Word - _arbori.docx

Slide 1

Diapositive 1

Subiectul 1

Microsoft Word - CarteC.doc

E_d_Informatica_sp_SN_2014_bar_10_LRO

Grafuri neorinetate Aplicatii 1 Care este numărul maxim de componente conexe pe care le poate avea un graf neorientat cu 20 noduri şi 12 muchii? a. 6

Analiză statică Analiza fluxului de date 23 octombrie 2014

Analiză de flux de date 29 octombrie 2012

Limbaje de Programare Curs 6 – Functii de intrare-iesire

Logică și structuri discrete Limbaje regulate și automate Marius Minea marius/curs/lsd/ 24 noiembrie 2014

L7

Logică și structuri discrete Logică propozițională Marius Minea marius/curs/lsd/ 3 noiembrie 2014

Microsoft Word - PCLP2_Curs_4_2019.doc

Probleme rezolvate informatica: Probleme rezolvate grafuri si a

Paradigme de programare

Logică și structuri discrete Relații. Funcții parțiale Marius Minea marius/curs/lsd/ 20 octombrie 2014

Curs 8: Tehnica divizării (I) Algoritmi si structuri de date - Curs 8 1

ALGORITMICĂ. Seminar 3: Analiza eficienţei algoritmilor - estimarea timpului de execuţie şi notaţii asimptotice. Problema 1 (L) Să se determine număru

Slide 1

SUBPROGRAME

1. Găsiți k numerele cele mai apropiate într-un şir nesortat Dându-se un şir nesortat și două numere x și k, găsiți k cele mai apropiate valori de x.

Paradigme de Programare

ExamView Pro - Untitled.tst

Curs 3 Permutari cu repetitie. Combinari. Algoritmi de ordonare si generare

LOGICA MATEMATICA SI COMPUTATIONALA Sem. I,

ALGORITHMICS

Operatorii in C Expresii Operatori aritmetici Operatori de asignare Operatori de incrementare si decrementare Operatori relationali Operatori logici O

Metode de programare Proiectarea algoritmilor

Lecții de pregă,re la informa,că Admitere 2019 Tema: Discutarea problemelor date la ul,mele sesiuni de admitere Bogdan Alexe

Slide 1

Microsoft Word - CarteC.doc

Microsoft Word - Curs1.docx

Microsoft PowerPoint - ImplementareLimbaj [Read-Only] [Compatibility Mode]

Metode de sortare - pregătire admitere - Conf.dr. Alexandru Popa Lect. dr. Andrei Pătraşcu Universitatea din Bucureşti 1

Laborator 2 Incompatibilităţi/Diferenţe între C şi C++ Completări C++ Supraîncărcarea (redefinirea) numelui de funcţii În C nu este permisă existenţa

Structuri de date pentru partiţii de mulţimi O partiţie finită a unei mulţimi nevide S este o mulţime finită de submulţimi ale lui S: {S 1, S 2,..., S

Limbaje de ordinul I LOGICA DE ORDINUL I Un limbaj L de ordinul I este format din: o mulţime numărabilă V = {v n n N} de variabile; conectorii şi ; pa

1

Tablouri unidimensionale Problema 1 Să se determine mulţimea cifrelor unui număr natural n > 0, dat. Exemplu: n= Cifre = {1,2,3,7} Se cere să s

Programarea şi utilizarea calculatoarelor

Limbaje de programare Pointeri. Alocare dinamică (continuare) 26 noiembrie 2012

proiectarea bazelor de date

D.Rusu, Teoria măsurii şi integrala Lebesgue 6 MĂSURA LEBESGUE Cursul 5 Teorema 6.26 Există submulţimi ale lui R care nu sunt măsurabile Lebesgue. Dem

PPSD

Capitole Speciale de Informatică Curs 4: Calculul scorurilor în un sistem complet de extragere a informaţiilor 18 octombrie 2018 Reamintim că în cursu

LUCRAREA 8 PROGRAMAREA NELINIARĂ ÎN REZOLVAREA PROBLEMELOR DIN ENERGETICĂ. METODE DE ORDINUL Aspecte generale Programarea neliniară are o foart

Algoritmi elementari Metode de căutare secvenţială binară Metode de ordonare metoda bulelor metoda inserţiei metoda selecţiei metoda numărării Intercl

Microsoft Word - Algoritmi genetici.docx

Procesarea Imaginilor - Laborator 1: Introducere în utilizarea bibliotecii OpenCV 1 1. Introducere în utilizarea bibliotecii OpenCV 1.1. Introducere S

Poo Laboratoare 1 Contents Laborator7 2 1 Colecţii de obiecte în Java Interfaţa Iterator Interfaţa C

2.1.Tipul tablou unidimensional

Microsoft Word - 2 ES RO.doc

Gheorghe IUREA Adrian ZANOSCHI algebră geometrie clasa a VII-a ediţia a V-a, revizuită mate 2000 standard EDITURA PARALELA 45 Matematică. Clasa a VII-

CURBE BÉZIER În CAGD se utilizează adesea curbele polinomiale, adică acele curbe definite de o parametrizare polinomială: C : [a, b] R 3 C(t) = (x(t),

Top

Fâciu N. Maria-Ema CASA CORPULUI DIDACTIC BRĂILA PROGRAM DE FORMARE INFORMATICĂ ȘI TIC PENTRU GIMNAZIU CLASA A V-A SERIA 1 GRUPA 2 CURSANT: Fâciu N. M

GHERCĂ MAGDA CASA CORPULUI DIDACTIC BRĂILA PORTOFOLIU EVALUARE INFORMATICĂ ȘI TIC PENTRU GIMNAZIU CLASA A V-A Neamț SERIA 1 GRUPA 1 CURSANT: GHERCĂ G

Prelegerea 4 În această prelegere vom învăţa despre: Algebre booleene; Funcţii booleene; Mintermi şi cuburi n - dimensionale. 4.1 Definirea algebrelor

Lucrarea 7 Filtrarea imaginilor BREVIAR TEORETIC Filtrarea imaginilor se înscrie în clasa operaţiilor de îmbunătăţire, principalul scop al acesteia fi

Electricitate II

OPERATII DE PRELUCRAREA IMAGINILOR 1

1. Operatii cu matrici 1 Cerinte: Sa se realizeze functii pentru operatii cu matrici patratice (de dimensiune maxima 10x10). Operatiile cerute sunt: A

Cuantizare Vectoriala.doc

Cursul 12 (plan de curs) Integrale prime 1 Sisteme diferenţiale autonome. Spaţiul fazelor. Fie Ω R n o mulţime deschisă şi f : Ω R n R n o funcţie de

Grafuri - Concepte de baza. Tipuri de grafuri. Modalitati de reprezentare

Programarea şi utilizarea calculatoarelor

C++ Probleme

Şiruri de numere reale Facultatea de Hidrotehnică Universitatea Tehnică Gheorghe Asachi Iaşi, 2015 Analiză Matematică Lucian Maticiuc 1 / 29

Laborator 9: Fire de execuţie Întocmit de: Adina Neculai Îndrumător: Asist. Drd. Gabriel Danciu 20 noiembrie 2011

Microsoft Word - cap1p4.doc

Capitole Speciale de Informatică Curs 1: Extragerea informaţiilor. Modelul boolean şi modelul boolean extins 27 septembrie 2018 Extragerea informaţiil

Limbaje de Programare Curs 5 – Siruri de caractere

Lucrarea nr. 4 - Algoritmi de sortare şi ordonare Breviar teoretic Un algoritm de sortare este o metoda prin care se aranjează elementele unui tablou

Proiectarea Algoritmilor

Cursul 7 Formula integrală a lui Cauchy Am demonstrat în cursul precedent că, dacă D C un domeniu simplu conex şi f : D C o funcţie olomorfă cu f cont

Adresarea memoriei Modurile de adresare constituie un instrument principal pentru reprezentarea în memorie a imaginii datelor, aşa cum este ace

Propunator: Morar Florin Colegiul National Silvania Zalau Discipina: Informatica Nivel liceal, cls. XII 1.Să se scrie în limbajul C/C++ definiţia comp

CAPITOLUL I

Microsoft Word - Curs_08.doc

Şcoala ………

PROIECT DIDACTIC DATE DE IDENTIFICARE Data: Școala : Școala Gimnazială Grigore Moisil Ploiești Clasa: a VI-a Profesor: Ilie Oana Magdalena Disciplina:

Prelegerea 3 În această prelegere vom învăţa despre: Clase speciale de latici: complementate. modulare, metrice, distributive şi 3.1 Semi-distributivi

Microsoft Word - TIC5

PowerPoint-Präsentation

Elemente de aritmetica

Laborator 3

CASA CORPULUI DIDACTIC BRAILA PROGRAM DE FORMARE INFORMATICA SI TIC PENTRU GIMNAZIU CLASA A V-A SERIA 1 GRUPA 2 CURSANT: TIMOFTI V. AFRODITA COLEGIUL

Logică și structuri discrete Mulțimi Casandra Holotescu

Laborator 4: Continuare Programare Orientată pe Obiecte Întocmit de: Adina Neculai Îndrumător: Asist. Drd. Gabriel Danciu 29 octombrie 2011

Microsoft Word - Mihailesc Dan_Test logica (1).doc

Microsoft Word - Software pentru ordonarea multirang a componentelor unei colectivitati.doc

Procesarea Imaginilor Laborator 3: Histograma nivelurilor de intensitate 1 3. Histograma nivelurilor de intensitate 3.1. Introducere În această lucrar

PowerPoint Presentation

Introducere

Transcriere:

SDA (PC2) Curs 10 Arbori Iulian Năstac

Definiția 1: Arbori Recapitulare Arborele este un graf orientat, aciclic și simplu conex. Definiția 2: Un arbore este un ansamblu de structuri de date de natură recursivă şi dinamică. 2

Definiția 3: Prin arbore înţelegem o mulţime finită şi nevidă de elemente numite noduri: ARB = { A1, A2, A3,..., An }, unde n > 0, care are următoarele proprietăţi: - Există un nod şi numai unul care se numeşte rădăcina arborelui. - Celelalte noduri formează submulţimi disjuncte ale lui ARB, care formează fiecare câte un arbore. Arborii respectivi se numesc subarbori ai rădăcinii. 3

Nodurile unui arbore Recapitulare Într-un arbore există noduri cărora nu le mai corespund subarbori. Un astfel de nod se numeşte terminal sau frunză. În legătură cu arborii s-a stabilit un limbaj conform căruia un nod rădacină se spune că este un nod tată, iar subarborii rădăcinii sunt descendenţii acestuia. Rădăcinile descendenţilor unui nod tată sunt fiii lui. 4

Relația de ordine Recapitulare Dacă există o relație de ordine între subarborii oricărui nod al arborelui atunci arborele este ordonat. Pentru un nod al unui arbore ordonat se notează rădăcina primului subarbore ca fiind fiul cel mai în vârstă, iar rădăcina ultimului subarbore drept fiul cel mai tânăr. 5

Arbori binari Recapitulare Un arbore binar este o mulţime finită de elemente care sau este vidă, sau conţine un element numit rădăcina, iar celelalte elemente (dacă există) se împart în două submulţimi disjuncte, care fiecare la rândul ei, este un arbore binar. 6

Particularități Recapitulare Un arbore binar nu se defineşte ca un caz particular de arbore ordonat. Astfel, un arbore nu este niciodată vid, spre deosebire de un arbore binar care poate fi şi vid. Orice arbore ordonat poate fi întotdeauna reprezentat printr-un arbore binar. 7

Modalitatea de transformare a unui arbore ordonat într-un arbore binar (Recapitulare) 1. Se leagă între ei frații descendenți ai aceluiași nod tată și se suprimă legăturile lor cu nodul tată, cu excepția primului fiu. 2. Fostul prim fiu devine fiul stâng al nodului tată, iar ceilalți foști frați formează, în mod consecutiv, subarbori drepți. Fiecare dintre foștii frați devine descendent drept (fiu drept) al fostului frate mai mare. 8

Utilizarea structurilor pentru realizarea unui arbore binar Nodul unui arbore binar poate fi reprezentat ca o dată structurală de tipul NOD care se defineşte în felul următor: typedef struct nod { declaratii ; struct nod *st; struct nod *dr; } NOD; unde: st - este pointerul spre fiul stâng al nodului curent; dr - este pointerul spre fiul drept al aceluiaşi nod. 9

Asupra arborilor binari se pot defini mai multe operaţii: 1. inserarea unui nod frunză într-un arbore binar; 2. accesul la un nod al unui arbore; 3. parcurgerea unui arbore; 4. ştergerea unui arbore. 10

Recapitulare Operaţiile de inserare şi acces la un nod, au la bază un criteriu care să definească locul în arbore al nodului în cauză. Acest criteriu este dependent de problema concretă, la care se aplică arborii binari, pentru a fi rezolvată. 11

Funcția criteriu Definim o funcţie pe care o vom denumi criteriu. Aceasta are doi parametri care sunt pointeri spre tipul NOD. Fie p1 primul parametru al funcţiei criteriu şi p2 cel de-al doilea parametru al ei. Atunci, funcţia criteriu returnează: -1 - dacă p2 pointează spre o dată de tip NOD care poate fi un nod al subarborelui stâng al nodului spre care pointează p1; 1 - dacă p2 pointează spre o dată de tip NOD care poate fi un nod al subarborelui drept al nodului spre care pointează p1; 0 - dacă p2 pointează spre o dată de tip NOD care nu poate fi nod al subarborilor nodului spre care pointează p1. 12

Exemplu: Considerăm următorul șir de numere: 20, 30, 5, 20, 4, 30, 7, 40, 25, 28,... Să se creeze un arbore în nodurile căruia vor fi trecute numerele respective împreună cu frecvența lor de apariție. Practic nodurile acestui arbore vor avea două câmpuri utile: - primul care va conține numărul; - celălalt care va conține frecvența de apariție a numărului. 13

Abordarea problemei: a. p1 - este pointer spre un nod al arborelui în care se face inserarea (iniţial p1 pointează spre rădacina arborelui). b. p2 - este un pointer spre nodul curent (nodul de inserat). c. dacă p2->val < p1->val, atunci se va încerca inserarea nodului curent în subarborele stâng al nodului spre care pointează p1. d. dacă p2->val > p1->val, atunci se va încerca inserarea nodului curent în subarborele drept al nodului spre care pointează p1. e. dacă p2->val = p1->val, atunci nodul curent nu se mai inserează în arbore deoarece există deja un nod corespunzător valorii citite curent. 14

Nodul curent nu se mai inserează în arbore în cazul descris la punctul e (situaţie care în general corespunde cazului când funcţia criteriu returnează valoarea zero). În acest caz, nodurile spre care pointează p1 şi p2 le vom considera echivalente. 15

În cazul exemplului precedent, funcția criteriu este: int criteriu(nod *p1, NOD *p2) { if(p2->nr < p1->nr) return(-1); if(p2->nr > p1->nr) return(1); return(0); } 16

Funcția pentru tratarea echivalenței De obicei, la întâlnirea unei perechi de noduri echivalente, nodul din arbore (spre care pointează p1) este supus unei prelucrări, iar nodul curent (spre care pointează p2) este eliminat. Pentru a realiza o astfel de prelucrare este necesar să se apeleze o funcţie care are ca parametri pointerii p1 şi p2 şi care returnează un pointer spre tipul NOD (de obicei se returnează valoarea lui p1). Vom numi această funcţie: echivalenta. Ea este dependentă de problema concretă, ca şi funcţia criteriu. 17

Exemplu: NOD *echivalenta(nod *q, NOD *p) { q -> frecventa ++; elibnod(p); return(q); } Observație: Funcția de mai sus realizează următoarele: - eliberează zona de memorie ocupată de nodul spre care pointează p; - incrementează valoarea componentei: q -> frecventa; - returnează valoarea lui q. 18

Alte funcții În afară de funcţiile enumerate anterior, vom folosi nişte funcţii specifice pentru operaţii asupra arborilor. Exemple tipice de funcții: elibnod și incnod Unele funcții utilizează o variabilă globală care este un pointer spre rădăcina arborelui. 19

Exemplu de funcție folosită la laborator: void elibnod(nod *p) /* elibereaza zonele din memoria heap ocupate de nodul spre care pointează p */ { free(p -> cuvant); free(p); } 20

Intrarea în arbore (Recapitulare) Numim prad o variabilă globală către rădăcina arborelui binar. Ea se defineşte astfel: NOD *prad; În cazul în care într-un program se prelucrează simultan mai mulţi arbori, se vor utiliza mai multe variabile globale de tip prad; interfaţa dintre funcţii realizându-se cu ajutorul unui parametru care este pointer spre tipul NOD şi căruia i se atribuie, la apel, adresa nodului rădăcină al arborelui prelucrat prin funcţia apelată. 21

1. Inserarea unui nod frunză într-un arbore binar Funcţia insnod ( declarată NOD *insnod() ) inserează un nod nou p în arbore, conform următorilor paşi: 1. Se alocă zona de memorie pentru nodul care urmează să se insereze în arbore. Fie p pointerul care are ca valoare adresa de început a zonei respective. 2. Se apelează funcţia incnod, cu parametrul p, pentru a încărca datele curente în zona spre care pointează p. Dacă incnod returnează valoarea 1, se trece la pasul 3. Altfel se revine din funcţie cu valoarea zero. 22

3. Se fac atribuirile: p->st = p->dr = 0 deoarece nodul de inserat este nod frunză. 4. q = prad 5. Se determină poziţia, în arbore, în care sa se faca inserarea. În acest scop se caută nodul care poate fi nod tată pentru nodul curent: i = criteriu(q,p) 6. Dacă i<0, se trece la pasul 7; altfel se sare la pasul 8. 23

7. Se încearcă inserarea nodului spre care pointează p (nodul curent) în subarborele stâng al arborelui spre care pointează q. - Dacă q -> st are valoarea zero, atunci nodul spre care pointează q nu are subarbore stâng şi nodul curent devine fiu stâng al celui spre care pointează q (q->st = p). Se revine din funcţie returnându-se valoarea lui p. - Altfel se face atribuirea q = q->st (se trece la fiul stâng al nodului spre care pointează q) şi se sare la pasul 5. 8. Dacă i>0, se trece la pasul 9; altfel se sare la pasul 10. 24

9. Se încearcă inserarea nodului spre care pointează p (nodul curent) în subarborele drept al arborelui spre care pointează q. - Dacă q -> dr are valoarea zero, atunci nodul spre care pointează q nu are subarbore drept şi nodul curent devine fiu drept al celui spre care pointează q (q->dr=p). Se revine din funcţie returnându-se valoarea lui p. - Altfel se face atribuirea q = q->dr (se trece la fiul drept al nodului spre care pointează q) şi se sare la pasul 5. 10. Nodul curent nu poate fi inserat în arbore. Se apelează funcţia numită echivalenta şi se revine din funcţie cu valoarea returnată de funcţia echivalenta. 25

2. Accesul la un nod al unui arbore binar Accesul la un nod presupune existența unui criteriu care să permită localizarea în arbore a nodului respectiv. Se va utiliza funcția criteriu. Funcția care realizează căutarea va identifica în arbore un nod echivalent cu cel spre care pointează un pointer p (folosit ca argument al funcției de căutare). 26

Funcția de căutare (numită cauta) va returna: - pointerul spre nodul determinat; - 0 dacă nu există un nod echivalent cu p. 27

NOD *cauta(nod *p) { extern NOD *prad; NOD *q; int i; if (prad = = 0) return 0; /*arborele este vid*/ for (q = prad; q; ) { if ( (i = criteriu(q, p)) = = 0) return q; else if (i < 0) q = q -> st; } } return 0; else q = q -> dr; 28

3. Parcurgerea unui arbore binar Prelucrarea informaţiei păstrată în nodurile unui arbore binar se realizează parcurgând nodurile arborelui respectiv. Parcurgerea nodurilor unui arbore binar se poate face în mai multe moduri, dintre care se remarcă: parcurgerea în preordine; parcurgerea în inordine; parcurgerea în postordine. 29

Parcurgerea în preordine Parcurgerea în preordine înseamnă accesul la rădăcină şi apoi parcurgerea celor doi subarbori ai ei, întâi subarborele stâng, apoi cel drept. Subarborii, fiind ei înşişi arbori binari, se parcurg în acelaşi mod. 30

Parcurgerea în inordine Parcurgerea în inordine înseamnă parcurgerea mai întâi a subarborelui stâng, apoi accesul la rădăcină şi în continuare parcurgerea subarborelui drept. Cei doi subarbori se parcurg în acelaşi mod. 31

Parcurgerea în postordine Parcurgerea în postordine înseamnă parcurgerea mai întâi a subarborelui stâng, apoi a subarborelui drept şi în final accesul la rădăcina arborelui. Cei doi subarbori se parcurg în acelaşi mod. 32

Accesul la un nod permite prelucrarea informaţiei conţinute în nodul respectiv. În acest scop se poate apela o funcţie care este dependentă de problema concretă care se rezolvă cu ajutorul parcurgerii arborelui (de exemplu funcţia prelucrare). void prelucrare( NOD *p) 33

Parcurgerea unui arbore binar in preordine void preord(nod *p) { if(p!= 0) { prelucrare(p); preord(p -> st); preord(p -> dr); } } 34

Parcurgerea unui arbore binar in inordine void inord(nod *p) { if(p!= 0) { inord(p -> st); prelucrare(p); inord(p -> dr); } } 35

Parcurgerea unui arbore binar in postordine void postord (NOD *p) { if(p!= 0) { postord (p -> st); postord (p -> dr); prelucrare(p); } } 36

Exemplu: Reluăm problema cu șirul de numere: 20, 30, 5, 20, 4, 30, 7, 40, 25, 28,... 37

Observații: Programul de la laborator (cu noduri care conțin cuvinte împreună cu frecvența lor de apariție într-un text) se rezolvă mai ușor prin intermediul arborilor (deoarece operația de căutare într-o listă este ineficientă). Procesul de căutare într-un arbore necesită mai puțini pași decât procesul de căutare într-o listă. 38

4. Ștergerea unui arbore binar pentru ștergerea unui arbore binar este necesară parcurgerea lui și ștergerea fiecărui nod al arborelui respectiv. se apelează funcția elibnod. arborele se parcurge în postordine 39

Ștergerea unui arbore binar in postordine void sterge_arb(nod *p) { if(p!= 0) { sterge_arb (p -> st); sterge_arb (p -> dr); elibnod(p); } } 40

Observații: Funcția sterge_arb nu atribuie valoarea zero variabilei globale prad. Această atribuire se va face obligatoriu imediat după ce se apelează funcția sterge_arb 41

Arbore binar degenerat dacă și numai dacă toți subarborii lui sunt de același fel (adică sunt numai stângi, sau numai drepți). 42

5. Ștergerea unui nod precizat printr-o cheie Cheia după care se face căutarea este unică și se găsește în fiecare nod: typedef struct nod { declaratii ; tip cheie; struct nod *st; struct nod *dr; } NOD; unde tipul cheii poate fi char, int, float sau double. Se pot șterge doar noduri care sunt frunză! Ștergerea unui nod care nu este frunză implică operații suplimentare complicate pentru refacerea arborelui. 43

void cauta_sterge(nod *p, int c) /*cheia este de tip int*/ { if (p!= 0) { if (( p -> st = = p -> dr ) && ( p -> st = = 0 ) && ( p -> cheie = = c)) { elibnod (p); return; } cauta_sterge(p -> st, c); cauta_sterge(p -> dr, c); } } Observație: această operație de căutare și ștergere se face în preordine. 44

Observație: La o analiză atenta, funcției anterioare îi lipsește ceva: după ce o un nod frunză identificat a fost șters, tatăl său ar trebui să aibă pointerul recursiv zero catre direcția proaspăt ștearsă! Cum rezolvați această problemă? 45

Precizare În anumite aplicații sunt necesari arbori mai aplatizați, de înălțime mică, dar cu număr mare de noduri. În aceste cazuri se pot înlocui arborii binari cu unii care să permită fiecărui nod un număr mai mare de descendenți direcți. Procedura este relativ simplă, iar în loc de cei doi pointeri recursivi (către subarborele stâng și către cel drept), se utilizează un vector de pointeri recursivi (cu o anumită lungime maximă) care permite tipului de structură, utilizată pentru definirea nodurilor, un număr arbitrar de mare de descendenți direcți. 46

Arbori binari degenerați sunt arbori binari cu n vârfuri dispuse pe n niveluri. 47

Adâncimea și înălțimea unui arbore Vom nota înălțimea unui arbore binar cu h sau cu i 48

Arbori binari speciali P: Un arbore binar de înălțime i are maximum 2 i+1-1 varfuri (sau noduri) Observație: Orice nivel de adâncime k are maximum 2 k noduri 49

Demonstrație prin inducție: Se observă foarte ușor că propoziția anterioară este valabilă pentru i = 0, 1, 2... Dacă pentru înălțimea i avem 2 i+1-1 noduri atunci pentru înălțimea i+1 avem 2 i+2-1 noduri Ne bazăm pe faptul că orice nivel de adâncime k are maximum 2 k noduri. Se observă ușor că pentru înălțimea i+1 avem: Nr_de_noduri = 2 i+1-1 + 2 i+1 = 2 i+1 (1 + 1) - 1 = 2 i+1 2-1 = 2 i+2-1 noduri 50

Arborele binar plin Arborele binar plin este arborele care are numărul maxim de vârfuri (2 i+1-1) pentru o înălțime i dată. De exemplu, arborele binar plin cu înălţimea 2 se prezintă astfel: 51

Observații: Vârfurile unui arbore binar plin se numerotează în ordinea adâncimii. Pentru aceeași adâncime, numerotarea se face în arbore de la stânga la dreapta. 52

Arborele binar complet Un arbore binar cu n vârfuri și de înălțime i este complet dacă se obține din arborele binar plin de înălțime i, prin eliminarea vârfurilor numerotate cu n+1, n+2,... până la 2 i+1-1. 53

Observație : Un arbore binar complet se poate reprezenta secvențial folosind un tablou T, punând vârfurile de adâncime k, de la stânga la dreapta, în pozițiile: T[2 k ], T[2 k +1],, T[2 k+1-1], cu excepția nivelului final care poate fi incomplet. 54

Atenție: acesta este un tablou generic care începe cu T [1] și nu cu T [0]. Se pot opera modificările necesare atunci când se scrie codul în C. 55

Observații: Tatăl unui vârf reprezentat în T[i], i>1, se află în T[i div 2]. Fiii unui vârf reprezentat în T[i], se află (dacă există) în T[2i] și T[2i + 1]. 56

Definim: x max{ n n x, n Z} x min{ n n x, n Z} 57

58 Proprietăți: 1. 2. 3. 4. 1 1 x x x x x n n n 2 2 ab n b a n și și ab n b a n a, b, n Z; a, b 0 n Z; x R; m m n m n 1 m m n m n 1 n, m N * ;

Înălțimea unui arbore binar complet Vom arăta că înălțimea unui arbore complet cu n vârfuri este: i log2 n 59

Demonstrație: Fie: n numărul de vârfuri; i înălțimea arborelui. Știm că: n max = 2 i+1-1 (când arborele binar este plin) n min = 2 i (când pe ultimul nivel avem un singur nod) Rezultă că: i log n 2 min i log n 2 min (1) 60

Deoarece funcția logaritmică este crescătoare avem: i1 i1 log log (2 1) log 2 2 nmax 2 2 i 1 Așadar: log 2 nmax i 1 (2) Din (1) și (2) rezultă că: i log log 2 nmin 2 nmax i 1 i log n 2 61

Arborele HEAP Un heap este un arbore binar complet care are proprietarea că valoarea fiecărui vârf este mai mare sau egală cu valoarea fiecărui fiu al său. Observație: orice heap poate fi reprezentat printr-un vector (tablou unidimensional) 62

Exemplu: Acest heap poate fi reprezentat prin următorul tablou: 10 7 9 4 7 5 2 2 1 6 T[1] T[2] T[3] T[4] T[5] T[6] T[7] T[8] T[9] T[10] 63

Observații: Într-un heap se pot opera modificări la nivel de nod (schimbarea valorii nodului curent). Astfel valoarea unui nod poate crește sau poate fi micșorată anulând ordinea inițială de heap. Ordinea de heap poate fi restabilită simplu prin intermediul a două operațiuni numite de cernere și de filtrare. 64

Filtrarea în heap Dacă valoarea unui vârf crește astfel încât depășește valoarea tatălui, este suficient să se schimbe între ele aceste două valori și să se continue procesul în mod ascendent, până când proprietatea de heap va fi restabilită. Se spune că valoarea modificată a fost filtrată (percolated) către noua sa poziție. 65

Cernerea în heap Dacă valoarea unui vârf scade astfel încât devine mai mică decât valoarea fiului mai mare, este suficient să schimbăm între ele aceste două valori, procesul continuând în mod descendent, până când proprietatea de heap va fi restabilită. Se spune că valoarea modificată a fost cernută (sift down) către noua sa poziție. 66

Notă: În continuare, marea majoritate a funcțiilor vor fi scrise în varianta pseudocod 67

Pseudocodul funcției de cernere void cerne (T[1 n], i) { int k, x, j; k i ; do { j k ; if ((2j n) (T[2j] > T[k])) then k 2j; if ((2j+1 n) (T[2j+1] > T[k])) then k 2j+1; x T[j]; T[j] T[k]; T[k] x } while (j k) } 68

Pseudocodul funcției de filtrare void filtreaza (T[1 n], i) { int k, j, x; k i ; do { j k ; if ((j > 1) (T[ j div 2] < T[k])) then k j div 2; x T[ j]; T[ j] T[k]; T[k] x } while (j k) } 69

Restabilirea proprietății de heap Considerăm T[1..n] ca fiind un heap. Fie i, 1 i n. Lui T[i] i se atribuie valoarea și apoi restabilim proprietatea de heap. void restab_heap (T[1..n], i, ) { variab. loc. x; x T[i]; T[i] ; } if < x then cerne(t, i); else filtreaza(t,i); 70

Heap-ul este un modelul util pentru: Determinarea și extragerea maximului dintr-o mulțime. Inserarea unui nou vârf. Modificarea valorii unui vârf (cu restab_heap). 71

Operațiile anterioare pot fi folosite pentru a implementa o listă dinamică de priorități: Valoarea unui vârf va da prioritatea elementului corespunzător. Evenimentul cu probabilitatea cea mai mare se va afla mereu la rădăcina heap-ului. Prioritatea unui eveniment poate fi modificată în mod dinamic. Acestea sunt câteva principii care stau la baza programelor de baze de date. 72

Exemple de funcții utile: 1) Funcția pentru găsirea unui maxim: gaseste_maxim (T[1..n]) { return T[1]; } 2) Funcția pentru extragerea unui maxim (și ștergerea sa): extr_max (T[1..n]) { var loc x; x T[1]; T[1] T[n]; cerne (T[1..n-1], 1); } return x; 73

3) Funcția de inserare a unui element nou în heap: insert (T[1..n], ) { T[n+1] ; filtreaza (T[1..n+1], n+1); } 74

Observație: în limbajul C nu este luată în considerație valoarea maximă a numărului de elemente ale unui tablou, folosit ca parametru de funcție, astfel încât, de exemplu, pentru funcția de cernere, filtrare, etc., va trebui să ținem seama de un parametru suplimentar. Ex.: cerne (T[ ], n, i) unde n indică indicele ultimului element folosit (!de fapt numerotarea ar trebui să înceapă de la 0). 75

Cum putem forma un heap pornind de la un vector neordonat T[1..n]? O soluție mai puțin eficientă este aceea de a porni de la un heap virtual vid și adăugăm elementele unul câte unul. slow_make_heap(t[1..n]) { for (i=2; i n; i++) filtreaza (T[1..i], i); } 76

Există un algoritm mai eficient care lucrează liniar (din punct de vedere al ordinului/eficienței): make_heap(t[1..n]) { for (i = n div 2; i 1; i - -) cerne (T[ ], i); } 77

Exemplu: Pornind de la vectorul următor (care nu este un heap): 1 6 9 2 7 5 2 7 4 10 T[1] T[2] T[3] T[4] T[5] T[6] T[7] T[8] T[9] T[10] Printr-o succesiune de câțiva pași se ajunge la: 10 7 9 4 7 5 2 2 1 6 T[1] T[2] T[3] T[4] T[5] T[6] T[7] T[8] T[9] T[10] 78

Există variante Def.: Un min-heap este un heap inversat (valoarea fiecărui vârf este mai mică sau egală cu valoarea fiecărui fiu al său). Observații: - Rădăcina min-heap-ului va conține cel mai mic element al vectorului. - Se modifică în mod corespunzător și celelalte proceduri de manipulare a heap-ului. 79

Atenție! Heap-ul este o structură de date foarte atractivă, dar are și limitări. Există operații care nu pot fi efectuate eficient într-un heap. 80

Dezavantajele unui heap: Necesitatea ca arborele să fie complet. Găsirea unui vârf, cu o anumită valoare dată, este ineficientă (pentru că pot exista mai multe vârfuri cu aceeași valoare plasate pe diferite ramuri și nivele din heap). 81

O extensie a conceptului de heap este posibilă pentru arbori compleți și ordonați a căror noduri neterminale au mai mult de doi fii. O astfel de structură accelerează procedura de filtrare. 82

Principala aplicație: O nouă tehnică de sortare (heapsort) Noțiunea de heap a fost introdusă și folosită în anii 60 de Robert W. Floyd și J. W. J. Williams pentru crearea unui algoritm de sortare numit heapsort. 83