// ------------------------------------------------------------------------------
// Funcao rotacao dupla a direita
// ------------------------------------------------------------------------------
nodo * rd_dir(nodo * x)
{
	x->esq = rot_esq(x->esq);	
	x = rot_dir(x);
	
	return x;
}
// ------------------------------------------------------------------------------
// Funcao balanceamento
// ------------------------------------------------------------------------------
nodo * balanceamento(nodo * raiz)
{
	int fb = fat_bal(raiz);
	

	
	if ((fb <= -2) || (fb >=2)){
		printf("-- Acao do Balanceamento: \n");
		if (fb > 0){
			fb = fat_bal(raiz->dir);
			if (fb >= 0){
				
				printf(" rot simples a esq \n");
				raiz = rot_esq(raiz);
			} else {
				printf(" rot dupla a esq.\n");
				raiz = rd_esq(raiz);				
			}	 
		} else {
			fb = fat_bal(raiz->esq);
			if (fb <= 0){
				printf(" rot simples a dir\n");
				raiz = rot_dir(raiz);	
			} else {
				printf(" rot dupla a dir\n");
				raiz = rd_dir(raiz);
				
			}
		}
	}	
	return raiz;
}	
// ------------------------------------------------------------------------------
// Funcao rotacao dupla a esquerda
// ------------------------------------------------------------------------------
nodo * rd_esq(nodo * x)
{

	x->dir = rot_dir(x->dir);
	x = rot_esq(x);
	
	return x;
}
Example #4
0
//------------------------------------------------------------------------------
// ROT_ESQ_DIR
//   Realiza a rotação esquerda e direita de um nó
//------------------------------------------------------------------------------
Registro *rot_esq_dir(Registro *no) {
	Registro *pai;
	Registro *no_esq;
	Registro *novo_no;

	pai		= no->pai;
	no_esq	= no->esq;
	no->esq = rot_esq(no_esq);
	no_esq	= no->esq;
	novo_no = rot_dir(no);
	novo_no->pai = pai;

return novo_no;
}
Example #5
0
//------------------------------------------------------------------------------
// ROT_DIR_ESQ
//   Realiza a rotação direita e esquerda de um nó
//------------------------------------------------------------------------------
Registro *rot_dir_esq(Registro *no) {
	Registro *pai;
	Registro *no_dir;
	Registro *novo_no;

	pai 	= no->pai;
	no_dir 	= no->dir;
	no->dir = rot_dir(no_dir);
	no_dir 	= no->dir;
	novo_no = rot_esq(no);
	novo_no->pai = pai;

	return novo_no;
}
Example #6
0
//------------------------------------------------------------------------------
// REMOVE_AVL
//   Remove um registro e balanceia a árvore caso necessário
//------------------------------------------------------------------------------
Registro *remove_avl(Registro *reg,  const char *nome) {
	if (reg == NULL) return NULL;
	if (stricmp(reg->nome, nome) == 0) {
		if ((reg->esq) == NULL && (reg->dir == NULL)) {
			free(reg);
			return NULL;
		}
		
		if (reg->dir == NULL) {
			Registro *aux = reg->esq;
			free(reg);
			aux->fb = fator_bal(aux);
			return aux;
		}
		
		if (reg->esq == NULL) {
			Registro *aux = reg->dir;
			free(reg);
			aux->fb = fator_bal(aux);
			return aux;
		}
		
		Registro *aux  = reg->esq;
		Registro *aux2 = reg->esq;
		
		for ( ; aux2->dir != NULL; aux2 = aux2->dir);
		aux2->dir=reg->dir;
		free(reg);
		aux->fb=fator_bal(aux);
		
		if (aux->fb >= 2) {
			if (aux->dir->dir != NULL) aux=rot_esq(aux);
			else rot_dir_esq(aux);
			aux->fb = fator_bal(aux);
		}

		if (aux->fb <= -2) {
			if (aux->esq->esq != NULL) aux = rot_dir(reg);
			else rot_esq_dir(aux);
			aux->fb = fator_bal(aux);
		}
		
		return aux;
	}
	
	if (stricmp(reg->nome, nome) > 0) reg->esq = remove_avl(reg->esq, nome);
	if (stricmp(reg->nome, nome) < 0) reg->dir = remove_avl(reg->dir, nome);
	return reg;
}
Example #7
0
//------------------------------------------------------------------------------
// REG_INSERE_AVL
//   Insere um novo registro, preenchendo os dados e o colocando em sua
//   posição correta dentro da árvore binária e checa o balanceamento da
//   mesma. Caso esteje balanceada, reorganiza os nós.
//------------------------------------------------------------------------------
Registro *reg_insere_avl(Registro *reg, const char *nome, const char *curso, const char *turno, const char *cidade) {
	if (reg == NULL) {
		reg = reg_cria();
		strcpy(reg->nome  , nome);
		strcpy(reg->curso , curso);
		strcpy(reg->turno , turno);
		strcpy(reg->cidade, cidade);
		reg->fb = 0;
	}
	
	if (strcmp(reg->nome, nome) > 0) {
		Registro *aux = reg_insere_avl(reg->esq, nome, curso, turno, cidade);
		reg->esq = aux;
		reg->esq->pai = reg;
	}
	
	if (strcmp(reg->nome, nome) < 0) {
		Registro *aux = reg_insere_avl(reg->dir, nome, curso, turno, cidade);
		reg->dir = aux;
		reg->dir->pai = reg;
	}
	
	reg->fb = fator_bal(reg);
	
	if (reg->fb >= 2) {
		if (reg->dir->dir != NULL) reg=rot_esq(reg);
		else reg = rot_dir_esq(reg);
		reg->fb = fator_bal(reg);
	}
	
	if (reg->fb <= -2) {
		if (reg->esq->esq != NULL) reg = rot_dir(reg);
		else reg = rot_esq_dir(reg);
		reg->fb = fator_bal(reg);
	}
	return reg;
}
Example #8
0
// atualização do FB e balanceamento para a raiz esquerda
struct NO *balanceamento_esq(struct NO *no, bool h) {
    struct NO *fdir;
    int fbdir;

    switch (no->fb) {
        case 1:
            no->fb = 0;
            break;
        case 0:
            no->fb = -1;
            h = false;
            break;
        case -1:
                fdir = no->fdir;
                fbdir = fdir->fb;
                if (fbdir <= 0) {
                    fdir = rot_esq(no);

                    if (fbdir == 0) {
                        no->fb = -1;
                        fdir->fb = 1;
                        h = false;
                    }
                    else {
                        no->fb = 0;
                        fdir->fb = 0;
                    }
                    no = fdir;
                }
                else {
                    no = rot_dir_esq(no);
                    no->fb = 0;
                }
    }
    return(no);
}
Example #9
0
struct NO *inserir_arvore_avl_aux(struct NO *raiz, struct INFO info, int *atual_fb) {
  if (raiz == NULL) {
    raiz = (struct NO *) malloc(sizeof(struct NO));
    raiz->fesq = raiz->fdir = raiz->pai = NULL;
    raiz->info = info;
    raiz->fb = 0;
    *atual_fb = 1;
  } else {
    if (raiz->info.chave > info.chave) { //desce pela esquerda
      raiz->fesq = inserir_arvore_avl_aux(raiz->fesq, info, atual_fb);
      raiz->fesq->pai = raiz;

      if (*atual_fb) {
          switch(raiz->fb) {
              case -1: {
                raiz->fb = 0;
                *atual_fb = 0;
                break;
              }
              case 0: {
                raiz->fb = 1;
                break;
              }
              case 1: {
                  if (raiz->fesq->fb == 1) {
                      raiz = rot_dir(raiz);
                      raiz->fb = 0;
                      raiz->fdir->fb = 0;
                      *atual_fb = 0;
                  }
                  else {
                      raiz = rot_esq_dir(raiz);

                      if (raiz->fb == 1) {
                          raiz->fesq->fb = 0;
                          raiz->fb = -1;
                      }
                      else {
                          raiz->fesq->fb = 1;
                          raiz->fdir->fb = 0;
                      }
                      raiz->fb = 0;
                      *atual_fb = 0;
                  }
                break;
              }
          }
      }

    } else { //desce pela direita
      raiz->fdir = inserir_arvore_avl_aux(raiz->fdir, info, atual_fb);
      raiz->fdir->pai = raiz;

      if (*atual_fb) {
          switch(raiz->fb) {
              case 1: {
                raiz->fb = 0;
                *atual_fb = 0;
                break;
              }
              case 0: {
                raiz->fb = -1;
                break;
              }
              case -1: {
                  if (raiz->fdir->fb == -1) {
                      raiz = rot_esq(raiz);
                      raiz->fb = 0;
                      raiz->fesq->fb = 0;
                      *atual_fb = 0;
                  }
                  else {
                      raiz = rot_dir_esq(raiz);

                      if (raiz->fb == -1) {
                          raiz->fdir->fb = 0;
                          raiz->fb = 1;
                      }
                      else {
                          raiz->fdir->fb = -1;
                          raiz->fesq->fb = 0;
                      }
                      raiz->fb = 0;
                      *atual_fb = 0;
                  }
                break;
              }
            }
        }
    }
  }
  return(raiz);
}
Example #10
0
struct NO *rot_dir_esq(struct NO *no) {
  rot_dir(no->fdir);
  return(rot_esq(no));
}
Example #11
0
struct NO *rot_esq_dir(struct NO *no) {
  rot_esq(no->fesq);
  return(rot_dir(no));
}