Vous êtes sur la page 1sur 5

Operaes com rvores Binrias

1) Insero
2) Retirada

Insero de nodos na AB
A operao de insero de um nodo na rvore pode ser
decomposta nas seguintes operaes
a) Busca pelo nodo que ser o pai do nodo a ser inserido;
b) Criao do novo nodo a ser inserido;
c) Insero do nodo na rvore.
Geralmente a insero dos nodos menores que o nodo raiz so
inseridos na subrvore da esquerda e os maiores na
subrvore da direita.
Obs.: ver exemplo ABO.PAS no TELEDUC.

Remoo de nodos em uma rvore


A remoo exige alguns cuidados especiais.
a) Remoo de uma folha da rvore
b) Remoo de um nodo que tem um filho
c) Remoo de um nodo que tem 2 filhos
Seja a rvore:

a) Algoritmo de remoo de uma folha da rvore


Esta uma situao de simples remoo de um nodo da
rvore. Percorre-se a rvore procurando o nodo a ser
retirado. Como se trata de um elemento folha ele ser
encontrado e atravs da referncia de um nodo de nvel
superior. Basta ento liberar o nodo e tornar nulo o
ponteiro que apontava para ele.
Supondo v = 4 tem-se:
void Remove_Folha (ptr_arvore *a, int v)
ptr_arvore p, q;
int achou;
{
achou = 0;
q, p = a;
enquanto (q != NULL) e (achou == 0) faca
{
se (v == q->dado) entao
{
se (q->dado < p->dado)
entao p->esq = NULL;
senao p->dir = NULL;
free (q);
achou = 1;
}
senao
se (v < q->dado)
entao { //Caminha pela esquerda
p = q;
q = q->esq;
}
senao { //Caminha pela direita
p = q;
q = q->dir;
}
}
se (achou == 0) entao escrever ("Nodo nao encontrado");
}

b)Algoritmo de remoo de um nodo que tem um filho


Neste caso teremos uma situao parecida com a anterior,
exceto quanto ao fato de o nodo a ser removido possuir um
nodo filho o qual no pode ser perdido. Este nodo deve ser
ligado ao nodo pai do nodo removido.
Supondo v = 8 tem-se:
void Remove_com_1filho (ptr_arvore a, int v)
ptr_arvore q, p;
int achou;
{
achou = 0;
q, p = a;
enquanto (q != NULL) e (achou == 0) faca
{
se (v == q->dado)
entao
{
se (q->dir == NULL)
entao {
se (q->esq == NULL)
entao p->dir = NULL;
senao p->dir = q->esq;
}
senao p->dir = q->dir;
free(q);
achou = 1;
}
senao
se (v < q->dado)
entao { //Caminha pela esquerda
p = q;
q = esq(q);
}
senao { //Caminha pela direita
p = q;
q = dir(q);
}
}
se (achou == 0) entao escrever ("Nodo nao encontrado");
}

c) Algoritmo de remoo de um nodo que tem 2 filhos


Tambm precisaremos arrumar a rvore, para evitar que os
filhos do nodo removido sejam perdidos ou que fique
desordenada. Procura-se o nodo da subrvore que tem como
raiz o filho esquerdo do nodo que vai ser removido e em
seguida procura-se o nodo cujo campo Dado possua o maior
valor. Este valor estar em um galho que no possua filho
direito ou em uma folha. Pendura-se neste nodo de maior
valor no campo Dado, usando o campo Esq do nodo, a
subrvore que tem como raiz o filho direito do nodo que
est sendo removido.
Supondo v = 6 tem-se:
void Remove_com_2filho (ptr_arvore *a, int v)
ptr_arvore q, p;
int achou;
{
achou = 0;
q, p = a;
enquanto (q != NULL) e (achou == 0) faca
{
se (v == q->dado) entao
{
p = q->esq;
enquanto p->dir <> NULL faca
p = p->dir;
p->dir = q->dir;
a = q->esq;
free(q);
achou := 1;
}
senao
se (v < q->dado)
entao { //Caminha pela esquerda
p = q;
q = q->esq;
}
senao { //Caminha pela direita
p = q;
q = q->dir;
}
}
se (achou == 0) entao escrever ("Nodo nao encontrado");
}

Essas operaes podem ser reunidas em um nico procedimento


Remove_Nodo_Arvore o qual por sua vez faz uso de um outro
procedimento Arruma_Arvore conforme mostrado a seguir:
void Arruma_Arvore(ptr_arvore *sub);
{
se sub->dir != NULL
entao Arruma_Arvore(sub->dir)
senao {
q->dado = sub->dado;
q = sub;
}
} {fim do procedimento Arruma}
void Remove_Nodo_Arvore (ptr_arvore *a, int v)
q:ptr_arvore;
{
se (a == NULL)
entao escreva ("Nodo nao encontrado")
senao se (v < a->dado)
entao Remove_Nodo_Arvore(a->esq, v)
senao se v > a->dado
entao Remove_Nodo_Arvore(a->dir, v)
senao {
q = a;
se a->dir = NULL
entao a = a->esq
senao se a->esq = NULL
entao a = a->dir
senao Arruma_Arvore(a->esq)
desaloque(q);
}
}
{fim do Remove}

Vous aimerez peut-être aussi