Advertisement
DimasDark

L2Q2 ~AVL Tree~Complete

Jul 1st, 2013
255
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.18 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <string.h>
  3.  
  4.  
  5. //AVL BY DIMASDARK ~ALGORITMOS~
  6.  
  7. int _numeroElementos = 0;
  8. int _nivel = 0;
  9. int _valor = 0;
  10. int _rotacao = 0;
  11.  
  12. typedef struct avl
  13. {
  14.     int identificador;
  15.     int valor;
  16.     int altura; //hdireita - hesquerda
  17.     struct avl* esquerda;
  18.     struct avl* direita;
  19.  
  20. } Arv;
  21.  
  22. Arv* inicializar()
  23. {
  24.     return NULL;
  25. }
  26.  
  27. //Remove o minimo a direita e ja retorna o no
  28. Arv* removerMinimoDireita(Arv* arvdir)
  29. {
  30.     Arv* aux = new Arv();
  31.  
  32.     if (arvdir -> esquerda == NULL)
  33.     {
  34.         aux = arvdir -> direita;
  35.         delete(arvdir);
  36.         return aux;
  37.     }
  38.     else
  39.     {
  40.         arvdir -> esquerda = removerMinimoDireita(arvdir -> esquerda);
  41.         return arvdir;
  42.     }
  43. }
  44.  
  45.  
  46. int altura(Arv* no)
  47. {
  48.     if (no == NULL)
  49.         return 0;
  50.     int hesq = altura(no->esquerda);
  51.     int hdir = altura(no->direita);
  52.     return hesq > hdir ? hesq + 1 : hdir + 1;
  53. }
  54.  
  55. int maximo(int a, int b)
  56. {
  57.     return (a > b)? a : b;
  58. }
  59.  
  60. int fatorBalanceamento(Arv* raiz)
  61. {
  62.     if (raiz == NULL)
  63.         return 0;
  64.     return altura(raiz->esquerda) - altura(raiz->direita);
  65. }
  66.  
  67. Arv* novoNo(int i, int v)
  68. {
  69.     Arv* no = new Arv();
  70.     no->identificador = i;
  71.     no->valor = v;
  72.     no->esquerda = NULL;
  73.     no->direita = NULL;
  74.     no->altura = 1;
  75.     return(no);
  76. }
  77.  
  78.  
  79. Arv* rotacaoDireita(Arv* no)
  80. {
  81.  
  82.     Arv* a = no->esquerda;
  83.     Arv* b = a->direita;
  84.  
  85.     // Faz a rotacao
  86.     a->direita = no;
  87.     no->esquerda = b;
  88.  
  89.     // Atualiza altura
  90.     no->altura = maximo(altura(no->esquerda), altura(no->direita))+1;
  91.     a->altura = maximo(altura(a->esquerda), altura(a->direita))+1;
  92.  
  93.     // Retorna o novo no
  94.     return a;
  95. }
  96.  
  97. Arv* rotacaoEsquerda(Arv* no)
  98. {
  99.     Arv* a = no->direita;
  100.     Arv* b = a->esquerda;
  101.  
  102.     a->esquerda = no;
  103.     no->direita = b;
  104.  
  105.     no->altura = maximo(altura(no->esquerda), altura(no->direita))+1;
  106.     a->altura = maximo(altura(a->esquerda), altura(a->direita))+1;
  107.  
  108.     return a;
  109. }
  110.  
  111. //Pega menor valor da esquerda de uma subarvore
  112. Arv* pegaMenor(Arv* no)
  113. {
  114.     Arv* aux = no;
  115.     while (aux->esquerda != NULL)
  116.         aux = aux->esquerda;
  117.  
  118.     return aux;
  119. }
  120.  
  121. Arv* buscaNo(Arv* arv, int t, int &nivel, int &valor,int n = 0)
  122. {
  123.     nivel = n;
  124.     Arv* aux = arv;
  125.     if (arv == NULL)
  126.         return NULL; /* árvore vazia: não encontrou */
  127.     else
  128.     {
  129.         if (t > arv->identificador)
  130.         {
  131.             aux = buscaNo(arv->direita, t, nivel, valor, n+1);
  132.         }
  133.         else if (t < arv->identificador)
  134.         {
  135.             aux = buscaNo(arv->esquerda,t, nivel, valor, n+1);
  136.         }
  137.         else
  138.         {
  139.             valor = aux->valor;
  140.         }
  141.         return aux;
  142.     }
  143. }
  144.  
  145. Arv* insere(Arv* no, int i, int v, int &nivel, int &rotacao, int n = 0)
  146. {
  147.     nivel = n;
  148.     //Se for nulo, ele vai ser a cabeça
  149.     if (no == NULL)
  150.         return(novoNo(i, v));
  151.  
  152.     if (i < no->identificador)
  153.         no->esquerda  = insere(no->esquerda, i, v, nivel, rotacao, n+1);
  154.     else
  155.         no->direita = insere(no->direita, i, v, nivel, rotacao, n+1);
  156.  
  157.     //atualiza altura
  158.     no->altura = maximo(altura(no->esquerda), altura(no->direita)) + 1;
  159.  
  160.     //ver se esta balanceado
  161.     int bal = fatorBalanceamento(no);
  162.  
  163.     // Se nao estiver balanceado, existem 4 possibilidades
  164.  
  165.     // Pesado pra esquerda ~rotação direita
  166.     if (bal > 1 && i < no->esquerda->identificador)
  167.     {
  168.         nivel -= 1;
  169.         rotacao = 1;
  170.         return rotacaoDireita(no);
  171.     }
  172.  
  173.     // Pesado pra direita ~rotação esquerda
  174.     if (bal < -1 && i > no->direita->identificador)
  175.     {
  176.         rotacao = 2;
  177.         nivel -= 1;
  178.         return rotacaoEsquerda(no);
  179.     }
  180.  
  181.     // rotacao dupla pra direita
  182.     if (bal > 1 && i > no->esquerda->identificador)
  183.     {
  184.         rotacao = 3;
  185.         nivel -= 2;
  186.         no->esquerda =  rotacaoEsquerda(no->esquerda);
  187.         return rotacaoDireita(no);
  188.     }
  189.  
  190.     // rotação dupla pra esquerda
  191.     if (bal < -1 && i < no->direita->identificador)
  192.     {
  193.         rotacao = 4;
  194.         nivel -= 2;
  195.         no->direita = rotacaoDireita(no->direita);
  196.         return rotacaoEsquerda(no);
  197.     }
  198.  
  199.     //Retorna arvore atualizada
  200.     return no;
  201. }
  202.  
  203. Arv* remover(Arv* raiz, int identificador)
  204. {
  205.     if (raiz == NULL)
  206.         return raiz;
  207.  
  208.     // Valor menor, pega sub a esquerda
  209.     if ( identificador < raiz->identificador )
  210.         raiz->esquerda = remover(raiz->esquerda, identificador);
  211.  
  212.     //Valor maior, pega sub a direita
  213.     else if( identificador > raiz->identificador )
  214.         raiz->direita = remover(raiz->direita, identificador);
  215.  
  216.     //Achou
  217.     else
  218.     {
  219.         // CASO TENHA 1 OU ZERO FILHOS
  220.         if( (raiz->esquerda == NULL) || (raiz->direita == NULL) )
  221.         {
  222.             Arv* aux = raiz->esquerda ? raiz->esquerda : raiz->direita;
  223.  
  224.             // FOLHA
  225.             if(aux == NULL)
  226.             {
  227.                 aux = raiz;
  228.                 raiz = NULL;
  229.             }
  230.             else // NO COM 1 FILHO
  231.                 *raiz = *aux;
  232.  
  233.             delete(aux);
  234.         }
  235.         else
  236.         {
  237.             // NO COM 2 FILHOS
  238.             Arv* aux = pegaMenor(raiz->direita);
  239.  
  240.             // Copia as informações do sucessor
  241.             raiz->identificador = aux->identificador;
  242.             raiz->valor = aux->valor;
  243.  
  244.             // Deleta o sucessor
  245.             raiz->direita = remover(raiz->direita, aux->identificador);
  246.         }
  247.     }
  248.  
  249.     // Se o no for nulo
  250.     if (raiz == NULL)
  251.         return raiz;
  252.  
  253.     // atualiza altura do no
  254.     raiz->altura = maximo(altura(raiz->esquerda), altura(raiz->direita)) + 1;
  255.  
  256.     // verifica se no esta desbalanceado
  257.     int bal = fatorBalanceamento(raiz);
  258.  
  259.     // Caso desbalanceie, tem 4 possibilidades
  260.  
  261.     // Pesa pra esquerda ~rotacao direita
  262.     if (bal > 1 && fatorBalanceamento(raiz->esquerda) >= 0)
  263.         return rotacaoDireita(raiz);
  264.  
  265.     // Rotação dupla pra direita
  266.     if (bal > 1 && fatorBalanceamento(raiz->esquerda) < 0)
  267.     {
  268.         raiz->esquerda =  rotacaoEsquerda(raiz->esquerda);
  269.         return rotacaoDireita(raiz);
  270.     }
  271.  
  272.     // Pesa pra direita ~rotacao esquerda
  273.     if (bal < -1 && fatorBalanceamento(raiz->direita) <= 0)
  274.         return rotacaoEsquerda(raiz);
  275.  
  276.     // Rotacao dupla esquerda
  277.     if (bal < -1 && fatorBalanceamento(raiz->direita) > 0)
  278.     {
  279.         raiz->direita = rotacaoDireita(raiz->direita);
  280.         return rotacaoEsquerda(raiz);
  281.     }
  282.  
  283.     return raiz;
  284. }
  285.  
  286.  
  287. void preOrdem(Arv* arv, bool cabeca = true)
  288. {
  289.  
  290.     if (arv != NULL)
  291.     {
  292.         if (cabeca)
  293.             printf("%d", arv->identificador);
  294.         else
  295.             printf(" %d", arv->identificador);
  296.         preOrdem(arv->esquerda, false);
  297.         preOrdem(arv->direita, false);
  298.     }
  299.  
  300. }
  301.  
  302. void deletarArvore(Arv* arvore)
  303. {
  304.     if ( arvore != NULL )
  305.     {
  306.         deletarArvore( arvore->esquerda );
  307.         deletarArvore( arvore->direita );
  308.         delete(arvore);
  309.     }
  310. }
  311.  
  312.  
  313.  
  314. int main()
  315. {
  316.  
  317.     freopen("L2Q2.in", "r", stdin);
  318.     freopen("L2Q2.out", "w", stdout);
  319.     Arv* arvore = new Arv();
  320.     arvore = inicializar();
  321.  
  322.     int comando = 0, identificador = 0, valor = 0;
  323.  
  324.     while (scanf("%d", &comando) != EOF)
  325.     {
  326. //        printf("Operacoes: %d\n", operacoes);
  327.  
  328.  
  329.  
  330.  
  331.     //comando 1
  332.        if (comando == 1)
  333.                 { //Se for comando 1 le mais 2
  334.                     scanf("%d %d", &identificador, &valor);
  335.                     arvore = insere(arvore,  identificador, valor, _nivel, _rotacao);
  336.  
  337.                     if (_rotacao == 0)
  338.                     {
  339.                         printf("1 %d N\n", _nivel);
  340.                     }
  341.                     else if (_rotacao == 1)
  342.                     {
  343.                         printf("1 %d RSD\n", _nivel);
  344.                     }
  345.                     else if (_rotacao == 2)
  346.                     {
  347.                         printf("1 %d RSE\n", _nivel);
  348.                     }
  349.                     else if (_rotacao == 3)
  350.                     {
  351.                         printf("1 %d RDD\n", _nivel);
  352.                     }
  353.                     else if (_rotacao == 4)
  354.                     {
  355.                         printf("1 %d RDE\n", _nivel);
  356.                     }
  357.                     _nivel = 0;
  358.                     _rotacao = 0;
  359.                 }
  360.             else if (comando == 2)
  361.             {
  362.                 //comando 2 ~busca~le mais um
  363.                 scanf("%d", &identificador);
  364.                 if (buscaNo(arvore, identificador, _nivel, _valor))   //Se encontrou
  365.                 {
  366.                     printf("2 %d %d", _nivel,_valor);
  367.  
  368.                 }
  369.                 else
  370.                 {
  371.                     //Imprime nada
  372.                 }
  373.                 printf("\n");
  374.                 _nivel = 0;
  375.                 _valor = 0;
  376.             }
  377.             else if (comando == 3)      //imprimir em preOrdem
  378.             {
  379.                    preOrdem(arvore);
  380.                     printf("\n");
  381.             }
  382.             else if (comando == 0){ //reinicia a arvore
  383.                     Arv* aux = arvore;
  384.                     arvore = inicializar();
  385.                     deletarArvore(aux);
  386.  
  387.             }
  388.  
  389.  
  390.             }
  391.  
  392.     return 0;
  393.  
  394. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement