No *rotacaoLL(No *raiz){ No *no=raiz->pEsquerda; no->pai=raiz->pai; raiz->pEsquerda=no->pDireita; no->pDireita=raiz; raiz->balanceamento=maior(alt_NO(raiz->pEsquerda),alt_NO(raiz->pDireita))+1; no->balanceamento=maior(alt_NO(no->pEsquerda),raiz->balanceamento)+1; raiz->pai=no; return no; }
void Rot_Simp_esq (ArvAVL *raiz){ // rotacao simples a esquerda: quer dizer que o no inserido ficou a direida da subarvore da direita, ocasionando um fatbal +2. O ponteiro de ponteiro recebido como raiz é deste nó com fatbal +2. ArvAVL no; no = (*raiz)->dir; (*raiz)->dir = no->esq; no->esq = (*raiz); (*raiz)->alt = maior(alt_NO((*raiz)->esq), alt_NO((*raiz)->dir))+1; no->alt = maior(alt_NO(no->dir), alt_NO(no->esq))+1; *raiz = no; }
int insere_ArvAVL (ArvAVL *raiz, int chave){ int res; if(*raiz == NULL){ // arvore vazia ou no folha ArvAVL novo; novo = (ArvAVL)malloc(sizeof(struct NO)); if(novo == NULL) return 0; novo->chave = chave; novo->alt = 0; novo->esq = NULL; novo->dir = NULL; *raiz = novo; return 1; } ArvAVL atual = *raiz; if(chave < atual->chave){ // inserção na sub arvore da esquerda if((res = insere_ArvAVL(&(atual->esq), chave)) == 1){ atual->alt = maior(alt_NO(atual->esq),alt_NO(atual->dir)) + 1; if(FatBal(atual) <= -2){ if(chave < (*raiz)->esq->chave ){ Rot_Simp_dir(raiz); }else{ Rot_dupla_direita_met2(raiz); } } } } else{ if(chave > atual->chave){ if((res = insere_ArvAVL(&(atual->dir), chave)) == 1){ atual->alt = maior(alt_NO(atual->esq),alt_NO(atual->dir)) + 1; if(FatBal(atual) >= 2){ if((*raiz)->dir->chave < chave){ Rot_Simp_esq(raiz); }else{ Rot_dupla_esquerda_met2(raiz); } } } } else{ printf("Valor duplicado!!\n"); return 0; } } return res; }
void Rot_Simp_dir (ArvAVL *raiz){ // rotacao simples a direita: quer dizer que o no inserido ficou a esquerda da subarvore da esquerda, ocasionando um fatbal -2. o ponteiro de ponteiro recebido como raiz é deste nó com fatbal -2. ArvAVL no; no = (*raiz)->esq; (*raiz)->esq = no->dir; no->dir = (*raiz); (*raiz)->alt = maior (alt_NO((*raiz)->esq),alt_NO((*raiz)->dir)) +1; no->alt = maior(alt_NO(no->esq), alt_NO(no->dir))+1; // alteracao das alturas, sempre sera isso. pego a maior altura entre os dois filhos e acrescento um. faco recursivamente ate a folha que eh 0. *raiz = no; // se faz necessaria a troca pois estamos usando uma referencia e, portanto, temos que definir a nova raiz. }
No* inserir(ARVORE* arv, char chave[], No *no, No *anterior, int assa){ No *esq,*dir,*aux; //Ponteiros de Nós que auxiliam substituições futuras if(no==NULL){//no que olhamos é nulo; no= (No *)malloc(sizeof(No)); strcpy(no->chave,chave); no->pEsquerda = NULL; no->pDireita = NULL; no->pai = anterior; no->mortos=0; no->balanceamento=0; if(assa==0) no->situacao=0; else{ no->situacao=1; no->mortos=1; } return (no); } if(strcmp(chave,no->chave)<0){// indica que o valor a ser inserido é menor que o atual no->pEsquerda = inserir(arv, chave, no->pEsquerda, no, assa); if(fatorBalanceamento_NO(no)>=2){ if(strcmp(chave,no->pEsquerda->chave)<0){ no=rotacaoLL(no); } else if(strcmp(chave,no->pEsquerda->chave)>0){ no=rotacaoLR(no); } } } else if(strcmp(chave,no->chave)>0){//indica que o valor a ser inserido é maior que o atual no->pDireita = inserir(arv, chave, no->pDireita, no, assa); if(fatorBalanceamento_NO(no)>=2){ if(strcmp(chave,no->pDireita->chave)>0){ no=rotacaoRR(no); } else if(strcmp(chave,no->pDireita->chave)<0){ no=rotacaoRL(no); } } } else{//indica que temos a chave com mesmo valor do no if(assa==1){ no->mortos+=1; } else no->situacao=0; } no->balanceamento=maior(alt_NO(no->pEsquerda),alt_NO(no->pDireita))+1; return(no); }
void Rot_dupla_dir (ArvAVL *raiz){ // metodo explicado em aula, onde a rotacao dupla a direita sera tratada com trocas de ponteiros e o ajuste braçal da arvore, neste caso a raiz da sub-arvore da direita do filho da esquerda se tornara a raiz da subarvore principal tratada. ArvAVL no1; ArvAVL no2; no1 = (* raiz)-> esq; no2 = (* raiz)-> esq -> dir; // dupla rot para direita, no2 está na sub arvore da direita do filho da esquerda e se tornará a nova raiz desta subarvore no1->dir = no2->esq; (*raiz)->esq = no2->dir; no2->esq = no1; no2->dir = (* raiz); (*raiz)->alt = maior(alt_NO((*raiz)->esq), alt_NO((*raiz)->dir))+1; no1->alt = maior(alt_NO(no1->dir), alt_NO(no1->esq))+1; no2->alt = maior(alt_NO(no2->dir), alt_NO(no2->esq))+1; (*raiz) = no2; }
int FatBal (ArvAVL no){ return (alt_NO(no->dir) - alt_NO(no->esq)); //vou retornar o valor da altura da sub arvore da direita menos a da esquerda }
int fatorBalanceamento_NO(No *no){ return labs(alt_NO(no->pEsquerda)-alt_NO(no->pDireita)); }