Differences

This shows you the differences between two versions of the page.

Link to this comparison view

sd-ca:laboratoare:lab-09 [2019/04/22 09:56]
andrei.vasiliu2211 [Exerciții]
sd-ca:laboratoare:lab-09 [2023/05/03 01:00] (current)
andrei.otetea [Schelet]
Line 2: Line 2:
  
 Responsabili Responsabili
-  * [[mailto:​dinuaadrian@gmail.com|Andrei ​Dinu]] +  * [[andreiotetea23@gmail.com|Andrei ​Oțetea]] 
-  * [[mailto:​adina.budriga@gmail.com|Adina Budrigă]] +  * [[marin.eduard.c@gmail.com|Eduard Marin]] 
-  * [[mailto:​amirea99@gmail.com|Adrian Mirea]] + 
-  * [[mailto:​andrei.raduta11@gmail.com|Andrei Răduță]]+
 ===== Obiective ===== ===== Obiective =====
  
-În urma parcurgerii ​articolului, studentul va fi capabil să: +În urma parcurgerii ​laboratorului, studentul va fi capabil să: 
-  *înţeleagă structura ​şi proprietățile unui arbore binar de căutare; +  * înțeleagă structura ​și proprietățile unui arbore binar de căutare; 
-  *construiască,​ în limbajul C++, un arbore binar de căutare; +  * construiască,​ în limbajul C, un arbore binar de căutare; 
-  *realizeze o parcurgere a structurii de date prin mai multe moduri; +  * realizeze o parcurgere a structurii de date prin mai multe moduri; 
-  *realizeze diferite operaţii folosind arborii binari de căutare;+  * realizeze diferite operații folosind arborii binari de căutare;
  
-  *definească proprietăţile structurii de heap; +  * definească proprietățile structurii de heap; 
-  *implementeze operaţii de inserare, ​ştergere ​şi căutare care să păstreze proprietatea de heap; +  * implementeze operații de inserare, ​ștergere ​și căutare care să păstreze proprietatea de heap; 
-  *folosească heap-ul pentru a implementa o metodă de sortare eficientă.+  * folosească heap-ul pentru a implementa o metodă de sortare eficientă.
  
 ===== Noțiuni teoretice - ABC ===== ===== Noțiuni teoretice - ABC =====
Line 22: Line 22:
 Un arbore binar de căutare este un arbore binar care are în plus următoarele proprietăți: ​ Un arbore binar de căutare este un arbore binar care are în plus următoarele proprietăți: ​
   * cheile stocate în noduri (informația utilă) aparțin unei mulțimi peste care există o relație de ordine **totală**   * cheile stocate în noduri (informația utilă) aparțin unei mulțimi peste care există o relație de ordine **totală**
-  * cheia dintr-un nod oarecare este **mai mare** decât cheile tuturor nodurilor din subarborele stâng ​şi este **mai mică** decât cheile tuturor nodurilor ce compun subarborele drept+  * cheia dintr-un nod oarecare este **mai mare** decât cheile tuturor nodurilor din subarborele stâng ​și este **mai mică** decât cheile tuturor nodurilor ce compun subarborele drept
  
-Arborii binari de căutare permit menţinerea datelor în ordine ​şi o căutare rapidă a unei chei, ceea ce îi recomandă pentru implementarea de mulţimi şi dicţionare ordonate.+Arborii binari de căutare permit menținerea datelor în ordine ​și o căutare rapidă a unei chei, ceea ce îi recomandă pentru implementarea de mulțimi și dicționare ordonate.
  
-O importantă caracteristică a arborilor de căutare, este aceea că parcurgerea ''​inordine''​ produce o secvenţă ordonată crescător a cheilor din nodurile arborelui.+O importantă caracteristică a arborilor de căutare, este aceea că parcurgerea ''​inordine''​ produce o secvență ordonată crescător a cheilor din nodurile arborelui.
  
 ==== Valoarea maximă ==== ==== Valoarea maximă ====
  
-Valoarea maximă dintr-un arbore binar de căutare se află în **nodul din extremitatea dreaptă** ​şi se determină prin coborârea pe subarborele drept, iar **valoarea minimă** se află în **nodul din extremitatea stângă**, determinarea fiind simetrică.+Valoarea maximă dintr-un arbore binar de căutare se află în **nodul din extremitatea dreaptă** ​și se determină prin coborârea pe subarborele drept, iar **valoarea minimă** se află în **nodul din extremitatea stângă**, determinarea fiind simetrică.
  
 ==== Căutarea ==== ==== Căutarea ====
  
-Căutarea unei chei într-un arbore binar de căutare este asemănătoare căutării binare: cheia căutată este comparată cu cheia din nodul curent (iniţial nodul rădăcină). În funcţie de rezultatul comparaţiei apar trei cazuri:+Căutarea unei chei într-un arbore binar de căutare este asemănătoare căutării binare: cheia căutată este comparată cu cheia din nodul curent (inițial nodul rădăcină). În funcție de rezultatul comparației apar trei cazuri:
   * acestea coincid –> elementul a fost găsit   * acestea coincid –> elementul a fost găsit
   * elementul căutat este mai mic decât cheia din nodul curent –> căutarea continuă în subarborele stâng   * elementul căutat este mai mic decât cheia din nodul curent –> căutarea continuă în subarborele stâng
Line 41: Line 41:
 Pseudocod: Pseudocod:
  
-<​code ​search_function+<​code ​c
-bool cautare(nod, cheie) {+bool căutare(nod, cheie) {
   if nod == NULL   if nod == NULL
     return false;     return false;
Line 49: Line 49:
   ​   ​
   if cheie < nod.cheie   if cheie < nod.cheie
-    return ​cautare(nod.stanga,​ cheie);+    return ​căutare(nod.stanga,​ cheie);
   else   else
-    return ​cautare(nod.dreapta,​ cheie);+    return ​căutare(nod.dreapta,​ cheie);
 } }
 </​code>​ </​code>​
Line 57: Line 57:
 ==== Inserarea ==== ==== Inserarea ====
  
-Inserarea unui nod se faceîn funcţie de rezultatul comparaţiei cheilor, în subarborele stâng sau drept. Dacă arborele este vid, se creează un nod care devine nodul rădăcină al arborelui. În caz contrar, cheia se inserează ca fiu stâng sau fiu drept al unui nod din arbore.+Inserarea unui nod se face în funcție de rezultatul comparației cheilor, în subarborele stâng sau drept. Dacă arborele este vid, se creează un nod care devine nodul rădăcină al arborelui. În caz contrar, cheia se inserează ca fiu stâng sau fiu drept al unui nod din arbore.
  
 ==== Ștergerea ==== ==== Ștergerea ====
  
-Ștergerea unui nod este o operaţie puţin mai complicată,​ întrucât presupune o rearanjare a nodurilor. Pentru eliminarea unui nod dintr-un arbore binar de căutare sunt posibile următoare cazuri: +Ștergerea unui nod este o operație puțin mai complicată,​ întrucât presupune o rearanjare a nodurilor. Pentru eliminarea unui nod dintr-un arbore binar de căutare sunt posibile următoare cazuri: 
-  * nodul de şters nu există -> operaţia se consideră încheiată  +  * nodul de șters nu există -> operația se consideră încheiată  
-  * nodul de şters nu are succesori -> este o frunză +  * nodul de șters nu are succesori -> este o frunză 
-  * nodul de şters are un singur ​successor +  * nodul de șters are un singur ​succesor 
-  * nodul de şters are doi succesori+  * nodul de șters are doi succesori
  
 <note tip> <note tip>
-În cazul ştergerii unui nod frunză sau a unui nod având un singur ​successor, legătura de la părintele nodului de şters este înlocuită prin legătura nodului de şters la succesorul său (**NULL** în cazul frunzelor).+În cazul ștergerii unui nod frunză sau a unui nod având un singur ​succesor, legătura de la părintele nodului de șters este înlocuită prin legătura nodului de șters la succesorul său (**NULL** în cazul frunzelor).
  
-Eliminarea unui nod cu doi succesori se face prin înlocuirea sa cu nodul care are cea mai apropiată valoare de nodul şters. Acesta poate fi nodul din extremitatea dreaptă a subarborelui stâng (**predecesorul**) sau nodul din extremitatea stânga a subarborelui drept (**succesorul**). Acest nod are cel mult un successor.+Eliminarea unui nod cu doi succesori se face prin înlocuirea sa cu nodul care are cea mai apropiată valoare de nodul șters. Acesta poate fi din extremitatea dreaptă a subarborelui stâng (**predecesorul**; se caută cel mai mare nod din acest subarbore, adică "se merge" în dreapta până se ajunge la un nod cu cel mult un succesor, aflat evident în partea stângă, altfel am putea avansa în adâncime pe dreapta) sau nodul din extremitatea stânga a subarborelui drept (**succesorul**; se caută cel mai mic nod din acest subarbore, adică "se merge" în stânga până se ajunge la un nod cu cel mult un succesor, aflat evident în partea dreaptă, altfel am putea avansa în adâncime pe stânga).
 </​note>​ </​note>​
  
-**Complexitatea** operaţiilor (căutare, inserare, ștergere) într-un arbore binar de căutare este - //pe cazul mediu// - **O(logn)**.+**Complexitatea** operațiilor (căutare, inserare, ștergere) într-un arbore binar de căutare este - //pe cazul mediu// - **O(log n)**.
  
-===== Notiuni teoretice - Heap ===== 
  
-Mai sus considerat arborii binari ca fiind o înlănţuire de structuri, legate între ele prin pointeri la descendenţii stâng, respectiv drept. Această reprezentare are avantajul flexibilităţii şi a posibilităţii de a creşte sau micşora dimensiunea arborelui oricât de mult, cu un efort minim. Cu toate acestea, metoda precedentă nu poate fi folosită atunci când este nevoie de o reprezentare compactă a arborelui în memorie (de exemplu pentru stocarea într-un fişier), pentru că acei pointeri nu sunt valizi decât în cadrul programului curent. ​+===== Noțiuni teoretice - Heap ===== 
 + 
 +Mai sus am considerat arborii binari ca fiind o înlănțuire de structuri, legate între ele prin pointeri la descendenții stâng, respectiv drept. Această reprezentare are avantajul flexibilității și a posibilității de a crește sau micșora dimensiunea arborelui oricât de mult, cu un efort minim. Cu toate acestea, metoda precedentă nu poate fi folosită atunci când este nevoie de o reprezentare compactă a arborelui în memorie (de exemplu pentru stocarea într-un fișier), pentru că acei pointeri nu sunt valizi decât în cadrul programului curent. ​
  
 Din acest motiv, există câteva moduri de a stoca arborii într-o structura liniară de date (vectori), dintre care: Din acest motiv, există câteva moduri de a stoca arborii într-o structura liniară de date (vectori), dintre care:
-  *Înlocuirea pointer-ilor din structurile asociate nodurilor cu întregi ce reprezintă indici într-un vector de astfel de structuri. Primul element din vector va fi rădăcina arborelui, ​şi va exista un contor curent (la nivelul întregului vector) care indică următoarea poziţie liberă. Atunci când un nod trebuie adăugat în arbore, i se va asocia valoarea curentă a contorului, iar acesta va fi incrementat. În nodul părinte se va reţine indicele **în vector** al noului nod, în locul adresei lui în memorie (practic acesta este un mic mecanism de alocare de memorie, pe care îl gestionăm noi). +  * Înlocuirea pointer-ilor din structurile asociate nodurilor cu întregi ce reprezintă indici într-un vector de astfel de structuri. Primul element din vector va fi rădăcina arborelui, ​și va exista un contor curent (la nivelul întregului vector) care indică următoarea poziție liberă. Atunci când un nod trebuie adăugat în arbore, i se va asocia valoarea curentă a contorului, iar acesta va fi incrementat. În nodul părinte se va reține indicele **în vector** al noului nod, în locul adresei lui în memorie (practic acesta este un mic mecanism de alocare de memorie, pe care îl gestionăm noi). 
-  *Eliminarea totală a informaţiei legate de predecesori, ​şi folosirea unei formule de calcul a părintelui ​si a descendenţilor unui nod pe baza indicelui acestuia în vector.+  *Eliminarea totală a informației legate de predecesori, ​și folosirea unei formule de calcul a părintelui ​și a descendenților unui nod pe baza indicelui acestuia în vector.
  
 Pentru un arbore binar, cea de-a doua modalitate se implementează conform figurii de mai jos: Pentru un arbore binar, cea de-a doua modalitate se implementează conform figurii de mai jos:
Line 88: Line 89:
  
 <note tip> <note tip>
-Se consideră că arborele este aşezat în vector în ordine (începând de la 0) de la primul nivel până la ultimul, iar nodurile fiecărui nivel se aşează de la stânga la dreapta.+Se consideră că arborele este așezat în vector în ordine (începând de la 0) de la primul nivel până la ultimul, iar nodurile fiecărui nivel se așează de la stânga la dreapta.
 </​note>​ </​note>​
  
Line 95: Line 96:
 {{:​sd-ca:​laboratoare:​2000px-binary_tree_in_array.svg.png?​400}} {{:​sd-ca:​laboratoare:​2000px-binary_tree_in_array.svg.png?​400}}
  
-Se constată că poziţia nodului rădăcină în vector este 0, iar pentru fiecare nod în parte, părintele ​şi descendenţii se pot calcula după formulele:​ +Se constată că poziția nodului rădăcină în vector este 0, iar pentru fiecare nod în parte, părintele ​și descendenții se pot calcula după formulele:​ 
-  * Parinte(i) = (i - 1) / 2, unde i este indicele nodului curent +  * Părinte(i) = (i - 1) / 2, unde i este indicele nodului curent 
-  * IndexStanga(i) = 2 * i + 1, unde i este indicele nodului curent+  * IndexStânga(i) = 2 * i + 1, unde i este indicele nodului curent
   * IndexDreapta(i) = 2 * i + 2, unde i este indicele nodului curent   * IndexDreapta(i) = 2 * i + 2, unde i este indicele nodului curent
  
-===== Proprietăţi ale structurii de heap binar. Operaţii elementare. =====+===== Proprietăți ale structurii de heap binar. Operații elementare. =====
  
-În cele ce urmează vom considera un heap ca fiind de fapt un min-heap. Noţiunile sunt perfect similare ​şi pentru max-heap-uri.+În cele ce urmează vom considera un heap ca fiind de fapt un min-heap. Noțiunile sunt perfect similare ​și pentru max-heap-uri.
  
 Un min-heap binar este un arbore binar în care fiecare nod are proprietatea că valoarea sa este mai mare sau egală cu cea a părintelui său. Un min-heap binar este un arbore binar în care fiecare nod are proprietatea că valoarea sa este mai mare sau egală cu cea a părintelui său.
Line 110: Line 111:
 Un min-heap binar este un arbore binar în care fiecare nod are proprietatea că valoarea sa este mai mică sau egală decât cea a tuturor descendenților săi. Un min-heap binar este un arbore binar în care fiecare nod are proprietatea că valoarea sa este mai mică sau egală decât cea a tuturor descendenților săi.
  
-<​code ​condition>+<​code ​c>
 h[parinte(x)] <= h[x] h[parinte(x)] <= h[x]
 </​code>​ </​code>​
Line 116: Line 117:
 **h[x]** reprezintă valoarea nodului **x**, din vectorul h asociat arborelui. **h[x]** reprezintă valoarea nodului **x**, din vectorul h asociat arborelui.
  
-În mod similar, un max-heap are semnul inegalităţii inversat. Astfel, putem defini ​şi recursiv proprietatea de heap pentru orice (sub)arbore:​+În mod similar, un max-heap are semnul inegalității inversat. Astfel, putem defini ​și recursiv proprietatea de heap pentru orice (sub)arbore:​
   * nodul rădăcină trebuie să respecte proprietatea de heap (inegalitatea);​   * nodul rădăcină trebuie să respecte proprietatea de heap (inegalitatea);​
-  * cei doi subarbori descendenţi sa fie heap-uri.+  * cei doi subarbori descendenți sa fie heap-uri.
  
 <note tip> <note tip>
-Pentru a implementa operaţiile de inserare, ​ştergere, etc. pentru un heap, vom avea nevoie mai întâi de două operaţii elementare:​ +Pentru a implementa operațiile de inserare, ​ștergere, etc. pentru un heap, vom avea nevoie mai întâi de două operații elementare:​ 
-  *''​pushDown'',​ care presupune că heap-ul a fost modificat într-un singur nod şi noua valoare este mai mare decât cel puţin unul dintre descendenţi, şi astfel ea trebuie "​cernută"​ către nivelurile de jos, până când heap-ul devine din nou valid.+  *''​pushDown'',​ care presupune că heap-ul a fost modificat într-un singur nod și noua valoare este mai mare decât cel puțin unul dintre descendenți, și astfel ea trebuie "​cernută"​ către nivelurile de jos, până când heap-ul devine din nou valid.
  
-  *''​pushUp'',​ care presupune că valoarea modificată (sau adăugată la sfârşitul vectorului, în acest caz) este mai mică decât părintele, ​şi astfel se propagă acea valoare spre rădăcina arborelui, până ​cand heap-ul devine valid. ​+  *''​pushUp'',​ care presupune că valoarea modificată (sau adăugată la sfârșitul vectorului, în acest caz) este mai mică decât părintele, ​și astfel se propagă acea valoare spre rădăcina arborelui, până ​când heap-ul devine valid. ​
 </​note>​ </​note>​
  
-===== Operaţii uzuale asupra heap-ului =====+===== Operații uzuale asupra heap-ului =====
  
-Având implementate cele două operaţii de bază, putem defini operaţiile uzuale de manipulare a heap-urilor:​+Având implementate cele două operații de bază, putem defini operațiile uzuale de manipulare a heap-urilor:​
  
 ==== Peek ==== ==== Peek ====
Line 143: Line 144:
   - "​împingem"​ elementul adăugat în vector până la poziția în care se respectă proprietatea de heap; veți folosi funcția ''​pushUp''​.   - "​împingem"​ elementul adăugat în vector până la poziția în care se respectă proprietatea de heap; veți folosi funcția ''​pushUp''​.
  
-<​code ​heap_push_function+<​code ​c
-push(X)+push(heap, X)
 { {
     heap[dimVec] = X;     heap[dimVec] = X;
     dimVec++;     dimVec++;
-    pushUp(dimVec - 1);+    pushUp(heap, dimVec - 1);
 } }
 </​code>​ </​code>​
Line 161: Line 162:
   - vom "​împinge"​ nodul care se afla acum în rădăcina heap-ului către poziția în care trebuie sa fie pentru a fi respectată proprietatea de heap; acest lucru se va face cu funcția ''​pushDown''​.   - vom "​împinge"​ nodul care se afla acum în rădăcina heap-ului către poziția în care trebuie sa fie pentru a fi respectată proprietatea de heap; acest lucru se va face cu funcția ''​pushDown''​.
  
-<​code ​heap_extract_function+<​code ​c
-extractMin()+extractMin(heap)
 { {
     interschimba(heap[0],​ heap[dimVec - 1]);     interschimba(heap[0],​ heap[dimVec - 1]);
     dimVect--;     dimVect--;
-    pushDown(0);​+    pushDown(heap, 0);
 } }
 </​code>​ </​code>​
Line 172: Line 173:
 ===== Algoritmul Heap Sort ===== ===== Algoritmul Heap Sort =====
  
-Întrucât operaţiile de extragere a minimului ​şi de adăugare/​reconstituire sunt efectuate foarte eficient (complexităţi de O(1), respectiv O(log n) ), heap-ul poate fi folosit într-o multitudine de aplicaţii care necesită rapiditatea unor astfel de operaţii. O aplicaţie importantă o reprezintă sortarea, care poate fi implementată foarte eficient folosind heap-uri. Complexitatea acesteia este O(n*log n), aceeaşi cu cea de la quick sort şi merge sort.+Întrucât operațiile de extragere a minimului ​și de adăugare/​reconstituire sunt efectuate foarte eficient (complexități de O(1), respectiv O(log n)), heap-ul poate fi folosit într-o multitudine de aplicații care necesită rapiditatea unor astfel de operații. O aplicație importantă o reprezintă sortarea, care poate fi implementată foarte eficient folosind heap-uri. Complexitatea acesteia este O(n*log n), aceeași cu cea de la quick sort și merge sort.
  
-Se poate implementa ​inserand, pe rând, în heap, toate elementele din vectorul nesortat. Apoi într-un alt şir se extrag minimele. Noul şir va conţine vechiul vector sortat.+Se poate implementa ​inserând, pe rând, în heap, toate elementele din vectorul nesortat. Apoi într-un alt șir se extrag minimele. Noul șir va conține vechiul vector sortat.
  
-<​code ​heap_sort+<​code ​c
-HeapSort() ​+HeapSort(heap
 { {
-    ConstruiesteMaxHeap();​+    ​heap = ConstruiesteMaxHeap();​
     for (i = dimHeap - 1; i >= 1; i--)      for (i = dimHeap - 1; i >= 1; i--) 
     {     {
Line 187: Line 188:
         dimHeap--;         dimHeap--;
         // Reconstituim heap-ul ramas         // Reconstituim heap-ul ramas
-        pushDown(0);​+        pushDown(heap, 0);
     }     }
 } }
Line 194: Line 195:
 ===== ABC vs Heap ===== ===== ABC vs Heap =====
  
-Deși la prima vedere nu există mari diferențe între cele două structuri de date, ele sunt complet diferite. Se poate observa că ele diferă atât la nivelul implementării (bst:pointeri către fii vs heap:​vector), ​cat și al complexităților operațiilor specifice. Totuși, deși ambele se pot folosi în rare cazuri pentru același scop (fără a fi la fel de eficiente), ele au întrebuințări diferite.+Deși la prima vedere nu există mari diferențe între cele două structuri de date, ele sunt complet diferite. Se poate observa că ele diferă atât la nivelul implementării (''​abc:pointeri către fii'' ​vs ''​heap:vector''​), cât și al complexităților operațiilor specifice. Totuși, deși ambele se pot folosi în rare cazuri pentru același scop (fără a fi la fel de eficiente), ele au întrebuințări diferite.
  
 **ABC** **ABC**
-  * Se folosește pentru a implementa arbori echilibrați,​ precum AVL, Red-Black +  * Se folosește pentru a implementa arbori echilibrați,​ precum AVL, Red-Black. 
-  * Prezintă toate avantajele unui vector sortat, venind în plus cu inserare în timp constant.+  * Prezintă toate avantajele unui vector sortat, venind în plus cu inserare în timp logaritmic.
   * Nu este mereu echilibrat.   * Nu este mereu echilibrat.
  
 **HEAP** **HEAP**
-  * Heap-ul stă la baza implementării cozii de priorități și a algoritmului heapsort+  * Heap-ul stă la baza implementării cozii de priorități și a algoritmului heapsort.
   * Se poate folosi pentru găsirea eficientă a celui de-al k-lea cel mai mic/mare (minheap/​maxheap) element.   * Se poate folosi pentru găsirea eficientă a celui de-al k-lea cel mai mic/mare (minheap/​maxheap) element.
-  * Este mereu un arbore echilibrat (complet)+  * Este mereu un arbore echilibrat (complet).
  
 <​note>​ <​note>​
-Un arbore este **echilibrat** dacă fiecare subarbore este echilibrat și înălțimea ​orcăror doi subarbori diferă cu cel mult 1. Această regulă stă la baza implementării unui arbore AVL. Arborii roșu-negru impun alte reguli.+Un arbore este **echilibrat** dacă fiecare subarbore este echilibrat și înălțimea ​oricăror doi subarbori diferă cu cel mult 1.
 </​note>​ </​note>​
  
Line 214: Line 215:
 ===== Schelet ===== ===== Schelet =====
  
-{{sd-ca:​laboratoare:​lab_9:​lab_9_schelet.zip|Schelet}}+{{:sd-ca:​laboratoare:​lab09_2023_1.zip|Schelet ​de laborator}}
  
 ===== Exerciții ===== ===== Exerciții =====
  
 <​note>​ <​note>​
-Fiecare laborator va avea unul sau doua exerciții publice si un pool de subiecte ascunsedin care asistentul poate alege cum se formeaza celelalte puncte ale laboratorului.+Trebuie să vă creați cont de [[https://​lambdachecker.io | Lambda Checker]]dacă nu v-ați creat deja, pe care îl veți folosi la SD pe toată durata semestrului. Aveti grija sa selectati contestul corect la submit, si anume **[[https://​beta.lambdachecker.io/​contest/​36|Laborator 9 SD]]**
 </​note>​ </​note>​
  
-**ABC** 
- 
-Observații privind scheletul de cod pentru arbore binar de cautare: 
-  * Scheletul citește N numere dintr-un fișier dat ca parametru în linia de comandă. 
-  * Aceste N numere sunt introduse într-un arbore binar de căutare, funcționalitate pe care voi trebuie sa o implementaţi. 
-  * Clasa ''​BinarySearchTree''​ conține un membru de tip pointer către T pentru a reţine informaţia utilă şi de asemenea pentru a putea determina mai simplu cazul contrar. Astfel putem verifica dacă un BinarySearchTree conține minim un element (vezi funcția ''​isEmpty''​). 
-  * Funcția ''​removeKey''​ întoarce adresa noului nod rădăcină,​ dacă s-a șters vechea rădăcină. 
- 
-1) [**6p**] (**BinarySearchTree.h**) Implementați următoarele funcționalități de bază ale unui arbore binar de căutare: 
-    * [**1p**] constructor (**TODO 1.1**), destructor (**TODO 1.2**). 
-    * [**1p**] adăugare elemente în arbore (**TODO 1.3**). 
-    * [**1p**] căutare elemente în arbore (**TODO 1.4**). 
-    * [**1p**] parcurgere inordine arbore (**TODO 1.5**). 
-    * [**2p**] ștergere element în arbore 
- 
-**Heap** 
- 
-2) [**4p**] (**heap.h**) Definiţi o structură de vector pe care să poată fi folosite operaţiile de baza ale unui heap şi funcţii de construcţie şi eliberare a structurii: 
- 
-  * Constructor pentru inițializarea unui heap. ''​capacity''​ reprezintă numărul maxim de elemente din vector. Codul va trebui să aloce memorie separată şi apoi să lucreze cu acea memorie. 
-  * Funcție pentru eliberarea memoriei alocate pentru values. 
- 
-Implementaţi operaţiile elementare de lucru cu heap-uri, prezentate în secţiunile anterioare: 
- 
-  * Implementati functiile de calcul ai parintelui si ai descendentilor (functiile vor întoarce -1 în cazul în care părintele, respectiv descendenţii nu există). 
-  * Implementati pushUp si pushDown. 
- 
-Implementaţi operaţiile uzuale de lucru cu heap-uri. 
- 
- 
-3) [**1p**] Se dau vectorii v1 = {10, 8, 7, 5, 4, 6, 1} si v2 = {25, 12, 30, 5, 6, 10, 20}. Verificați dacă respectă condiția de max-heap. 
- 
-<​hidden>​311CAa 
-[**2p**] Implementați operația de delete al unui element pentru un arbore binar de căutare și asigurați-vă că funcționează pentru toate cazurile posibile (0, 1, 2 copii). Metoda va întoarce true dacă va găsi elementul și false dacă nu îl va găsi. 
-</​hidden>​ 
- 
-<​hidden>​311CAb 
-[**2p**] Implementați un iterator pentru un ABC. Primul element peste care se va itera va fi rădăcina. Trebuie să implementați metoda has_next() care verifică dacă mai aveți noduri peste care nu ați iterat și metoda next() care va întoarce următorul cel mai mic element. La final, iteratorul vostru va fi reușit să efectueze o parcurgere inordine. 
-</​hidden>​ 
  
-<​hidden>​312CAa +1) [**3.5p**] ABC
-[**2p**] Creați un ABC. Afișați al 4-lea cel mai mic element folosind O(1) extra space. +
-</​hidden>​+
  
-<​hidden>​312CAb +Task1 va testa operațiile de insert, remove șafișarea (în ordine) a elementelor introduse ​în ABC.
-[**2p**] Creați doi ABC. Afișați câte perechi de noduri ​(n1, n2cu n1 din primul arbore și n2 din al doilea arbore ​căror valoare însumează 13 avem.  Încercați o rezolvare cât mai eficientă, de preferat ​în O(n). +
-</​hidden>​+
  
-<​hidden>​313CAa +2) [**3.5p**] Heap
-[**2p**] Creați un ABC. Verificați dacă există un drum care să înceapă din rădăcină și care se termină într-o frunză care să aibă suma S dată de voi de la tastatură. +
-</​hidden>​+
  
-<​hidden>​313CAb +Task2 va abstractiza următoarea problemă:
-[**2p**] Se dă un vector de 10 elemente nesortate. Folosind un heap afișați al 3-lea cel mai mic element. +
-</​hidden>​+
  
-<​hidden>​314CAa +Avem un clasament în care pot fi introduse echipe ​nume + scor.
-[**2p**] Se dau vectorii v1 = {10, 8, 7, 5, 4, 6, 1} si v2 = {25, 12, 30, 5, 6, 10, 20}. Verificați dacă respectă condiția de max-heap. +
-</​hidden>​+
  
-<​hidden>​314CAb +Trebuie să efectuăm N operații de tipul:
-[**2p**] Aveți variabila vector<​vector<​int>>​ v = { {1, 3, 5}, {2, 10, 15, 17}, {4, 6, 8} }. Ajutându-vă de un heap faceți merge asupra celor 3 vectori din v rezultând un singur vector sortat. +
-</​hidden>​+
  
-<​hidden>​315CAa +  ​1 - introducem o nouă echipă în clasament 
-[**2p**] Creați un ABC. Găsiți cel mai mic strămoș comun al două noduri p și q. Ex:\\ +  * 2 - afișăm prima echipă din clasament 
-{{:sd-ca:​laboratoare:​binarysearchtree_improved.png?​nolink&​200|}}+  * 3 eliminăm prima echipă din clasament
  
-Pentru p = 0 si q = 7cel mai mic strămoș comun este 6.\\ +La finalvom afișa topul echipelor rămase în joc.
-Pentru p = 0 si q = 4, cel mai mic strămoș comun este 2.\\ +
-Pentru p = 2 si q = 4, cel mai mic strămoș comun este 2.\\ +
-</​hidden>​+
  
-<​hidden>​315CAb 
-[**2p**] Creați un ABC. Găsiți suma maximă care se poate forma din valorile nodurilor întâlnite pe un drum care pleacă din rădăcină și se termină într-o frunză. 
-</​hidden>​ 
 ===== Bibliografie ===== ===== Bibliografie =====
  
Line 304: Line 248:
     - [[http://​en.wikipedia.org/​wiki/​Binary_heap|Binary Heap]]     - [[http://​en.wikipedia.org/​wiki/​Binary_heap|Binary Heap]]
     - [[http://​en.wikipedia.org/​wiki/​Heap_sort|Heap Sort]]     - [[http://​en.wikipedia.org/​wiki/​Heap_sort|Heap Sort]]
-        ​ 
sd-ca/laboratoare/lab-09.1555916170.txt.gz · Last modified: 2019/04/22 09:56 by andrei.vasiliu2211
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0