예제 #1
0
파일: registro.c 프로젝트: bailon/learnings
//------------------------------------------------------------------------------
// 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;
}
예제 #2
0
파일: registro.c 프로젝트: bailon/learnings
//------------------------------------------------------------------------------
// 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;
}
예제 #3
0
// atualização do FB e balanceamento para a raiz direita
struct NO *balanceamento_dir(struct NO *no, bool h) {
    struct NO *fesq;
    int fbesq;

    switch (no->fb) {
        case -1:
            no->fb = 0;
            break;
        case 0:
            no->fb = 1;
            h = false;
            break;
        case 1:
            fesq = no->fesq;
            fbesq = fesq->fb;
            if (fbesq >= 0) {
                fesq = rot_dir(no);

                if (fbesq == 0) {
                    no->fb = 1;
                    fesq->fb = -1;
                    h = false;
                }
                else {
                    no->fb = 0;
                    fesq->fb = 0;
                }
                no = fesq;
            }
            else {
                no = rot_esq_dir(no);
                no->fb = 0;
            }
    }
    return(no);
}
예제 #4
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);
}