Advertisement
KDOXG

Arvore_RedBlack

Dec 16th, 2018
459
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 7.37 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <bool.h>
  4. #define vermelho 0
  5. #define preto 1
  6.  
  7. typedef long TipoChave;
  8.  
  9. typedef struct Regist {
  10.     TipoChave Chave;
  11. } Registro;
  12.  
  13. struct No {
  14.     Registro Reg;
  15.     short int cor;
  16.     struct No *pEsq, *pDir, *pPai, *pTio;
  17. };
  18.  
  19. /**
  20.  * ----------------------Regras para manipular uma árvore rubro-negra
  21.  *
  22.  * Caso 1- Nó inserido é a raiz
  23.  * Solução: Cor recebe preto
  24.  *
  25.  * Caso 2- Tio do nó inserido é vermelho
  26.  * Solução: Inverte a cor do pai, do tio e do avô
  27.  *
  28.  * Caso 3a- Tio do nó inserido é preto e o nó inserido e seu tio são os filhos da direita de seus respectivos pais
  29.  * Solução: Rotação Simples para Direita no pai do nó inserido
  30.  *
  31.  * Caso 3b- Tio do nó inserido é preto e o nó inserido e seu tio são os filhos da esquerda de seus respectivos pais
  32.  * Solução: Rotação Simples para Esquerda no pai do nó inserido
  33.  *
  34.  * Caso 4a- Tio do nó inserido é preto e o nó inserido é filho da direita e seu tio é filho da esquerda
  35.  * Solução: Rotação Simples para Esquerda no avô do nó inserido e inverte a cor do pai e do avô
  36.  *
  37.  * Caso 4b- Tio do nó inserido é preto e o nó inserido é filho da esquerda e seu tio é filho da direita
  38.  * Solução: Rotação Simples para Direita no avô do nó inserido e inverte a cor do pai e do avô
  39.  *
  40.  */
  41.  
  42. //-----------------------Funções
  43.  
  44. void Pesquisa(Registro *x, struct No *p);
  45.  
  46. void Insere(Registro x, struct No **p);
  47.  
  48. void Corrige(struct No **p);
  49.  
  50. bool EhArvoreRB(struct No *p);
  51.  
  52. void Antecessor(struct No *q, struct No **r);
  53.  
  54. void Retira(Registro x, struct No **p);
  55.  
  56. void RotacaoSimplesEsquerda(struct No **ppRaiz);
  57.  
  58. void RotacaoSimplesDireita(struct No **ppRaiz);
  59.  
  60. int BalancaEsquerda(struct No **ppRaiz);
  61.  
  62. int BalancaDireita(struct No **ppRaiz);
  63.  
  64. int Inserir(struct No **ppRaiz, Registro x);
  65.  
  66. //-----------------------Main
  67.  
  68. int main()
  69. {
  70.     struct No *arvore=NULL, *resgate=malloc(sizeof(struct No));
  71.     int confere;
  72.     Registro dado;
  73.  
  74.     Leia: printf("Digite: ");
  75.     scanf("%li", &dado.Chave);
  76.     Insere(dado,&arvore,NULL);
  77.     printf("Feito!\n");
  78.     printf("Inserir outro número? ");
  79.     scanf("%d", &confere);
  80.     if (confere == 1)
  81.         goto Leia;
  82.  
  83.     Pesquise: printf("Digite: ");
  84.     scanf("%li", &resgate->Reg.Chave);
  85.     Pesquisa(&resgate->Reg,arvore);
  86.     printf("Feito!\n");
  87.     printf("Pesquisar por outro? ");
  88.     scanf("%d", &confere);
  89.     if (confere == 1)
  90.         goto Pesquise;
  91.  
  92.     Remova: printf("Digite: ");
  93.     scanf("%li", &resgate->Reg.Chave);
  94.     Retira(resgate->Reg,&arvore);
  95.     printf("Feito!\n");
  96.     printf("Remover outro? ");
  97.     scanf("%d", &confere);
  98.     if (confere == 1)
  99.         goto Remova;
  100.  
  101.     return 0;
  102. }
  103.  
  104. //-----------------------Métodos
  105.  
  106. void Pesquisa(Registro *x, struct No *p)
  107. {
  108.     if (p == NULL)
  109.     {
  110.         printf("Erro : Registro nao esta presente na arvore\n");
  111.         return;
  112.     }
  113.     if (x->Chave < p->Reg.Chave)
  114.     {
  115.         Pesquisa(x, p->pEsq);
  116.         return;
  117.     }
  118.     if (x->Chave > p->Reg.Chave)
  119.         Pesquisa(x, p->pDir);
  120.     else
  121.         *x = p->Reg;
  122. }
  123.  
  124. void Insere(Registro x, struct No **p, struct No *Pai)
  125. {
  126.     if ((*p) == NULL)
  127.     {
  128.         (*p) = (struct No*)malloc(sizeof(struct No));
  129.         (*p)->Reg = x;
  130.         (*p)->pEsq = NULL;
  131.         (*p)->pDir = NULL;
  132.         (*p)->pPai = Pai;
  133.         (*p)->pTio=NULL;
  134.         if ((*p)->pPai != NULL && (*p)->pPai->pPai != NULL)
  135.         {
  136.             (*p)->cor=vermelho;
  137.             if ((*p)->pPai->pPai->pDir == (*p)->pPai)  
  138.             {//Se o nodo que esta sendo inserido e o filho do pai da direita, o tio sera o da esquerda
  139.                 (*p)->pTio=(*p)->pPai->pPai->pEsq;
  140.             }
  141.             else
  142.             {
  143.                 (*p)->pTio=(*p)->pPai->pPai->pDir;
  144.             }
  145.         }
  146.         else
  147.         {//Corrigindo Caso 1
  148.             (*p)->cor=preto;
  149.         }
  150.         return;
  151.     }
  152.     if (x.Chave < (*p)->Reg.Chave)
  153.     {
  154.         Insere(x, &(*p)->pEsq, *p);
  155.         return;
  156.     }
  157.     if (x.Chave > (*p)->Reg.Chave)
  158.         Insere(x, &(*p)->pDir, *p);
  159.     else
  160.         printf("Erro : Registro ja existe na arvore\n");
  161. }
  162.  
  163. void Corrige(struct No **p)
  164. {
  165.    
  166. }
  167.  
  168. bool EhArvoreRB(struct No *p)
  169. {
  170.     if (p == NULL)
  171.         return false;   //Nao precisa corrigir nada
  172.     if (p->pPai != NULL && p.cor == preto && p->pPai.cor == vermelho)
  173.         return true;    //Precisa corrigir
  174.     return EhArvoreRB(p->pEsq) || EhArvoreRB(p->pDir);
  175. }
  176.  
  177. void Retira(Registro x, struct No **p)
  178. {
  179.     if ((*p) == NULL)
  180.     {
  181.         printf("Erro : Registro nao esta na arvore\n");
  182.         return;
  183.     }
  184.     if (x.Chave < (*p)->Reg.Chave)
  185.     {
  186.         Retira(x, &(*p)->pEsq);
  187.         return;
  188.     }
  189.     if (x.Chave > (*p)->Reg.Chave)
  190.     {
  191.         Retira(x, &(*p)->pDir);
  192.         return;
  193.     }
  194.     if ((*p)->pDir == NULL)
  195.     {
  196.         struct No *Aux;
  197.         Aux = (*p);
  198.         (*p) = (*p)->pEsq;
  199.         free(Aux);
  200.         return;
  201.     }
  202.     if ((*p)->pEsq != NULL)
  203.     {
  204.         Antecessor((*p), &(*p)->pEsq);
  205.         return;
  206.     }
  207.     // ((*p)->pEsq == NULL)
  208.     struct No *Aux;
  209.     Aux = (*p);
  210.     (*p) = (*p)->pDir;
  211.     free(Aux);
  212. }
  213.  
  214. void Antecessor(struct No *q, struct No **r)
  215. {
  216.     struct No *aux;
  217.     if ((*r)->pDir != NULL)
  218.     {
  219.         Antecessor(q, &(*r)->pDir);
  220.         return;
  221.     }
  222.     q->Reg = (*r)->Reg;
  223.     aux = (*r);
  224.     (*r) = (*r)->pEsq;
  225.     free(aux);
  226. }
  227.  
  228. void RotacaoSimplesEsquerda(struct No **ppRaiz)
  229. {
  230.     struct No *pAux;
  231.     pAux = (*ppRaiz)->pDir;
  232.     (*ppRaiz)->pDir = pAux->pEsq;
  233.     pAux->pEsq = (*ppRaiz);
  234.     (*ppRaiz) = pAux;
  235. }
  236.  
  237. void RotacaoSimplesDireita(struct No **ppRaiz)
  238. {
  239.     struct No *pAux;
  240.     pAux = (*ppRaiz)->pEsq;
  241.     (*ppRaiz)->pEsq = pAux->pDir;
  242.     pAux->pDir = (*ppRaiz);
  243.     (*ppRaiz) = pAux;
  244. }
  245.  
  246. int BalancaEsquerda(struct No **ppRaiz)
  247. {
  248.     int fbe = FB ((*ppRaiz)->pEsq);
  249.     if (fbe > 0)
  250.     {
  251.         RotacaoSimplesDireita(ppRaiz);
  252.         return 1;
  253.     }
  254.     else if (fbe < 0)
  255.     { //Rotação Dupla Direita
  256.         RotacaoSimplesEsquerda(&((*ppRaiz)->pEsq));
  257.         RotacaoSimplesDireita(ppRaiz); // &(*ppRaiz)
  258.         return 1;
  259.     }
  260.     return 0;
  261. }
  262.  
  263. int BalancaDireita(struct No **ppRaiz)
  264. {
  265.     int fbd = FB((*ppRaiz)->pDir);
  266.     if (fbd < 0)
  267.     {
  268.         RotacaoSimplesEsquerda(ppRaiz);
  269.         return 1;
  270.     }
  271.     else if (fbd > 0 )
  272.     { // Rotação Dupla Esquerda
  273.         RotacaoSimplesDireita(&((*ppRaiz)->pDir));
  274.         RotacaoSimplesEsquerda(ppRaiz); // &(*ppRaiz)
  275.         return 1;
  276.     }
  277.     return 0;
  278. }
  279.  
  280. int Inserir(struct No **ppRaiz, Registro x)
  281. {
  282.     if (*ppRaiz == NULL)
  283.     {
  284.         *ppRaiz = (struct No*)malloc(sizeof(struct No));
  285.         (*ppRaiz)->Reg = x;
  286.         (*ppRaiz)->pEsq = NULL;
  287.         (*ppRaiz)->pDir = NULL;
  288.         return 1;
  289.     }
  290.     if ((*ppRaiz)->Reg.Chave > x.Chave)
  291.     {
  292.         if (Inserir(&(*ppRaiz)->pEsq,x))
  293.         {
  294.             if (Balanceamento(ppRaiz))
  295.                 return 0;
  296.             else
  297.                 return 1;
  298.         }
  299.     }
  300.     if ((*ppRaiz)->Reg.Chave < x.Chave)
  301.     {
  302.         if (Inserir(&(*ppRaiz)->pDir,x))
  303.         {
  304.             if (Balanceamento(ppRaiz))
  305.                 return 0;
  306.             else
  307.                 return 1;
  308.         }
  309.         else
  310.             return 0;
  311.     }
  312.     else
  313.         return 0; // valor ja presente
  314. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement