Differences

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

Link to this comparison view

sda-ab:laboratoare:07 [2021/02/24 18:02]
ruben_gilian.udroiu
sda-ab:laboratoare:07 [2021/04/04 14:45] (current)
leonard.necula [1. Obiectivele laboratorului]
Line 1: Line 1:
-===== Laboratorul 06: BST si Tries =====+===== Laboratorul 6: BST si AVL ===== 
 + 
 +====== 1. Obiectivele laboratorului ====== 
 + 
 +  *Intelegerea notiunii de arbore binar de cautare (BST) 
 +  *Intelegerea notiunii de arbore binar de cautare echilibrat (AVL) 
 + 
 + 
 +Structura laboratorului se gaseste in **[[https://​github.com/​sda-ab/​lab-06-tasks|acest link.]]** 
 + 
 +====== 2. BST (Binary Search Tree)  ====== 
 + 
 +BST este un arbore binar cu o structură specială adaptată căutărilor eficiente, având următoarele proprietăți:​ 
 +  *se dă un nod rădăcină (numit si **root**) 
 +  *în subarborele său stâng sunt stocate valori **mai mici** decât cea din rădăcină 
 +  *în subarborele său drept sunt stocate valori **mai mari** decât cea din rădăcină 
 + 
 +<note warning>​Într-un BST **NU** apar valori duplicat, iar criteriul/​valoarea în funcție de care se face sortarea se mai numește și **cheie**(key).Cheile sunt alese în așa fel încât proprietatea BST sa se verifice la fiecare nivel.</​note>​ 
 + 
 +**Operații specifice BST** 
 +  *Inserarea/​Căutarea/​Ștergerea unui element 
 +  *Găsirea predecesorului/​succesorului unui element 
 +  *Afișarea datelor stocate in forma sortată 
 +  *Găsirea elementului min/max/al k-lea ca valoare 
 + 
 +{{ :​sda-ab:​laboratoare:​binary-search-tree-example.png?​400 |}} 
 +<​note>​Se poate observa că parcurgerea în **inordine(SRD)** a unui BST va furniza un șir de numere ordonat crescător.</​note>​ 
 + 
 +=== 2.1. Inserarea unui element într-un BST === 
 + 
 +Operația de inserarea a unui element într-un BST adaugă elementul ca frunza a arborelui, iar mai apoi nodul cu cheia data va fi inserat ca fiu stâng sau drept in așa fel încât sa se respecte proprietatea BST. 
 +<code c> 
 +Node* newNode(Data data) 
 +{  Node* node = (Node*)malloc(sizeof(Node));​ 
 +    node->​val = data; 
 +    node->​left = node->​right = NULL; 
 +    return node; 
 +
 + 
 +Node* insert(Node* node, int key) 
 +{ // daca (sub)arborele e gol – se creeaza un nod  
 +   //si se returneaza adresa 
 +    if (node == NULL) return newNode(key);​ 
 +  
 +    //altfel se coboara la stanga sau dreapta in arbore  
 +    if (key < node->​val) ​ node->​left ​ = insert(node->​left,​ key); 
 +                          else if (key > node->​val)  
 +        ​  ​    ​node->​right = insert(node->​right,​ key);    
 +     //​pointerul node se intoarce nemodificat pe acest return  
 +    return node; 
 +} //nu se adauga elemente egale 
 +</​code>​ 
 + 
 +{{ :​sda-ab:​laboratoare:​binary-search-tree-insertion-animation.gif?​400 |}} 
 + 
 +=== 2.2. Căutarea unui element într-un BST === 
 + 
 +  *se începe cu rădăcina, daca valoarea căutata este chiar rădăcina - return 
 +  *daca valoarea cautata < cea stocata in rădăcină – se caută in subarborele stâng, altfel in cel drept.  
 +  *cautarea are loc pana la gasirea elementului sau pana se ajunge la NULL. 
 +<code c> 
 +Node* search(Node* root, int key) { 
 +    //daca radacina e null sau s-a gasit elementul 
 +    if (root == NULL || root->​val == key) 
 +      return root; 
 +    //daca valoarea stocata in radacina e mai mica decat cheia 
 +    if (root->​val < key)  return search(root->​right,​ key); 
 +    // daca valoarea stocata in radacina e mai mare decat cheia 
 +    return search(root->​left,​ key); 
 +} //daca nu se gaseste nod cu aceasta cheie se returneaza NULL 
 + 
 +</​code>​ 
 + 
 +=== 2.3. Ștergerea unui element într-un BST === 
 + 
 +La partea de ștergere, trebuie avut în vedere: 
 +  *Dacă nodul este **frunză** - se elibereaza spatiul ocupat si se seteaza legatura parintelui catre acel nod cu NULL 
 +{{ :​sda-ab:​laboratoare:​stergere_bst_1.png?​400 |}} 
 +  *Dacă nodul are doar un subarbore - nodul e scos din arbore și singurul sau copil (subarbore) e legat direct la parintele său (**OBS**- trebuie actualizat pointerul la stânga sau dreapta din parintele nodului de șters ca să pointeza catre subarborele nodului de șters) 
 +{{ :​sda-ab:​laboratoare:​stergere_bst_2.png?​400 |}} 
 +  *Dacă nodul are doi subarbori - se bazeaza pe ideea că același set de valori poate fi reprezentat folosind 2 BST diferiți în așa fel încât să ne reducem la unul dintre cele două cazuri de mai sus. 
 +{{ :​sda-ab:​laboratoare:​stergere_bst_3_1.png?​400 |}} 
 +<note tip>Idee : Se alege valoarea minimă din subarborele drept, se interschimbă cu valoarea rădăcinii,​ iar apoi se reface arborele pentru a păstra proprietatea BST</​note>​ 
 +{{ :​sda-ab:​laboratoare:​stergere_bst_3_3.png?​400 |}} 
 +<note tip>​Pentru a șterge nodul cu valoarea 12, se caută valoarea minimă in subarborele drept(prin inordine(SRD)),​ se înlocuieste cu această valoarea,​iar apoi valoarea duplicat este ștearsă, ajungându-se la cazul II, în care nodul cu valoarea actualizată 19 are un singur subarbore.</​note>​ 
 + 
 +====== 3. AVL (Adelson-Velsky and Landis tree)  ====== 
 + 
 +Un **AVL** este un arbore binar de căutare echilibrat.(Proprietatea de echilibru trebuie respectata pentru fiecare nod - înălțimea 
 +subarborelui stâng al nodului diferă de inaltimea subarborelui drept al nodului prin cel mult o unitate). De asemenea, trebuie păstrată si condiția de BST. 
 +<​note>​ 
 +Arbore ​ binar **perfect** ​ - fiecare nod are exact 2 copii si  toate frunzele sunt la acelasi nivel. 
 + 
 +Arbore binar **complet** ​ -  un arbore binar care este complet umplut cu posibila exceptie a ultimului nivel care este umplut de la stanga la dreapta  
 + 
 +**OBS!** - arborii compleți sau perfecți sunt implicit echilibrați 
 + 
 +</​note>​ 
 +=== 3.1 Reprezentarea unui nod AVL === 
 + 
 +<code c> 
 +typedef int Data;     
 +typedef struct N  Node;   
 + 
 + ​struct N {  
 +        int height; //​inaltimea 
 +        Data val; // datele efective memorate  
 +        struct ​ N  *left,​*right;​ // legatura catre subarbori  
 +}; 
 + 
 +</​code>​ 
 + 
 +**OBS** - înălțimea unui AVL este floor(log N), iar orice **cautare/​adaugare/​stergere/​gasire min/max de element** se va realiza cu complexitatea **O(log N)** - cost amortizat pe mai multe operații. 
 +<note warning>​**Adăugarea/​Ștergerea** unui nod poate conduce la modificarea conditiei de echilibru, de aceea se folosesc tehnici de **rotație** pentru a reface proprietatea AVL</​note>​ 
 + 
 +=== 3.2 Inserarea unui nod in AVL === 
 + 
 +Operația constă în inserția unui nod într-un BST, urmată de reechilibrarea arborelui. 
 +Există doua tipuri de rotații (care pastrează proprietatea BST): 
 +  *rotație la dreapta 
 +  *rotație la stânga 
 +{{ :​sda-ab:​laboratoare:​tree_rotation.gif?​300 |}} 
 + 
 +=== 3.2.1 Rotații simple === 
 + 
 +  ***RR** - x copilul drept al lui y, y copilul drept al lui z 
 +{{ :​sda-ab:​laboratoare:​avl_rr.png?​300 |}} 
 +  ***LL** - x este copilul stâng al lui y, y copilul stâng al lui z 
 +{{ :​sda-ab:​laboratoare:​avl_ll.png?​300 |}} 
 + 
 +=== 3.2.1 Rotații duble === 
 +  ***LR** - y e copilul stang al lui z si x e copilul drept al lui y  - rotație la stanga + rotație la dreapta 
 +{{ :​sda-ab:​laboratoare:​avl_lr.png?​400 |}} 
 +  ***RL** - y e copilul drept al lui z si x e copilul stâng al lui y – rotașie dreapta +rotație stânga  
 +{{ :​sda-ab:​laboratoare:​avl_rl.png?​400 |}} 
 + 
 +<​note>​**OBS** Ștergerea unui nod se bazeaza pe cea pentru BST, cu updatarea înălțimii și rebalansarea făcută exact ca in cazul inserării unui nod </​note>​ 
 + 
  
  
sda-ab/laboratoare/07.1614182570.txt.gz · Last modified: 2021/02/24 18:02 by ruben_gilian.udroiu
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