void balancearAVL(struct No *r, struct Arvore *t) { int fatorR = fatorBalanceamento(r); int fatorE = fatorBalanceamento(r->esquerda); int fatorD = fatorBalanceamento(r->direita); if(fatorR == -2) { if(fatorD == 1) { rotacaoDireita(r->direita, t); } rotacaoEsquerda(r, t); } else if(fatorR == 2) { if(fatorE == -1) { rotacaoEsquerda(r->esquerda, t); } rotacaoDireita(r, t); } if(r->pai != NULL) { balancearAVL(r->pai, t); } }
No* Arvore::balancear(No* pNo) { if(pNo) { if(pNo->getPeso() == 2) { if(pNo->getDireita()->getPeso() == -1) { //return rotacaoDuplaEsquerda(pNo); pNo->setDireita(rotacaoDireita(pNo->getDireita())); return rotacaoEsquerda(pNo); } else { return rotacaoEsquerda(pNo); } } else if(pNo->getPeso() == -2) { if(pNo->getEsquerda()->getPeso() == 1) { //return rotacaoDuplaDireita(pNo); pNo->setEsquerda(rotacaoEsquerda(pNo->getEsquerda())); return rotacaoDireita(pNo); } else { return rotacaoDireita(pNo); } } } return pNo; }
NO* balanceamentoCaso5(NO* raiz, NO* n) { /*Sempre depois do caso4 ele vem pra ca, onde ajusta as cores.*/ n->pai->cor = NEG;/*Ja que o no é vermelho, caso esteja vermelho o pai, já troca para preto.*/ noAvo(n)->cor = RUB;/*Caso esse avo ainda nao seja a raiz, deixando vermelho para assim ficar V P V*/ if(n == n->pai->esquerda && n->pai == noAvo(n)->esquerda) { /*Verificando de qual lado esta localizado para fazer a ultima rotacao. No desenho que fiz logo a cima, é o segundo passo.*/ raiz = rotacaoDireita(raiz, noAvo(n)); } else if(n == n->pai->direita && n->pai == noAvo(n)->direita) { raiz = rotacaoEsquerda(raiz, noAvo(n)); } return raiz; }
tipoNo* balanceamentoCaso4(tipoNo* raiz, tipoNo* n){ if(n == n->noPai->noDireito && n->noPai == noAvo(n)->noEsquerdo){ raiz = rotacaoEsquerda(raiz, n->noPai); n = n->noEsquerdo; } else if(n == n->noPai->noEsquerdo && n->noPai == noAvo(n)->noDireito){ raiz = rotacaoDireita(raiz, n->noPai); n = n->noDireito; } return balanceamentoCaso5(raiz, n); }
tipoNo* balanceamentoCaso5(tipoNo* raiz, tipoNo* n){ n->noPai->cor = NEG; noAvo(n)->cor = RUB; if(n == n->noPai->noEsquerdo && n->noPai == noAvo(n)->noEsquerdo){ raiz = rotacaoDireita(raiz, noAvo(n)); } else if(n == n->noPai->noDireito && n->noPai == noAvo(n)->noDireito){ raiz = rotacaoEsquerda(raiz, noAvo(n)); } return raiz; }
NO* balanceamentoCaso4(NO* raiz, NO* n) { if(n == n->pai->direita && n->pai == noAvo(n)->esquerda) { /*se ele tiver no lado direito e o pai lado esquerdo*/ /* (4) (4) (3) / / / \ (2) => (3)no => (2) (4) \ / (3)no (2) */ raiz = rotacaoEsquerda(raiz, n->pai); n = n->esquerda; } /* (4) (4) (5) \ \ / \ (6) => (5) => (4) (6) / \ (5)no (6) */ else if(n == n->pai->esquerda && n->pai == noAvo(n)->direita) { raiz = rotacaoDireita(raiz, n->pai); n = n->direita; } return balanceamentoCaso5(raiz, n); }
// Corrige e balanceia a arvore Arvore* balanceia(Arvore * raiz, Arvore * z) { Arvore* pai = getNextNode(z->pai); Arvore* avo = getNextNode(pai->pai); while (z->pos != raiz->pos && pai->cor == RED) { if (pai->pos == avo->esquerda) { Arvore * tio = getNextNode(avo->direita); if (tio->cor == RED) { //CASO 1 pai->cor = BLACK; tio->cor = BLACK; avo->cor = RED; z = avo; atualizaNo(pai); atualizaNo(tio); atualizaNo(avo); } else { if (z->pos == pai->direita) { //CASO 2 z = pai; raiz = rotacaoEsquerda(raiz, z); } //CASO 3 pai->cor = BLACK; avo->cor = RED; atualizaNo(pai); atualizaNo(avo); raiz = rotacaoDireita(raiz, avo); } } else { //PARA DIREITA if (pai->pos == avo->direita) { Arvore * tio = getNextNode(avo->esquerda); if (tio->cor == RED) { pai->cor = BLACK; tio->cor = BLACK; avo->cor = RED; z = avo; atualizaNo(pai); atualizaNo(tio); atualizaNo(avo); } else { if (z->pos == pai->esquerda) { z = pai; raiz = rotacaoDireita(raiz, z); // OLHAR } pai->cor = BLACK; avo->cor = RED; atualizaNo(pai); atualizaNo(avo); raiz = rotacaoEsquerda(raiz,avo); } } } //reloadRaiz raiz = getNextNode(raiz->pos); pai = getNextNode(z->pai); avo = getNextNode(pai->pai); } raiz->cor = BLACK; atualizaNo(raiz); return raiz; }