Algorítmos e estrutura de
dados III
Carlos Oberdan Rolim
Ciência da Computação
Árvores de busca binária
Problemas...
Se um vetor tiver ordenado é possível obter um algoritmo de
pesquisa muito eficiente denominado pesquisa binária
Não é eficiente na inserção e remoção devido a necessidade de
reorganização para manter a ordenação
As listas ligadas resolvem esse problema com o uso de
ponteiros
Problema é que algoritmos de pesquisa são sequenciais
Árvore binária resolve esse tipo de problema de forma
eficiente
Árvore de pesquisa binária
Uma árvore de pesquisa
binária é uma árvore
binária armazenando
chaves (ou itens) em
seus nós internos e
satisfazendo a seguinte
propriedade:
Seja u, v e w três nós tais que
u é nó esquerdo de v e w é o
nó direito. Temos key(u) 
key(v)  key(w)
Nós externos não
armazenam itens (null)
Itens da esqueda menor que
a raiz
Itens da direita maior ou igual
a raiz
Cada subarvore é uma arvore
Uma travessia em ordem
visita as chaves em ordem
crescente
6
2
1
9
4
8
Árvore de pesquisa binária
Árvore binária onde os elementos são organizados
de forma que:
x
y<x
z>x
Árvore de pesquisa
binária
2
9
1
3
3
7
1
5
8
2
5
6
7
Árvore de pesquisa binária
Exemplo: 50, 20, 39, 8, 79, 26, 58, 15,
88, 4, 85, 96, 71, 42, 53.
50
20
79
8
4
39
15
26
58
42
53
88
71
85
96
Árvore de pesquisa binária
Estrutura de dados dinâmica, com recuperação
em tempo logarítmico.
1
2
3
4
Representação de um Nó
struct arvore{
char info;
struct arvore *esq, *dir;
};
typedef struct arvore *arvorePTR;
Uma árvore binária de busca vazia é representada por uma
variável ponteiro com conteúdo nulo
Árvore com ponteiro para raiz
Inserindo um elemento em uma árvore de busca
binária
5
14
(a) Árvore depois da inserção de 5 e 14
Inserindo um elemento em uma árvore de busca
binária
5
14
8
(b) Árvore depois da inserção de 8
Inserindo um elemento em uma árvore de busca
binária
5
2
14
8
(c) Árvore depois da inserção de 2
Inserindo um elemento em uma árvore de busca
binária
5
2
14
8
(d) Árvore depois da inserção de 20
20
Inserindo um elemento em uma árvore de busca
binária
Exemplo: 50, 20, 39, 8, 79, 26, 58, 15,
88, 4, 85, 96, 71, 42, 53.
50
20
79
8
4
39
15
26
58
42
53
88
71
85
96
Inserindo um elemento em uma árvore de busca
binária
void tInsere (arvorePTR *plist, char x)
{
if((*plist) == NULL){
*plist=(arvorePTR) malloc (sizeof(struct arvore));
(*plist)->info=x;
(*plist)->esq=NULL;
(*plist)->dir=NULL;
}
else{
if (x<(*plist)->info){
tInsere (&((*plist)->esq),x);
} else{
tInsere (&((*plist)->dir),x);
}
}
Pesquisa de um elemento
Se T é uma árvore nula, não há o que pesquisar;
Se a raiz de T armazena o elemento x, a solução é imediata;
Se x é menor que o valor da raiz de T, a busca prossegue na
subarvore esquerda de T;
Se x é maior ou igual a T, a busca prossegue na subarvore direita
de T
Pesquisa de um elemento
AVRPTR aPesq(arvorePTR *plist, char x) {
if (*plist == NULL)
/*elemento não encontrado*/
return (NULL);
else
if (x==(*plist)->info)
/*elemento encontrado na raiz*/
return (*plist);
else
if (x<(*plist)->info)
/*procura-o numa subarvore*/
return(aPesq(&((*plist)->esq),x));
else
return(aPesq(&((*plist)->dir),x));
}
Remoção de um Elemento
Três cenários:
1. Se a Raiz não possuí filhos, a solução é imediata. Podemos
removê-la e anular T;
2. Se a raiz possuí um único filho, podemos remover o nó raiz e o
nó filho toma o seu lugar;
3. Se a raiz possuir dois filhos, não é possível que ambos assumam
o lugar do pai.
Qual das subarvores deve assumir o lugar do nó pai removido?
O que deve ser feito com a subarvore que não foi escolhida?
Seu nó ficará órfão?
Remoção de um Elemento
Não pode produzir nós órfãos;
Aplicação pode inserir nós com a mesma “info” (definição de árvore
binária):
Impossibilidade de existir em uma subarvore da esquerda elementos maiores
ou iguais à raiz;
Subarvore da direita não pode existir nenhum elemento menor que a raiz;
Assim:
Se identificarmos o maior elemento da subarvore da esquerda e o
posicionarmos na raiz, a árvore obtida continua seguindo a definição de
árvore binária;
O maior elemento em uma árvore binária ordenada encontra-se no nó que
ocupa a posição mais à direita;
com certeza esse nó não possuirá um filho à direita;
Mas poderá possuir um filho a esquerda ….
Remoção de um Elemento
Detalhando uma solução:
Elaborar uma função auxiliar;
recebe um ponteiro para uma árvore não nula;
Faz uma pesquisa para identificar o nó que armazena o seu maior elemento;
Retorna o endereço deste nó;
ARVPTR tMaior(TREEPTR *plist){
TREEPTR t;
t=*plist;
if (t->dir == NULL){
*plist = (*plist)->esq;
return (t);
}else
return(tMaior(&((*plist)->dir)));
}
Remoção de um Elemento
Possíveis passos para remover um nó que tenha dois
filhos:
p=tMaior(&(t->esq)); /*desliga o nó com o maior valor */
t->info = p->info;
free(p);
/*armazena o valor na raiz da árvore */
/*libera o nó removido
*/
Download

Árvores de busca binária