shouldz

Estrutura de Dados - Arvore AVL

Sep 28th, 2019
179
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.54 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. /*
  5. /@autor: Shouldz
  6. /@Linguagem: C
  7. /@Descrição: [Estrutura de Dados] Árvore AVL com operação de inserção recursiva.
  8. */
  9.  
  10. typedef struct no{
  11.     int valor;
  12.     int fb;
  13.     struct no *dir;
  14.     struct no *esq;
  15. }no;
  16.  
  17. no *criar_no(int valor, int *cresceu){
  18.     no *criar_no = malloc(sizeof(no));
  19.     criar_no -> valor = valor;
  20.     criar_no -> fb = 0;
  21.     criar_no -> dir = NULL;
  22.     criar_no -> esq = NULL;
  23.     *cresceu = 1;
  24.     return criar_no;
  25. }
  26.  
  27. no *rotacao_simples_direita(no *pivo){
  28.     no *u = pivo -> esq;
  29.     no *t2 = u -> dir;
  30.     u -> fb = 0;
  31.     pivo -> fb = 0;
  32.     pivo -> esq = t2;
  33.     u -> dir = pivo;
  34.     return u;
  35. }
  36.  
  37. no *rotacao_simples_esquerda(no *pivo){
  38.     no *u = pivo -> dir;
  39.     no *t2 = u -> esq;
  40.     u -> fb = 0;
  41.     pivo -> fb = 0;
  42.     pivo -> dir = t2;
  43.     u -> esq = pivo;
  44.     return u;
  45. }
  46.  
  47. no *rotacao_dupla_direita(no *pivo){
  48.     //situação inicial da arvore
  49.     no *u = pivo -> esq;
  50.     no *v = u -> dir;
  51.     no *t2 = v -> dir;
  52.     no *t3 = v -> esq;
  53.     switch(v -> fb){
  54.         //alteração do fator de balanço referente ao final    
  55.         case 0:
  56.             //caso V tenha os dois filhos  
  57.             v -> fb = 0;
  58.             u -> fb = 0;
  59.             pivo -> fb = 0;
  60.             break;
  61.         case 1:
  62.             //caso V tenha apenas filho direito
  63.             v -> fb = 0;
  64.             u -> fb = -1;
  65.             pivo -> fb = 0;
  66.             break;
  67.         case -1:
  68.             //caso V tenha apenas filho esquerdo
  69.             v -> fb = 0;
  70.             u -> fb = 0;
  71.             pivo -> fb = 1;
  72.             break;
  73.     }
  74.     //situação final da arvore
  75.     v -> dir = pivo;
  76.     v -> esq = u;
  77.     pivo -> esq = t2;
  78.     u -> dir = t3;
  79.     return v;
  80. }
  81.  
  82. no *rotacao_dupla_esquerda(no *pivo){
  83.     no *u = pivo -> dir;
  84.     no *v = u -> esq;
  85.     no *t2 = v -> esq;
  86.     no *t3 = v -> dir;
  87.     switch(v -> fb){
  88.         //alteração do fator de balanço referente ao final
  89.         case 0:
  90.             //caso V tenha os dois filhos  
  91.             v -> fb = 0;
  92.             u -> fb = 0;
  93.             pivo -> fb = 0;
  94.             break;
  95.         case 1:
  96.             //caso V tenha apenas filho direito
  97.             v -> fb = 0;
  98.             pivo -> fb = -1;
  99.             u -> fb = 0;
  100.             break;
  101.         case -1:
  102.             //caso V tenha apenas filho esquerdo
  103.             v -> fb = 0;
  104.             pivo -> fb = 0;
  105.             u -> fb = 1;
  106.             break;
  107.     }
  108.     v -> dir = u;
  109.     v -> esq = pivo;
  110.     u -> esq = t3;
  111.     pivo -> dir = t2;
  112.     return v;
  113. }
  114.  
  115. no *balanceamento(no *pivo) {
  116.     //responsavel por definir qual rotação será realizada
  117.     if(pivo->fb == -2 && pivo->esq->fb == -1){
  118.         return rotacao_simples_direita(pivo);
  119.     }else if(pivo -> fb == 2 && pivo -> dir -> fb == 1){
  120.         return rotacao_simples_esquerda(pivo);
  121.     }else if(pivo -> fb == -2 && pivo -> esq -> fb == 1){
  122.         printf("DISPAROU DUPLO DIREITA");
  123.         return rotacao_dupla_direita(pivo);
  124.     }else if(pivo -> fb == 2 && pivo -> dir -> fb == -1){
  125.         printf("DISPAROU DUPLO ESQUERDA");
  126.         return rotacao_dupla_esquerda(pivo);
  127.     }
  128. }
  129.  
  130.  
  131. no *inserir(no *raiz, int valor, int *cresceu){
  132.     //caso base
  133.     if(raiz == NULL){
  134.         return criar_no(valor, cresceu);
  135.     }else{
  136.          //procurar local para o valor, percorrendo as sub-arvores
  137.         if(valor > raiz -> valor){
  138.             raiz -> dir = inserir(raiz -> dir, valor, cresceu);
  139.             if(*cresceu){
  140.                 //calculo de fator de balanço, alterando o fator
  141.                 switch(raiz -> fb){
  142.                     case 0:
  143.                         raiz -> fb = 1;
  144.                         *cresceu = 1;
  145.                         break;
  146.                     case 1:
  147.                         raiz -> fb = 2;
  148.                         *cresceu = 0;
  149.                         //balanceamento chamado para rotacionar a arvore
  150.                         return balanceamento(raiz);
  151.                         break;
  152.                     case -1:
  153.                         raiz -> fb = 0;
  154.                         *cresceu = 0;
  155.                         break;
  156.                 }
  157.             }
  158.         }else{
  159.             raiz -> esq = inserir(raiz -> esq, valor, cresceu);
  160.             if(*cresceu){
  161.                 //calculo de fator de balanço, alterando o fator, de maneira analoga a anterior
  162.                 switch(raiz -> fb){
  163.                     case 0:
  164.                         raiz -> fb = -1;
  165.                         *cresceu = 1;
  166.                         break;
  167.                     case 1:
  168.                         raiz -> fb = 0;
  169.                         *cresceu = 0;
  170.                         break;
  171.                     case -1:
  172.                         raiz -> fb = -2;
  173.                         *cresceu = 0;
  174.                         //balanceamento chamado para rotacionar a arvore
  175.                         return balanceamento(raiz);
  176.                         break;
  177.                 }
  178.             }
  179.         }
  180.         return raiz;
  181.     }
  182. }
  183.  
  184. void preorder(no *arvore){
  185.     if(arvore != NULL){
  186.         printf("[%d fb = %d]", arvore -> valor, arvore -> fb);
  187.         preorder(arvore -> esq);
  188.         preorder(arvore -> dir);
  189.     }
  190. }
  191.  
  192. void main(){
  193.     no *arvore = NULL;
  194.     int cresceu;
  195.     int vetor[] = {50, 20, 15, 70, 45, 32, 27, 37, 12, 18, 21};
  196.     for(int i = 0; i < 11; i++){
  197.         arvore = inserir(arvore, vetor[i], &cresceu);
  198.         preorder(arvore);
  199.         printf("\n======================================================\n");
  200.     }
  201. }
Advertisement
Add Comment
Please, Sign In to add comment