Você está na página 1de 41

Árvore binária de busca

Origem: Wikipédia, a enciclopédia livre.


Saltar para a navegaçãoSaltar para a pesquisa

Árvore binária de busca

Tipo Árvore

Ano 1960

Inventado por P.F. Windley, A.D. Booth, A.J.T. Colin, e T.N. Hibbard

Complexidade de Tempo em Notação big O

Algoritimo Caso Médio Pior Caso


Espaço O(n) O(n)
Busca O(log n) O(n)
Inserção O(log n) O(n)
Remoção O(log n) O(n)
Em Ciência da computação, uma árvore binária de busca (ou árvore binária de pesquisa) é
uma estrutura de dados de árvore binária baseada em nós, onde todos os nós da subárvore esquerda
possuem um valor numérico inferior ao nó raiz e todos os nós da subárvore direita possuem um valor
superior ao nó raiz (esta é a forma padrão, podendo as subárvores serem invertidas, dependendo da
aplicação).
O objetivo desta árvore é estruturar os dados de forma a permitir busca binária.[1]

Pesquisa binária
Origem: Wikipédia, a enciclopédia livre.

Saltar para a navegaçãoSaltar para a pesquisa

Pesquisa binária
classe Algoritmo de busca

estrutura de dados Array, Listas ligadas

complexidade caso
médio

complexidade
melhor caso

complexidade de
espaços pior caso

otimo Sim

espaço
Algoritmos

ver

A pesquisa ou busca binária (em inglês binary search algorithm ou binary chop) é um algoritmo


de busca em vetores que segue o paradigma de divisão e conquista. Ela parte do pressuposto de que
o vetor está ordenado e realiza sucessivas divisões do espaço de busca comparando o elemento
buscado (chave) com o elemento no meio do vetor. Se o elemento do meio do vetor for a chave, a
busca termina com sucesso. Caso contrário, se o elemento do meio vier antes do elemento buscado,
então a busca continua na metade posterior do vetor. E finalmente, se o elemento do meio vier
depois da chave, a busca continua na metade anterior do vetor.

Índice

 1Análise de Complexidade
 2Implementações
o 2.1Pseudo-Código
o 2.2Código em C
 3Ver também
 4Referências
 5Ligações externas

Análise de Complexidade[editar | editar código-fonte]


A complexidade desse algoritmo é da ordem de [1], em que  é o tamanho do vetor de busca.
Apresenta-se mais eficiente que a Busca linear cuja ordem é [2].

Implementações[editar | editar código-fonte]
Pseudo-Código[editar | editar código-fonte]
Um pseudo-código recursivo para esse algoritmo, dados  V  o vetor com elementos comparáveis
e  e  o elemento que se deseja encontrar:

BUSCA-BINÁRIA (V[], início, fim, e)


i recebe o índice do meio entre início e fim
se (v[i] = e) entao
devolva o índice i # elemento e encontrado
fimse
se (inicio = fim) entao
não encontrou o elemento procurado
senão
se (V[i] vem antes de e) então
faça a BUSCA-BINÁRIA(V, i+1, fim, e)
senão
faça a BUSCA-BINÁRIA(V, inicio, i-1, e)
fimse
fimse

Código em C[editar | editar código-fonte]

//Implementação Iterativa:

int PesquisaBinaria (int vet[], int chave, int Tam)


{
int inf = 0; // limite inferior (o primeiro índice de vetor
em C é zero )
int sup = Tam-1; // limite superior (termina em um número a
menos. 0 a 9 são 10 números)
int meio;
while (inf <= sup)
{
meio = (inf + sup)/2;
if (chave == vet[meio])
return meio;
if (chave < vet[meio])
sup = meio-1;
else
inf = meio+1;
}
return -1; // não encontrado
}

//Implementação Recursiva:

// x => chave | v[] => vetor ordenado | e => limite inferior


(esquerda) | d => limite superior (direita)
int PesquisaBinaria (int x, int v[], int e, int d)
{
int meio = (e + d)/2;
if (v[meio] == x)
return meio;
if (e >= d)
return -1; // não encontrado
else
if (v[meio] < x)
return PesquisaBinaria(x, v, meio+1, d);
else
return PesquisaBinaria(x, v, e, meio-1);
}

Obs: A linguagem C fornece a função  bsearch [3] na sua biblioteca padrão.

Ver também[editar | editar código-fonte]


 Busca linear

Referências
1. Ir para cima↑ Felipe, Henrique (6 de setembro de 2017). «A Busca Binária». Blog Cyberini.
Consultado em 8 de julho de 2018.
2. Ir para cima↑ Felipe, Henrique (14 de setembro de 2017). «Busca Linear». Blog Cyberini. Consultado
em 8 de julho de 2018.
3. Ir para cima↑ «bsearch(3): binary search of sorted array - Linux man page». linux.die.net (em
inglês). Consultado em 8 de julho de 2018.

Ligações externas[editar | editar código-fonte]


 Projeto de Algoritmos - Paulo Feofiloff -IME-USP
 NIST Dicionário de Algoritmos e Estrutura de Dados :binary search
 Tim Bray. On the Goodness of Binary Search. Pequeno ensaio das vantagens da busca
binária e exemplo de código em Java.
 Google Research: Nearly All Binary Searches and Mergesorts are Broken
 Busca binária em Java e em C

  Portal das tecnologias de informação


Categoria: 

 Algoritmos de busca
Menu de navegação
 Não autenticado
 Discussão
 Contribuições
 Criar uma conta
 Entrar
 Artigo
 Discussão
 Ler
 Editar
 Editar código-fonte
 Ver histórico
Busca
Ir
 Página principal
 Conteúdo destacado
 Eventos atuais
 Esplanada
 Página aleatória
 Portais
 Informar um erro
 Loja da Wikipédia
Colaboração
 Boas-vindas
 Ajuda
 Página de testes
 Portal comunitário
 Mudanças recentes
 Manutenção
 Criar página
 Páginas novas
 Contato
 Donativos
Imprimir/exportar
 Criar um livro
 Descarregar como PDF
 Versão para impressão
Noutros projetos
 Wikimedia Commons
Ferramentas
 Páginas afluentes
 Alterações relacionadas
 Carregar ficheiro
 Páginas especiais
 Hiperligação permanente
 Informações da página
 Elemento Wikidata
 Citar esta página
Noutras línguas
 ‫العربية‬
 Deutsch
 English
 Español
 हिन्दी
 Italiano
 日本語
 한국어
 中文
30 outras
Editar hiperligações

 Esta página foi editada pela última vez às 23h32min de 8 de julho de 2018.
 Este texto é disponibilizado nos termos da licença Atribuição-CompartilhaIgual 3.0 Não Adaptada (CC
BY-SA 3.0) da Creative Commons; pode estar sujeito a condições adicionais. Para mais detalhes, consulte
as condições de utilização.

 Política de privacidade

 Sobre a Wikipédia

 Avisos gerais

 Programadores

 Declaração sobre ''cookies''

 Versão móvel

Índice

 1Conceitos básicos
o 1.1Definição[2]
o 1.2Elementos
o 1.3Complexidade[3]
 2Operações[3]

o 2.1Busca
o 2.2Inserção
o 2.3Remoção
 2.3.1Remoção na folha
 2.3.2Remoção de nó com um filho
 2.3.3Remoção de nó com dois filhos
 3Aplicações
o 3.1Percursos em ABB
o 3.2Ordenação
 4Ver também
 5Referências
 6Ligações externas

Conceitos básicos[editar | editar código-fonte]

Árvore binária de busca de cardinalidade 9 e altura 4, com raiz 8 e folhas 1, 4, 7 e 13.

Definição[2][editar | editar código-fonte]
Seja S = {s1, s2, ..., sn} um conjunto de chaves tais que s1 < s2 ... sn. Seja k um valor dados. Deseja-se
verificar se k  S e identificar o índice i tal que k = si.
A Árvore Binária de Busca (ABB) resolve os problemas propostos. A figura ilustra uma ABB.
Uma ABB é uma árvore binária rotulada T com as seguintes propriedades:
1. T possui n nós. Cada nó u armazena uma chave distinta sj  S
e tem como rótulo o valor r(u) = sj.
2. Para cada nó v de T r(v1) < r(v) e r(v2) > r(v), onde
v1 pertence à subárvore esquerda de v e v2 pertence à
subárvore direita de v.
Dado o conjunto S com mais de um elemento, existem várias ABB que resolvem o problema.
Elementos[editar | editar código-fonte]

 Nós - são todos os itens guardados na árvore


 Raiz - é o nó do topo da árvore (no caso da figura acima, a raiz é
o nó 8)
 Filhos - são os nós que vem depois dos outros nós (no caso da
figura acima, o nó 6 é filho do 3)
 Pais - são os nós que vem antes dos outros nós (no caso da
figura acima, o nó 10 é pai do 14)
 Folhas - são os nós que não têm filhos; são os últimos nós da
árvore (no caso da figura acima, as folhas são 1, 4, 7 e 13)
Complexidade[3][editar | editar código-fonte]
A complexidade das operações sobre ABB depende diretamente da altura da árvore.
Uma árvore binária de busca com chaves aleatórias uniformemente distribuídas tem altura O(log n).
No pior caso, uma ABB poderá ter altura O(n). Neste caso a árvore é chamada de árvore zig-zag e
corresponde a uma degeneração da árvore em lista encadeada.
Em função da observação anterior, a árvore binária de busca é de pouca utilidade para ser aplicada
em problemas de busca em geral. Daí o interesse em árvores balanceadas, cuja altura seja O(log n)
no pior caso

Operações[3][editar | editar código-fonte]
Busca[editar | editar código-fonte]

Buscando um valor na árvore binária.

A busca em uma árvore binária por um valor específico pode ser um processo recursivo ou iterativo.
Será apresentado um método recursivo.
A busca começa examinando o nó raiz. Se a árvore está vazia, o valor procurado não pode existir na
árvore. Caso contrário, se o valor é igual a raiz, a busca foi bem sucedida. Se o valor é menor do que
a raiz, a busca segue pela subárvore esquerda. Similarmente, se o valor é maior do que a raiz, a
busca segue pela subárvore direita. Esse processo é repetido até o valor ser encontrado ou a
subárvore ser nula (vazia). Se o valor não for encontrado até a busca chegar na subárvore nula, então
o valor não deve estar presente na árvore.
Segue abaixo o algoritmo de busca implementado na linguagem Python:

# 'no' refere-se ao nó-pai, neste caso


def arvore_binaria_buscar(no, valor):
if no is None:
# valor não encontrado
return None
else:
if valor == no.valor:
# valor encontrado
return no.valor
elif valor < no.valor:
# busca na subárvore esquerda
return arvore_binaria_buscar(no.filho_esquerdo, valor)
elif valor > no.valor:
# busca na subárvore direita
return arvore_binaria_buscar(no.filho_direito, valor)

Essa operação poderá ser O(log n) em algumas situações, mas necessita O(n) de tempo no pior caso,
quando a árvore assumir a forma de lista ligada (árvore ziig-zag)[2].
Inserção[editar | editar código-fonte]
A inserção começa com uma busca, procurando pelo valor, mas se não for encontrado, procuram-se
as subárvores da esquerda ou direita, como na busca. Eventualmente, alcança-se a folha, inserindo-se
então o valor nesta posição. Ou seja, a raiz é examinada e introduz-se um nó novo na subárvore da
esquerda se o valor novo for menor do que a raiz, ou na subárvore da direita se o valor novo for
maior do que a raiz. Abaixo, um algoritmo de inserção em Python:

def arvore_binaria_inserir(no, chave, valor):


if no is None:
return TreeNode(None, chave, valor, None)
if chave == no.chave:
return TreeNode(no.filho_esquerdo, chave, valor,
no.filho_direito)
if chave < no.chave:
return TreeNode(arvore_binaria_inserir(no.filho_esquerdo,
chave, valor), no.chave, no.valor, no.filho_direito)
else:
return TreeNode(no.filho_esquerdo, no.chave, no.valor,
arvore_binaria_inserir(no.filho_direito, chave, valor))

Esta operação requer O (log n) vezes para o caso médio e necessita de O (n) no pior caso. A fim de
introduzir um nó novo na árvore, seu valor é primeiro comparado com o valor da raiz. Se seu valor
for menor que a raiz, é comparado então com o valor do filho da esquerda da raiz. Se seu valor for
maior, está comparado com o filho da direita da raiz. Este processo continua até que o nó novo esteja
comparado com um nó da folha, e então adiciona-se o filho da direita ou esquerda, dependendo de
seu valor.
Remoção[editar | editar código-fonte]
A exclusão de um nó é um processo mais complexo. Para excluir um nó de uma árvore binária de
busca, há de se considerar três casos distintos para a exclusão:
Remoção na folha[editar | editar código-fonte]
A exclusão na folha é a mais simples, basta removê-lo da árvore.

Remoção de nó com um filho[editar | editar código-fonte]


Excluindo-o, o filho sobe para a posição do pai.

Remoção de nó com dois filhos[editar | editar código-fonte]


Neste caso, pode-se operar de duas maneiras diferentes. Pode-se substituir o valor do nó a ser
retirado pelo valor sucessor (o nó mais à esquerda da subárvore direita) ou pelo valor antecessor (o
nó mais à direita da subárvore esquerda), removendo-se aí o nó sucessor (ou antecessor).

No exemplo acima, o nó de valor 30 está para ser removido, e possui como sucessor imediato o valor
35 (nó mais à esquerda da sua sub-árvore direita). Assim sendo, na exclusão, o valor 35 será
promovido no lugar do nó a ser excluído, enquanto a sua sub-árvore (direita) será promovida para
sub-árvore esquerda do 40, como pode ser visto na figura.
Exemplo de algoritmo de exclusão em Python:

def exclusao_em_arvore_binaria(nó_arvore, valor):


if nó_arvore is None: return None # Valor não encontrado
esquerda, nó_valor, direita = nó_arvore.esquerda, nó_arvore.valor,
nó_arvore.direita
if nó_valor == valor:
if esquerda is None:
return direita
elif direita is None:
return esquerda
else:
valor_max, novo_esquerda = busca_max(esquerda)
return TreeNode(novo_esquerda, valor_max, direita)
elif valor < nó_valor:
return TreeNode(exclusao_em_arvore_binaria(esquerda, valor),
nó_valor, direita)
else:
return TreeNode(esquerda, nó_valor,
exclusao_em_arvore_binaria(direita, valor))

def busca_max(nó_arvore):
esquerda, nó_valor, direita = nó_arvore.esquerda, nó_arvore.valor,
nó_arvore.direita
if direita is None: return (nó_valor, esquerda)
else:
(valor_max, novo_direita) = busca_max(direita)
return (valor_max, (esquerda, nó_valor, novo_direita))

Embora esta operação não percorra sempre a árvore até uma folha, esta é sempre uma possibilidade;
assim, no pior caso, requer o tempo proporcional à altura da árvore, visitando-se cada nó somente
uma única vez.

Aplicações[editar | editar código-fonte]
Percursos em ABB[editar | editar código-fonte]
Em uma árvore binária de busca podem-se fazer os três percursos que se fazem para qualquer árvore
binária (percursos em inordem, pré-ordem e pós-ordem). É interessante notar que, quando se faz um
percurso em ordem em uma árvore binária de busca, os valores dos nós aparecem em ordem
crescente. A operação "Percorre" tem como objetivo percorrer a árvore numa dada ordem,
enumerando os seus nós. Quando um nó é enumerado, diz-se que ele foi "visitado".
Pré-ordem (ou profundidade):

1. Visita a raiz
2. Percorre a subárvore esquerda em pré-ordem
3. Percorre a subárvore direita em pré-ordem
Ordem Simétrica:

1. Percorre a subárvore esquerda em ordem simétrica


2. Visita a raiz
3. Percorre a subárvore direita em ordem simétrica
Pós-ordem:

1. Percorre a subárvore esquerda em pós-ordem


2. Percorre a subárvore direita em pós-ordem
3. Visita a raiz

Árvore Binária de Busca


Usando a ABB acima, os resultados serão os seguintes:
Pré-ordem => 8, 3, 1, 6, 4, 7, 10, 14, 13
Ordem simétrica => 1, 3, 4, 6, 7, 8, 10, 13, 14 (chaves ordenadas)
Pós-ordem => 1, 4, 7, 6, 3, 13, 14, 10, 8
Ordenação[editar | editar código-fonte]
Uma árvore binária de busca pode ser usada para ordenação de chaves. Para fazer isto, basta inserir
todos os valores desejados na ABB e executar o percurso em ordem simétrica.

def criar_arvore_binaria(valor):
arvore = None
for v in valor:
arvore = arvore_binaria_de_insercao(arvore, v)
return arvore

def arvore_binaria_transversal(nó_arvore):
if nó_arvore is None: return []
else:
esquerda, valor, direita = nó_arvore
return (arvore_binaria_transversal(esquerda) + [valor] +
arvore_binaria_transversal(direita))

Criar ABB tem complexidade O(n2) no pior caso. A geração de um vetor de chaves ordenadas tem
complexidade O(n). O algoritmo de ordenação terá complexidade final O(n2) no pior caso.
Cabe observar que há algoritmos de ordenação dedicados com complexidade O(n.log n), com
desempenho superior ao proposto neste tópico.

Ver também[editar | editar código-fonte]


Outros projetos Wikimedia também contêm
material sobre este tema:

Livros e manuais no Wikilivros

Imagens e  media no Commons

 Árvore (estrutura de dados)


 Árvore binária
 Árvore AVL
 Árvore B
 Árvore Patricia
 Estrutura de dados

Referências
1. Ir para cima↑ Gilberg, R.; Forouzan, B. (2001). «8». Data
Structures: A Pseudocode Approach With C++ (em inglês).
Pacific Grove, CA: Brooks/Cole. p. 339. ISBN 0-534-95216-X
2. ↑ Ir para:a b Swarcfiter, Jayme Luiz (1994). Estruturas de Dados e
seus Algoritmos. Rio de Janeiro: LTC. pp. 91–97
3. ↑ Ir para:a b Cormen, Thomas H.; et al. (2009). Introduction to
Algorithms. Massachusetts: MIT Press. pp. 286–307

Ligações externas[editar | editar código-fonte]


 An introduction to binary trees from Stanford (em inglês)
 Árvores Binárias de Busca (IME/USP)  (em português)
 Dicionário de Algoritmos e Estrutura de Dados - Capítulo de
árvore binária de busca (em inglês)
 Exemplo de árvore binária de busca em Python (em inglês)

[Expandir]

v • e

Estrutura de dados
[Esconder]

v • e

Árvores (estrutura de dados)


Árvores de busca 2-3
(conjuntos dinâmicos/vetores associativos) 2-3-4
AA
(a,b)
AVL
B
B+
B*
Binária
Intervalo
Rubro-negra
Scapegoat
Splay
T
Treap
Binária
Binomial
Brodal
Heaps
Fibonacci
Esquerdista
Van Emde Boas
PATRICIA
Tries Sufixo
Ternária
BK
BSP
Hilbert R
k-d
M
Métrica
Árvores de particionamento de dados espaciais Octree
Quaternária
R
R+
R*
Segmentos
VP
Fenwick
K-ária
Outras árvores
Merkle
Hiperbólica
Categoria: 
 Estruturas de dados
Menu de navegação
 Não autenticado
 Discussão
 Contribuições
 Criar uma conta
 Entrar
 Artigo
 Discussão
 Ler
 Editar
 Editar código-fonte
 Ver histórico
Busca
Ir

 Página principal
 Conteúdo destacado
 Eventos atuais
 Esplanada
 Página aleatória
 Portais
 Informar um erro
 Loja da Wikipédia
Colaboração
 Boas-vindas
 Ajuda
 Página de testes
 Portal comunitário
 Mudanças recentes
 Manutenção
 Criar página
 Páginas novas
 Contato
 Donativos
Imprimir/exportar
 Criar um livro
 Descarregar como PDF
 Versão para impressão
Noutros projetos
 Wikimedia Commons
Ferramentas
 Páginas afluentes
 Alterações relacionadas
 Carregar ficheiro
 Páginas especiais
 Hiperligação permanente
 Informações da página
 Elemento Wikidata
 Citar esta página
Noutras línguas
 ‫العربية‬
 Deutsch
 English
 Español
 Italiano
 日本語
 한국어
 Русский
 中文
20 outras
Editar hiperligações
 Esta página foi editada pela última vez às 17h21min de 24 de agosto de
2017.
 Este texto é disponibilizado nos termos da licença Atribuição-
CompartilhaIgual 3.0 Não Adaptada (CC BY-SA 3.0) da Creative Commons;
pode estar sujeito a condições adicionais. Para mais detalhes, consulte
as condições de utilização.

 Política de privacidade

 Sobre a Wikipédia

 Avisos gerais

 Programadores

 Declaração sobre ''cookies''

 Versão móvel

Árvores binárias
As árvores da computação têm a curiosa tendência
de crescer para baixo…
 

Uma árvore binária é uma estrutura de dados mais geral que uma lista
encadeada.  Este capítulo introduz algumas operações básicas sobre
árvores binárias. O capítulo seguinte, Árvores binárias de busca, trata de
uma aplicação fundamental.

Nós e filhos
Uma árvore binária (= binary tree) é um conjunto de registros que satisfaz
certas condições.  As condições não serão dadas explicitamente, mas elas
ficarão implicitamente claras no contexto.  Os registros serão
chamados nós (poderiam também ser chamados células).  Cada nó tem
um endereço.  Suporemos por enquanto que cada nó tem apenas três
campos:  um número inteiro e dois ponteiros para nós.  Os nós podem,
então, ser definidos assim:

typedef struct reg {


int conteudo; // conteúdo
noh *esq;
noh *dir;
} noh; // nó

O campo conteudo é a carga útil do nó;  os dois outros campos servem


apenas para dar estrutura à árvore.  O campo esq de cada nó
contém NULL ou o endereço de outro nó.  Uma hipótese análoga vale para
o campo dir.

Se o campo esq de um nó P é o endereço de um nó E, diremos que E é


o filho esquerdo de P.  Analogamente, se P.dir é igual a &D, diremos
que D é o filho direito de P.  Se um nó F é filho (esquerdo ou direito) de P,
diremos que P é o pai de F.  Uma folha (= leaf) é um nó que não tem filho
algum.

É muito conveniente confundir, verbalmente, cada nó com seu endereço. 


Assim, se x é um ponteiro para um nó (ou seja, se x é do tipo *noh),
dizemos  considere o nó x  em lugar de  considere o nó cujo endereço é x.

A figura abaixo mostra dois exemplos de árvores binárias. Do lado


esquerdo, temos uma curiosa árvore binária na natureza. Do lado direito,
uma representação esquemática de uma árvore binária cujos nós contêm
os números 2, 7, 5, etc.
Exercícios 1
1. Dê uma lista das condições que um conjunto de nós deve satisfazer para ser
considerado uma árvore binária.

Árvores e subárvores
Suponha que x é um nó.  Um descendente de x é qualquer nó que possa ser
alcançado pela iteração das instruções  x = x->esq  e  x = x->dir  em
qualquer ordem.  (É claro que essas instruções só podem ser iteradas
enquanto x for diferente de NULL. Estamos supondo que NULL é de fato
atingido mais cedo ou mais tarde.)

Um nó x juntamente com todos os seus descendentes é uma árvore


binária.  Dizemos que x é a raiz (= root) da árvore.  Se x tiver um pai, essa
árvore é subárvore de alguma árvore maior.  Se x é NULL, a árvore é vazia.
Para qualquer nó x, o nó  x->esq  é a raiz da subárvore esquerda de  x 
e  x->dir  é a raiz da subárvore direita de x.

Endereço de uma árvore e definição recursiva


O endereço de uma árvore binária é o endereço de sua raiz.  É conveniente
confundir, verbalmente, árvores com seus endereços:  dizemos  considere
a árvore r  em lugar de  considere a árvore cuja raiz tem endereço r.  Essa
convenção sugere a introdução do nome alternativo arvore para o tipo-
de-dados ponteiro-para-nó:

typedef noh *arvore; // árvore

A convenção permite formular a definição de árvore binária de maneira


recursiva:  um ponteiro-para-nó r é uma árvore binária se

1. r é NULL    ou
2. r->esq  e  r->dir  são árvores binárias.

Muitos algoritmos sobre árvores ficam mais simples quando escritos em


estilo recursivo.

Exercícios 2
1. Árvores binárias têm uma relação muito íntima com certas sequências bem-
formadas de parênteses. Discuta essa relação.

2. ★ EXPRESSÕES ARITMÉTICAS.  Árvores binárias podem ser usadas, de maneira muito


natural, para representar expressões aritméticas (como ((a+b)*c-d)/(e-f)+g,
por exemplo).  Discuta os detalhes.

Varredura esquerda-raiz-direita
Uma árvore binária pode ser percorrida de muitas maneiras diferentes.
Uma maneira particularmente importante é a esquerda-raiz-direita, ou e-
r-d, também conhecida como inorder traversal, ou varredura infixa, ou
varredura central.  A varredura e-r-d visita

1. a subárvore esquerda da raiz, em ordem e-r-d,


2. a raiz,
3. a subárvore direita da raiz, em ordem e-r-d,
nessa ordem.  Na seguinte figura, os nós estão numeradas na ordem em
que são visitados pela varredura e-r-d.

Eis uma função recursiva que faz a varredura e-r-d de uma árvore


binária r:

// Recebe a raiz r de uma árvore binária e


// imprime os conteúdos dos seus nós
// em ordem e-r-d.

void erd (arvore r) {


if (r != NULL) {
erd (r->esq);
printf ("%d\n", r->conteudo);
erd (r->dir);
}
}

É um excelente exercício escrever uma versão iterativa dessa função. A


versão abaixo usa uma pilha de nós. A sequência de nós na pilha é uma
espécie de roteiro daquilo que ainda precisa ser feito:  cada nó x na pilha
é um lembrete de que ainda precisamos imprimir o conteúdo de x e o
conteúdo da subárvore direita de x.  O elemento do topo da pilha pode
ser um NULL, mas os demais elementos são diferentes de NULL.

// Recebe a raiz r de uma árvore binária e


// imprime os conteúdos dos seus nós
// em ordem e-r-d.

void erd_i (arvore r) {


criapilha (); // pilha de nós
empilha (r);
while (true) {
x = desempilha ();
if (x != NULL) {
empilha (x);
empilha (x->esq);
}
else {
if (pilhavazia ()) break;
x = desempilha ();
printf ("%d\n", x->conteudo);
empilha (x->dir);
}
}
liberapilha ();
}

(O código ficaria ligeiramente mais simples — mas um pouco menos


legível — se manipulasse a pilha diretamente.)   A figura abaixo dá um
exemplo de execução da função erd_i. Cada linha da tabela resume o
estado das coisas no início de uma iteração: à esquerda está a pilha e à
direita os nós impressos.  O valor NULL é indicado por -.

pilha
5
5 3
5 3 1
5 3 1 0
5 3 1 0 -
5 5 3 1 - 0
/ \ 5 3 2 1
5 3 2 -
3 8 5 3 - 2
/ \ / \ 5 4 3
1 4 6 9 5 4 -
/ \ \ 5 - 4
0 2 7 8 5
8 6
8 6 -
8 7 6
8 - 7
9 8
9 -
- 9

Os exercícios abaixo discutem duas outras ordens de varredura de uma


árvore binária:  a varredura  r-e-d, que percorre a árvore em ordem raiz-
esquerda-direita, e a varredura e-d-r, que percorre a árvore em ordem
esquerda-direita-raiz.  A primeira também é conhecida comopreorder
traversal, ou varredura em pré-ordem, ou varredura prefixa.  A segunda
também é conhecida como postorder traversal, ou varredura em pós-
ordem, ou varredura posfixa.  (A propósito, veja abaixo o exercício sobre
notações infixa, posfixa e prefixa.)

Exercícios 3
1. Considere a função erd_i. É verdade que a sequência de nós na pilha é um
caminho que começa em algum nó e segue os ponteiros esquerdo e direito em
alguma ordem?
2. Verifique que o código abaixo é equivalente ao da função erd_i.  O código usa
uma pilha de nós, todos diferentes de NULL, e mais um nó x (que é candidato a
entrar na pilha mas pode ser NULL).
3. void erd_i (arvore r) {
4. noh *x = r;
5. criapilha ();
6. while (true) {
7. while (x != NULL) {
8. empilha (x);
9. x = x->esq; }
10. if (pilhavazia ()) break;
11. x = desempilha ();
12. printf ("%d\n", x->conteudo);
13. x = x->dir; }
14. liberapilha (); }

15. NÚMERO DE NÓS.  Escreva uma função que calcule o número de nós de uma árvore
binária.

16. FOLHAS.  Escreva uma função que imprima, em ordem e-r-d, os conteúdos


das folhas de uma árvore binária.

17. Dada uma árvore binária, encontrar um nó da árvore cujo conteúdo tenha um dado
valor val.

18. VARREDURA R-E-D.  Escreva uma função que faça a varredura r-e-d (varredura


prefixa) de uma árvore binária. (A varredura r-e-d também é conhecida como busca
em profundidade ou depth-first search.)

19. VARREDURA E-D-R.  Escreva uma função que faça varredura e-d-r (varredura


posfixa) de uma árvore binária.

20. NOTAÇÕES INFIXA, POSFIXA E PREFIXA.  Mostre que a varredura e-r-d da árvore de


uma expressão aritmética corresponde exatamente à representação infixada
expressão.  Mostre que a varredura e-d-r da árvore de uma expressão aritmética
corresponde exatamente à representação da expressão em notação posfixa.  Mostre
que a varredura r-e-d da árvore de uma expressão aritmética corresponde
exatamente à notação prefixa.

Altura e profundidade
A altura de um nó x em uma árvore binária é a distância entre x e o seu
descendente mais afastado. Mais precisamente, a altura de x é o número
de passos no mais longo caminho que leva de x até uma folha. Os
caminhos a que essa definição se refere são os obtido pela iteração das
instruções x = x->esq e x = x->dir, em qualquer ordem.

A altura (= height) xde uma árvore é a altura da raiz da árvore.  Uma árvore


com um único nó tem altura 0. A árvore da figura tem altura 3.
Veja como a altura de uma árvore com raiz r pode ser calculada:

// Devolve a altura da árvore binária


// cuja raiz é r.

int altura (arvore r) {


if (r == NULL)
return -1; // altura da árvore vazia
else {
int he = altura (r->esq);
int hd = altura (r->dir);
if (he < hd) return hd + 1;
else return he + 1;
}
}

Qual a relação entre a altura, digamos h, e o número de nós de uma


árvore binária?  Se a árvore tem n nós então

n−1  ≥  h  ≥  lg (n) ,

onde  lg (n)  denota  ⌊log n⌋,  ou seja, o piso de log n .  Uma árvore binária


de altura n−1 é um tronco sem galhos: cada nó tem no máximo um filho. 
No outro extremo, uma árvore de altura lg (n) é quase completa: todos
os níveis estão lotados exceto talvez o último.

n lg(n)
4 2
5 2
6 2
10 3
64 6
100 6
128 7
1000 9
1024 10
1000000 19
Uma árvore binária é balanceada (ou equilibrada) se, em cada um de seus
nós, as subárvores esquerda e direita tiverem aproximadamente a mesma
altura. Uma árvore binária balanceada com n nós tem altura próxima
de  log n.  (A árvore do exemplo acima é balanceada).  Convém trabalhar
com árvores balanceadas sempre que possível. Mas isso não é fácil se a
árvore aumenta e diminui ao longo da execução do seu programa.

Profundidade.  A profundidade (= depth) de um nó s em uma árvore


binária com raiz r é a distância de r a s. Mais precisamente, a
profundidade de s é o comprimento do único caminho que vai de r até s.
Por exemplo, a profundidade de r é 0 e a profundidade de r->esqé 1.

Uma árvore é balanceada se todas as suas folhas têm aproximadamente a


mesma profundidade.

Exercícios 4
1. Desenhe uma árvore binária que com 17 nós que tenha a menor altura possível.
Repita com a maior altura possível.

2. Escreva uma função iterativa para calcular a altura de uma árvore binária.

3. Escreva uma função que imprima o conteúdo de cada nó de uma árvore binária.
Faça uma indentação (recuo de margem) proporcional à profundidade do nó.
Segue um exemplo de árvore e sua representação (os
caracteres '-' representam NULL):
4. 555 555
5. / \ 333
6. 111
7. 333 888 -
8. / \ \ -
9. 111 444 999 444
10. -
11. -
12. 888
13. -
14. 999
15. -
16. -

17. VARREDURA POR NÍVEIS.  A varredura por níveis (= level-traversal), ou busca em


largura (= breadth-first search), de uma árvore binária visita todos os nós à
profundidade 0, depois todos os nós à profundidade 1, depois todos os nós à
profundidade 2, e assim por diante.  Para cada profundidade, os nós são
visitados da esquerda para a direita.  Escreva uma função que imprima os
conteúdos dos nós de uma árvore na ordem da varredura por níveis.  (Dica: Use
uma fila de nós. Veja o cálculo de distâncias em um grafo.)

18. Digamos que h é a altura e p é a profundidade de um nó x em uma árvore binária. 
É verdade que h + p é igual à altura da árvore?

19. Escreva uma função que determine a profundidade de um nó dado.


20. Escreva uma função que decida se uma dada árvore binária é quase completa.

21. DE HEAP PARA ÁRVORE.  Escreva uma função que transforme um heap v[1..n] em
uma árvore binária (quase completa).

22. DE ÁRVORE PARA HEAP.  Uma árvore binária é hierárquica se  x->conteudo ≥ x-


>esq->conteudo  e  x->conteudo ≥ x->dir->conteudo  para todo nó x, desde
que os filhos existam.  Escreva uma função que transforme uma árvore hierárquica
quase completa em heap. 

23. HIERARQUIZAÇÃO.  Uma árvore binária é esquerdista se, para todo nó x, x->esq ==


NULL implica em x->dir == NULL.  Uma árvore binária é hierárquica se x-
>conteudo ≥ x->esq->conteudo  e  x->conteudo ≥ x->dir->conteudo 
para todo nó x, desde que os filhos existam.  Escreva uma função que movimente
os campos conteudo de uma árvore esquerdista de modo a torná-la hierárquica. 
(Sugestão: Imite a função que transforma um vetor em heap. Em particular, imite a
função peneira.)

24. ÁRVORE AVL.  Uma árvore é balanceada no sentido AVL se, para cada nó x, as
alturas das subárvores que têm raízes x->esq e x->dir diferem de no máximo
uma unidade. Escreva uma função que decida se uma dada árvore é balanceada no
sentido AVL. Procure escrever sua função de modo que ela visite cada nó no
máximo uma vez.

Nós com campo pai


Em algumas aplicações (veja a seção seguinte) é conveniente ter acesso
direto ao pai de qualquer nó. Para isso, é preciso acrescentar um
campo pai a cada nó:

typedef struct reg {


int conteudo;
struct reg *pai;
struct reg *esq, *dir;
} noh;

É um bom exercício escrever uma função que preencha o campo pai de


todos os nós de uma árvore binária.

Exercícios 5
1. Escreva uma função que preencha corretamente todos os campos pai de uma
árvore binária.

2. FILA DE PRIORIDADES.  Uma árvore binária quase completa com


campo pai é hierárquica se x->conteudo ≥ x->esq->conteudo ex->conteudo
≥ x->dir->conteudo para todo nó x (desde que os filhos existam).  Escreva uma
implementação de fila de prioridades baseada em árvore hierárquica. 
A implementação deve ter funções para criar uma fila vazia, retirar um elemento
máximo da fila, e inserir um elemento na fila.  (Dica: veja a implementação de fila
de prioridades baseada em heap.)
Primeiro e último nós
Considere o seguinte problema sobre uma árvore binária: encontrar o
endereço do primeiro nó da árvore na ordem e-r-d. É claro que o problema
só faz sentido se a árvore não é vazia.  Eis uma função que resolve o
problema:

// Recebe uma árvore binária não vazia r


// e devolve o primeiro nó da árvore
// na ordem e-r-d.

noh *primeiro (arvore r) {


while (r->esq != NULL)
r = r->esq;
return r;
}

Não é difícil fazer uma função análoga que encontre o último nó na


ordem e-r-d.

Nó seguinte e anterior (sucessor e predecessor)


Digamos que x é o endereço de um nó de uma árvore binária. Nosso
problema:  calcular o endereço do nó seguinte na ordem e-r-d.

Para resolver o problema, é necessário que os nós tenham


um campo pai.  A função a seguir resolve o problema. É claro que a
função só deve ser chamada com x diferente de NULL. A função devolve o
endereço do nó seguinte a x ou devolve NULL se x é o último nó.

// Recebe o endereço de um nó x. Devolve o endereço


// do nó seguinte na ordem e-r-d.
// A função supõe que x != NULL.

noh *seguinte (noh *x) {


if (x->dir != NULL) {
noh *y = x->dir;
while (y->esq != NULL) y = y->esq;
return y; // A
}
while (x->pai != NULL && x->pai->dir == x) // B
x = x->pai; // B
return x->pai;
}

(Note que a função não precisa saber onde está a raiz da árvore.)  Na
linha A, y é o endereço do primeiro nó, na ordem e-r-d, da subárvore cuja
raiz é x->dir. As linhas B fazem com que x suba na árvore enquanto for
filho direito de alguém.

Exercícios 6
1. Escreva uma versão recursiva da função primeiro.

2. Escreva uma função que encontre o último nó na ordem e-r-d.

3. Escreva uma função que receba o endereço de um nó x de uma árvore binária e
encontre o endereço do nó anterior a x na ordem e-r-d.

4. Escreva uma função que faça varredura e-r-d usando as


funções primeiro e seguinte.

Atualizado em 2018-08-07
https://www.ime.usp.br/~pf/algoritmos/
Paulo Feofiloff
DCC-IME-USP

Árvore Binária – Percursos Pré, Em


e Pós Ordem
Publicado em junho 7, 2015 por surfx2013

Código simples em Java de percurso em árvores binárias Pré, Em e Pós ordem.

Exemplo de leitura Pré, Em e Pós Ordem da árvore:


—————————————–
PreOrdem (RED): F,B,A,D,C,E,G,I,H
InOrdem (ERD): A,B,C,D,E,F,G,H,I
PosOrdem (EDR): A,C,E,D,B,H,I,G,F
—————————————–

Formas de Leitura:

 Pré-Ordem: RED = raiz, esquerda, direita


 In-Ordem: ERD = esquerda, raiz, direita
 Pós-Ordem: EDR = esquerda, direita, raiz
Crie um projeto no Eclipse chamado ‘Arvores’

Crie a classe ‘Node’:

1 package arvore.binary;

2  
/**
3  * Classe nó

4  *

 * @author Emerson Shigueo Sugimoto 07/06/2015 11:42


5
 */
6
public class Node {
7
 
8
    private String nome;
9
    private Node esquerda;
10     private Node direita;
11      
12     public String getNome() { return nome; }
13     public void setNome(String nome) { this.nome = nome; }

14     public Node getEsquerda() { return esquerda; }

15     public void setEsquerda(Node esquerda) { this.esquerda = esquerda; }

    public Node getDireita() { return direita; }


16
    public void setDireita(Node direita) { this.direita = direita; }
17
     
18
    public Node(){
19
        this(null, null, null);
20
    }
21
    public Node(String nome){
22         this(nome, null, null);
23     }

24      

25     public Node(String nome, Node esquerda, Node direita){

26         setNome(nome);

27         setEsquerda(esquerda);

        setDireita(direita);
28
    }
29
     
30
    @Override
31
    public int hashCode() {
32
        return getNome() == null ? 0 : getNome().hashCode();
33
34

35

36     }

37      

38     @Override

    public boolean equals(Object obj) {


39
        if (obj == null || !(obj instanceof Node)) { return false; }
40
        return ((Node)obj).hashCode() == hashCode();
41
    }
42
     
43
    @Override
44
    public String toString() {
45         return getNome() == null ? "" : getNome();
46     }

47      

48 }

49

50
O objetivo da classe nó (‘Node’) é ser um nodo da árvore binária, possuindo um
identificador (nome) e os ponteiros (referências) para as subárvores da esquerda (private
Node esquerda) e direita (private Node direita).

Crie a classe ‘ArvoreBin’:

1 package arvore.binary;

2  

3 /**

 * <b>Árvore binária</b>
4
 
5
 * <ul>
6
 *  <li>RED = <u>r</u>aiz, <u>e</u>squerda, <u>d</u>ireita</li>
7
 *  <li>ERD = <u>e</u>squerda, <u>r</u>aiz, <u>d</u>ireita</li>
8
 *  <li>EDR = <u>e</u>squerda, <u>d</u>ireita, <u>r</u>aiz</li>
9  * </ul>
10  * @author Emerson Shigueo Sugimoto 07/06/2015 11:39
11  */

12 public class ArvoreBin {

13      

    /**
14
     * ao invés deste enum, poderia ser usado um boolean
15
     */
16
    public enum ModoRL {
17
        esquerda, direita
18     }
19      
20     private Node arvore;
21  
22     public Node getArvore() { return arvore; }

23     public void setArvore(Node arvore) { this.arvore = arvore; }

24      

25     /**

     *
26
     * @param raiz raiz da árvore
27
     */
28
    public ArvoreBin(String raiz){
29
        setArvore(new Node(raiz));
30
    }
31
     
32     /**
33      * adiciona um novo nó

34      * @param noPai nome do nó pai

35      * @param nomeNo nome do novo nó

36      * @param modo posição: direita / esquerda

     */
37
    public void AdicionarNo(String noPai, String nomeNo, ModoRL modo){
38
        if (modo == ModoRL.direita) {
39
            AdicionarNoDireita(noPai, nomeNo);
40
        } else if (modo == ModoRL.esquerda) {
41
42             AdicionarNoEsquerda(noPai, nomeNo);

43         }

    }
44
     
45
    public void AdicionarNoEsquerda(String noPai, String nomeNo){
46
        Node no = findNode(getArvore(), noPai);
47
        if (no == null) { return; }
48
        no.setEsquerda(new Node(nomeNo));
49     }
50      
51     public void AdicionarNoDireita(String noPai, String nomeNo){
52         Node no = findNode(getArvore(), noPai);

53         if (no == null) { return; }

54         no.setDireita(new Node(nomeNo));

    }
55
     
56
    /**
57
     * A ideia não é criar uma árvore binária ordenada,
58
     * por isto a busca exaustiva pelos nós.
59
 
60
     * A principal ideia é permitir criar qualquer tipo
61
     * de árvore, com qualquer tipo de ordenação.
62      * @param no
63      * @param nome

64      * @return

65      */

    private Node findNode(Node no, String nome){


66
        if (no == null || nome == null || nome.isEmpty()) { return null; }
67
        if (no.getNome().equals(nome)) { return no; }
68
        Node noesquerda = findNode(no.getEsquerda(), nome);
69
        if (noesquerda != null) { return noesquerda; }
70
        return findNode(no.getDireita(), nome);
71     }
72
73      

74     /**

75      * limpa a árvore

     * @param raiz raiz da árvore


76
     */
77
    public void Clear(String raiz){
78
        nullnodes(getArvore());
79
        setArvore(new Node(raiz));
80     }
81      
82     /**
83      * método recursivo auxiliar para limpar a árvore

84      * @param no

85      */

    private void nullnodes(Node no){


86
        if (no == null) { return; }
87
        nullnodes(no.getDireita());
88
        nullnodes(no.getEsquerda());
89
        no.setEsquerda(null); no.setDireita(null);
90         no = null;
91     }
92      
93     /**

94      * RED

95      * @return

     */
96
    public String PreOrdem(){
97
        if (getArvore() == null) { return ""; }
98
        return readPreOrdem(getArvore());
99
    }
100
     
101
    /**
102      * RED
103      * @param no
104      * @return

105      */

    private String readPreOrdem(Node no){


106
        if (no == null) {return "";}
107
        String rt = no.toString();
108
        if (no.getEsquerda() != null) {
109
            rt += (rt.isEmpty() ? "" : ",") + readPreOrdem(no.getEsquerda());
110         }
111         if (no.getDireita() != null) {
112             rt += (rt.isEmpty() ? "" : ",") + readPreOrdem(no.getDireita());

113         }

114         return rt;

    }
115
     
116
    /**
117
     * ERD
118
     * @return
119
     */
120
    public String InOrdem(){
121         if (getArvore() == null) { return ""; }
122         return readInOrdem(getArvore());

123     }

124      

125     /**

126      * ERD

     * @param no
127
     * @return
128
     */
129
    private String readInOrdem(Node no){
130
        if (no == null) {return "";}
131         String rt = "";
132         if (no.getEsquerda() != null) {

133             rt += (rt.isEmpty() ? "" : ",") + readInOrdem(no.getEsquerda());

134         }
135         rt += (rt.isEmpty() ? "" : ",") + no.toString();

136         if (no.getDireita() != null) {

            rt += (rt.isEmpty() ? "" : ",") + readInOrdem(no.getDireita());


137
        }
138
        return rt;
139
    }
140
     
141
    /**
142      * EDR
143      * @return
144      */

145     public String PosOrdem(){

146         if (getArvore() == null) { return ""; }

        return readPosOrdem(getArvore());
147
    }
148
     
149
    /**
150
     * EDR
151
     * @param no
152
     * @return
153      */
154     private String readPosOrdem(Node no){

155         if (no == null) {return "";}

156         String rt = "";

        if (no.getEsquerda() != null) {


157
            rt += (rt.isEmpty() ? "" : ",") + readPosOrdem(no.getEsquerda());
158
        }
159
        if (no.getDireita() != null) {
160
            rt += (rt.isEmpty() ? "" : ",") + readPosOrdem(no.getDireita());
161
        }
162         rt += (rt.isEmpty() ? "" : ",") + no.toString();
163         return rt;

164     }

165      
166

167

168

169

170

171

172

173 }

174

175

176

177

178

179

180
A classe ‘ArvoreBin’ contém a referência para a árvore binária (private Node arvore),
os métodos para inserir nós à direita e esquerda de um nó (nó pai) e forma de percurso
recursivo na árvore binária.

O método

1 private Node findNode(Node no, String nome){

têm por objetivo encontrar um nó na árvore por busca exaustiva, pois, o objetivo da
árvore não é ordenar a entrada de novos nós, mais sim permitir ao usuário inserir nós na
ordem e posição que desejar, pois a finalidade da estrutura é realizar o estudo das
formas de leitura de árvore binária: Pré, Em e Pós-Ordem.

E por fim a classe ‘Main’:

1 package arvore.main;

2  

3 import arvore.binary.ArvoreBin;

import arvore.binary.ArvoreBin.ModoRL;
4
 
5
/**
6
 * <b>Classe Main - Árvore binária</b>
7  

8  * Objetivo: estudar percurso em árvore binária.

9  * <ul>

 *  <li>Pré-Ordem: RED = <u>r</u>aiz, <u>e</u>squerda, <u>d</u>ireita</li>


10
 *  <li>In-Ordem: ERD = <u>e</u>squerda, <u>r</u>aiz, <u>d</u>ireita</li>
11
 *  <li>Pós-Ordem: EDR = <u>e</u>squerda, <u>d</u>ireita, <u>r</u>aiz</li>
12
 * </ul>
13
 *
14  * @author Emerson Shigueo Sugimoto 07/06/2015 11:41
15  *

16  */

17 public class Main {

18  

19     public static void main(String[] args) {

        System.out.println("-----------------------------------------");
20
        ArvoreBin arvore = new ArvoreBin("A");
21
         
22
        arvore.AdicionarNo("A","B", ModoRL.esquerda);
23
        arvore.AdicionarNo("B", "D", ModoRL.esquerda);
24
        arvore.AdicionarNo("A", "C", ModoRL.direita);
25         arvore.AdicionarNo("C", "E", ModoRL.esquerda);
26         arvore.AdicionarNo("E", "G", ModoRL.direita);
27         arvore.AdicionarNo("C", "F", ModoRL.direita);

28         arvore.AdicionarNo("F", "H", ModoRL.esquerda);

29         arvore.AdicionarNo("F", "I", ModoRL.direita);

30          

        System.out.println("PreOrdem (RED): " + arvore.PreOrdem());


31
        System.out.println("InOrdem (ERD): " + arvore.InOrdem());
32
        System.out.println("PosOrdem (EDR): " + arvore.PosOrdem());
33
        System.out.println("-----------------------------------------");
34
         
35
        arvore.Clear("F");
36
         
37
38         arvore.AdicionarNo("F","B", ModoRL.esquerda);

39         arvore.AdicionarNo("B","A", ModoRL.esquerda);

        arvore.AdicionarNo("B","D", ModoRL.direita);
40
        arvore.AdicionarNo("D","C", ModoRL.esquerda);
41
        arvore.AdicionarNo("D","E", ModoRL.direita);
42
        arvore.AdicionarNo("F","G", ModoRL.direita);
43
        arvore.AdicionarNo("G","I", ModoRL.direita);
44         arvore.AdicionarNo("I","H", ModoRL.esquerda);
45          
46         System.out.println("PreOrdem (RED): " + arvore.PreOrdem());

47         System.out.println("InOrdem (ERD): " + arvore.InOrdem());

48         System.out.println("PosOrdem (EDR): " + arvore.PosOrdem());

49         System.out.println("-----------------------------------------");

50          

        arvore.Clear("A");
51
         
52
        arvore.AdicionarNo("A","B", ModoRL.esquerda);
53
        arvore.AdicionarNo("B","C", ModoRL.esquerda);
54
        arvore.AdicionarNo("C","E", ModoRL.esquerda);
55
        arvore.AdicionarNo("E","I", ModoRL.direita);
56
        arvore.AdicionarNo("C","F", ModoRL.direita);
57         arvore.AdicionarNo("F","J", ModoRL.direita);
58         arvore.AdicionarNo("B","D", ModoRL.direita);

59         arvore.AdicionarNo("D","G", ModoRL.esquerda);

60         arvore.AdicionarNo("D","H", ModoRL.direita);

        arvore.AdicionarNo("H","K", ModoRL.esquerda);
61
        arvore.AdicionarNo("H","L", ModoRL.direita);
62
         
63
        System.out.println("PreOrdem (RED): " + arvore.PreOrdem());
64
        System.out.println("InOrdem (ERD): " + arvore.InOrdem());
65
        System.out.println("PosOrdem (EDR): " + arvore.PosOrdem());
66
        System.out.println("-----------------------------------------");
67     }
68
69

70

71

72
 
73 }
74 /*
75  
76     Saída

77     -----------------------------------------

78     PreOrdem (RED): A,B,D,C,E,G,F,H,I

    InOrdem (ERD): D,B,A,E,G,C,H,F,I


79
    PosOrdem (EDR): D,B,G,E,H,I,F,C,A
80
    -----------------------------------------
81
    PreOrdem (RED): F,B,A,D,C,E,G,I,H
82
    InOrdem (ERD): A,B,C,D,E,F,G,H,I
83     PosOrdem (EDR): A,C,E,D,B,H,I,G,F
84     -----------------------------------------
85     PreOrdem (RED): A,B,C,E,I,F,J,D,G,H,K,L

86     InOrdem (ERD): E,I,C,F,J,B,G,D,K,H,L,A

87     PosOrdem (EDR): I,E,J,F,C,G,K,L,H,D,B,A

    -----------------------------------------
88
 
89
*/
90

91

92

93
O resultado será:

—————————————–
PreOrdem (RED): A,B,D,C,E,G,F,H,I
InOrdem (ERD): D,B,A,E,G,C,H,F,I
PosOrdem (EDR): D,B,G,E,H,I,F,C,A
—————————————–
PreOrdem (RED): F,B,A,D,C,E,G,I,H
InOrdem (ERD): A,B,C,D,E,F,G,H,I
PosOrdem (EDR): A,C,E,D,B,H,I,G,F
—————————————–
PreOrdem (RED): A,B,C,E,I,F,J,D,G,H,K,L
InOrdem (ERD): E,I,C,F,J,B,G,D,K,H,L,A
PosOrdem (EDR): I,E,J,F,C,G,K,L,H,D,B,A
—————————————–

Um exemplo de inserção da árvore binária via código é:

1
arvore.Clear("F");
2
 
3 arvore.AdicionarNo("F","B", ModoRL.esquerda);
4 arvore.AdicionarNo("B","A", ModoRL.esquerda);
5 arvore.AdicionarNo("B","D", ModoRL.direita);

6 arvore.AdicionarNo("D","C", ModoRL.esquerda);

7 arvore.AdicionarNo("D","E", ModoRL.direita);

arvore.AdicionarNo("F","G", ModoRL.direita);
8
arvore.AdicionarNo("G","I", ModoRL.direita);
9
arvore.AdicionarNo("I","H", ModoRL.esquerda);
10

A leitura será:

1 System.out.println("PreOrdem (RED): " + arvore.PreOrdem());

2 System.out.println("InOrdem (ERD): " + arvore.InOrdem());

3 System.out.println("PosOrdem (EDR): " + arvore.PosOrdem());

—————————————–
PreOrdem (RED): F,B,A,D,C,E,G,I,H
InOrdem (ERD): A,B,C,D,E,F,G,H,I
PosOrdem (EDR): A,C,E,D,B,H,I,G,F
—————————————–

o código pode ser encontrado em: https://mega.co.nz/#!ZAAhVK7I!


HyO0CXrjpjFRyqO21CAKO1WrmL7EN9UAC13C4rawHiA
Anúncios
REPORT THIS AD

REPORT THIS AD

Share this:

 Twitter
 Facebook

Relacionado
Java MatrixEm "Java"
Enviar E-mail C#Em "C#"
Comparação entre JAVA e C++Em "Cpp"
Postado em Árvore Binária, Estruturas de Dados, Java, ProgramaçãoCom a tag árvore binária, Em
Ordem Pós Ordem, Java, percurso, Pré OrdemDeixe um comentário

Navegação de Posts
C++ Threads com Time To Live (TTL)

Você também pode gostar