Advertisement
Bobita

Laborator_AVL_PAA

Apr 12th, 2024
785
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.59 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. // Structura pentru un nod din arbore
  5. typedef struct Node {
  6.     int key;
  7.     struct Node *left;
  8.     struct Node *right;
  9.     int height;
  10. } Node;
  11.  
  12. // Functie pentru a determina inaltimea unui nod
  13. int height(Node *N) {
  14.     if (N == NULL)
  15.         return 0;
  16.     return N->height;
  17. }
  18.  
  19. // Functie pentru a calcula maximul dintre doua numere
  20. int max(int a, int b) {
  21.     return (a > b) ? a : b;
  22. }
  23.  
  24. // Functie pentru alocarea unui nou nod cu cheia data
  25. Node* newNode(int key) {
  26.     Node* node = (Node*)malloc(sizeof(Node));
  27.     node->key = key;
  28.     node->left = NULL;
  29.     node->right = NULL;
  30.     node->height = 1;  // Noul nod este initial adaugat la frunza
  31.     return(node);
  32. }
  33.  
  34. // Rotatie la dreapta
  35. Node *rightRotate(Node *y) {
  36.     Node *x = y->left;
  37.     Node *T2 = x->right;
  38.  
  39.     // Executa rotatia
  40.     x->right = y;
  41.     y->left = T2;
  42.  
  43.     // Actualizeaza inaltimile
  44.     y->height = max(height(y->left), height(y->right)) + 1;
  45.     x->height = max(height(x->left), height(x->right)) + 1;
  46.  
  47.     // Returneaza noua radacina
  48.     return x;
  49. }
  50.  
  51. // Rotatie la stanga
  52. Node *leftRotate(Node *x) {
  53.     Node *y = x->right;
  54.     Node *T2 = y->left;
  55.  
  56.     // Executa rotatia
  57.     y->left = x;
  58.     x->right = T2;
  59.  
  60.     // Actualizeaza inaltimile
  61.     x->height = max(height(x->left), height(x->right)) + 1;
  62.     y->height = max(height(y->left), height(y->right)) + 1;
  63.  
  64.     // Returneaza noua radacina
  65.     return y;
  66. }
  67.  
  68. // Obtine factorul de echilibru al nodului N
  69. int getBalance(Node *N) {
  70.     if (N == NULL)
  71.         return 0;
  72.     return height(N->left) - height(N->right);
  73. }
  74.  
  75. // Functie recursiva pentru inserarea unei chei in subarborele cu radacina
  76. // la nodul dat si returneaza noua radacina a subarborelui
  77. Node* insert(Node* node, int key) {
  78.     /* 1. Efectuam inserarea normala a unui BST */
  79.     if (node == NULL)
  80.         return(newNode(key));
  81.  
  82.     if (key < node->key)
  83.         node->left = insert(node->left, key);
  84.     else if (key > node->key)
  85.         node->right = insert(node->right, key);
  86.     else // Chei egale nu sunt permise in arborele AVL
  87.         return node;
  88.  
  89.     /* 2. Actualizam inaltimea acestui nod stramos */
  90.     node->height = 1 + max(height(node->left), height(node->right));
  91.  
  92.     /* 3. Obtinem factorul de echilibru al acestui nod stramos
  93.        pentru a verifica daca acest nod a devenit dezechilibrat */
  94.     int balance = getBalance(node);
  95.  
  96.     // Daca acest nod devine dezechilibrat, atunci exista 4 cazuri
  97.  
  98.     // Cazul stanga-stanga
  99.     if (balance > 1 && key < node->left->key)
  100.         return rightRotate(node);
  101.  
  102.     // Cazul dreapta-dreapta
  103.     if (balance < -1 && key > node->right->key)
  104.         return leftRotate(node);
  105.  
  106.     // Cazul stanga-dreapta
  107.     if (balance > 1 && key > node->left->key) {
  108.         node->left = leftRotate(node->left);
  109.         return rightRotate(node);
  110.     }
  111.  
  112.     // Cazul dreapta-stanga
  113.     if (balance < -1 && key < node->right->key) {
  114.         node->right = rightRotate(node->right);
  115.         return leftRotate(node);
  116.     }
  117.  
  118.     /* returneaza pointer-ul nodului (nechimbat) */
  119.     return node;
  120. }
  121.  
  122. // Functia utilitara pentru a gasi nodul cu cea mai mica valoare
  123. // care este mai mare decat nodul dat
  124. Node * minValueNode(Node* node) {
  125.     Node* current = node;
  126.  
  127.     /* gaseste frunza cea mai din stanga */
  128.     while (current->left != NULL)
  129.         current = current->left;
  130.  
  131.     return current;
  132. }
  133.  
  134. // Functie recursiva pentru a sterge un nod cu o cheie data
  135. // din subarborele cu radacina data si returneaza radacina
  136. Node* deleteNode(Node* root, int key) {
  137.     // PASUL 1: EFECTUARE STERGERE NORMALA BST
  138.  
  139.     if (root == NULL)
  140.         return root;
  141.  
  142.     // Daca cheia de sters este mai mica decat cheia radacinii,
  143.     // atunci se afla in subarborele stang
  144.     if ( key < root->key )
  145.         root->left = deleteNode(root->left, key);
  146.  
  147.     // Daca cheia de sters este mai mare decat cheia radacinii,
  148.     // atunci se afla in subarborele drept
  149.     else if( key > root->key )
  150.         root->right = deleteNode(root->right, key);
  151.  
  152.     // Daca cheia este aceeasi cu cheia radacinii, atunci acesta
  153.     // este nodul care trebuie sters
  154.     else {
  155.         // nod cu unul sau fara copil
  156.         if( (root->left == NULL) || (root->right == NULL) ) {
  157.             Node *temp = root->left ? root->left : root->right;
  158.  
  159.             // Fara copil
  160.             if (temp == NULL) {
  161.                 temp = root;
  162.                 root = NULL;
  163.             }
  164.             else // Un copil
  165.              *root = *temp; // Copierea continutului copilului
  166.  
  167.             free(temp);
  168.         }
  169.         else {
  170.             // Nod cu doi copii: Ia succesorul inordine (cel mai mic
  171.             // din subarborele drept)
  172.             Node* temp = minValueNode(root->right);
  173.  
  174.             // Copiaza succesorul inordine in acest nod
  175.             root->key = temp->key;
  176.  
  177.             // Sterge succesorul inordine
  178.             root->right = deleteNode(root->right, temp->key);
  179.         }
  180.     }
  181.  
  182.     // Daca arborele avea doar un nod atunci returneaza
  183.     if (root == NULL)
  184.       return root;
  185.  
  186.     // PASUL 2: ACTUALIZEAZA INALTIMEA NODULUI CURENT
  187.     root->height = 1 + max(height(root->left), height(root->right));
  188.  
  189.     // PASUL 3: VERIFICA ECHILIBRUL NODULUI CURENT
  190.     int balance = getBalance(root);
  191.  
  192.     // Daca acest nod devine dezechilibrat, atunci exista 4 cazuri
  193.  
  194.     // Cazul stanga-stanga
  195.     if (balance > 1 && getBalance(root->left) >= 0)
  196.         return rightRotate(root);
  197.  
  198.     // Cazul stanga-dreapta
  199.     if (balance > 1 && getBalance(root->left) < 0) {
  200.         root->left = leftRotate(root->left);
  201.         return rightRotate(root);
  202.     }
  203.  
  204.     // Cazul dreapta-dreapta
  205.     if (balance < -1 && getBalance(root->right) <= 0)
  206.         return leftRotate(root);
  207.  
  208.     // Cazul dreapta-stanga
  209.     if (balance < -1 && getBalance(root->right) > 0) {
  210.         root->right = rightRotate(root->right);
  211.         return leftRotate(root);
  212.     }
  213.  
  214.     return root;
  215. }
  216.  
  217. // Functie de afisare a arborelui in inordine
  218. void inOrder(Node *root) {
  219.     if (root != NULL) {
  220.         inOrder(root->left);
  221.         printf("%d ", root->key);
  222.         inOrder(root->right);
  223.     }
  224. }
  225.  
  226. int main() {
  227.   Node *root = NULL;
  228.  
  229.   // Exemplu de inserari
  230.   root = insert(root, 10);
  231.   root = insert(root, 20);
  232.   root = insert(root, 30);
  233.   root = insert(root, 40);
  234.   root = insert(root, 50);
  235.   root = insert(root, 25);
  236.  
  237.   printf("Inorder traversal of the constructed AVL tree is \n");
  238.   inOrder(root);
  239.  
  240.   root = deleteNode(root, 20);
  241.  
  242.   printf("\nInorder traversal after deletion of 20 \n");
  243.   inOrder(root);
  244.  
  245.   return 0;
  246. }
  247.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement