SlideShare uma empresa Scribd logo
Estrutura de
Dados
Implementação da Arvore Binária
profa. Divani Barbosa
Aula 13 parte 2
2
É uma estrutura de dados caracterizada por:
 Ou não tem elemento algum (árvore vazia).
 Ou tem um elemento distinto, denominado raiz, com dois
apontamentos para dois elos diferentes, denominadas sub-
árvore esquerda e sub-árvore direita.
Arvore Binária
Exemplos:
a) b)
3
4
Arvores Balanceadas
 Uma arvore é considerada balanceada quando suas sub-
arvores a esquerda e a direita possuem a mesma altura.
 A arvore não balanceada é definida como degenerada.
Exemplos:
arvore binária
balanceada
arvore binária
degenerada
a) b)
5
Classe No
Uma arvore binária precisa de uma classe de
objetos Nós, assim como vimos na lista
duplamente encadeada:
class No {
public long item;
public No esq;
public No dir;
}
espaço para armazenamento da
informação (chave)
Um espaço para armazenar uma
referência da localização na
memória onde o Nó a esquerda
se encontra.
Um espaço para armazenar a
referência do Nó a direita.
6
Nó
esq =
dir =
item = 14
Nó
esq =
dir =
item = 4
Nó
esq =
dir =
item = 16
Nó
esq = NULL
dir = NULL
item = 3
Nó
esq = NULL
dir = NULL
item = 9
Nó
esq = NULL
dir = NULL
item = 15
Nó
esq = NULL
dir = NULL
item = 18
As referencias
são para outras
sub-arvores
root
Elos de uma arvore binária
7
Nó
esq =
dir =
item = 14
Nó
esq =
dir =
item = 4
Nó
esq =
dir =
item = 16
Nó
esq = NULL
dir = NULL
item = 3
Nó
esq = NULL
dir = NULL
item = 9
Nó
esq = NULL
dir = NULL
item = 15
Nó
esq = NULL
dir = NULL
item = 18
root = null
A árvore pode não ter nenhum elemento (árvore vazia)
Elos de uma arvore binária
8
Implementação
private No root;
Classe Tree:
Campo Construtor
public Tree() { root=null; }
Métodos
inserir: Insere itens na arvore
buscar: Retorna Nó procurado ou null
remover: Retorna verdadeiro se removeu item
no_sucessor: Retorna o Nó sucessor ao passado no
parâmetro
caminhar: (inOrder, preOrder, posOrder, altura,
folhas, min, max, contarNos)
Método: inserir
A inserção começa com a chave sendo atribuida a raiz,
logo após a função começa com uma busca, a-partir da
raiz, comparando a chave com o valor da raiz. Se a
chave é menor ou igual do que a raiz, ela é
introduzida num novo nó a esquerda da raiz, ou na
direita caso a chave seja maior que a raiz, e assim
sucessivamente, item a item, os nós são criados.
Exemplo:
Itens a serem adicionados:
25, 11, 42, 6, 19, 37 e 14
Método: inserir
public void inserir(long v) {
No novo = new No();
novo.item = v;
novo.dir = null;
novo.esq = null;
if (root == null)
root = novo;
else {
// inserir aqui
// trecho de código
// para tratamento
// caso árvore não vazia
}
}
Entrada: item que deseja inserir Saída: não há
Criando objeto Nó e
armazenando na referencia
novo
se arvore vazia
No atual = root;
No anterior;
while (true) {
anterior = atual;
if (v <= atual.item) {
atual = atual.esq;
if (atual == null) {
anterior.esq = novo;
return; }
}
else {
atual = atual.dir;
if (atual == null) {
anterior.dir = novo;
return; }
}
} // fim do laço while
trecho de código para tratamento caso não raiz (arvore não vazia)
começa a procurar desde raiz
Adiciona a esquerda
e sai
Adiciona a direita
e sai
Caminha para esquerda
Caminha para direita
Guarda o Nó anterior
12
Método: buscar
public No buscar(long chave) {
if (root == null) return null;
No atual = root;
while (atual.item != chave) {
if (chave < atual.item )
atual = atual.esq;
else
atual = atual.dir;
if (atual == null)
return null;
}
return atual;
}
Entrada: chave
Saída: Nó que procura ou null caso não encontre a chave
começa a procurar desde raiz
se arvore vazia
enquanto nao encontrou
caminha para esquerda
caminha para direita
encontrou uma folha -> sai
Saiu do laço while e chegou
aqui é porque encontrou item
Método: remover
O processo de exclusão de um nó é o mais complexo.
Para excluir um nó de uma árvore binária, deve-se
considerar três casos distintos:
Remoção da folha
A exclusão de um nó que se encontra no fim da árvore, isto é, na
folha, é o caso mais simples de exclusão. Basta remover o nó da
árvore
14
Remoção de um nó com “filho”
Caso o nó que será excluído tenha um único "filho", o "avô"
herda o "filho".
15
Remoção de um nó com dois “filhos”
Se o nó a ser excluído tiver dois "filhos", o processo de
exclusão poderá operar de duas maneiras diferentes:
Substituir o valor do nó a ser retirado pelo valor sucessor (o
nó mais à esquerda da sub-árvore direita).
Método: remover
public boolean remover(long v) {
if (root == null) return false;
No atual = root;
No pai = root;
boolean filho_esq = true;
while ( atual.item != v) {
pai = atual;
if ( v < atual.item ) {
atual = atual.esq;
filho_esq = true;
} else {
atual = atual.dir;
filho_esq = false;
}
if (atual == null) return false;
} // fim laço while busca
Entrada: item que deseja remover
Saída: verdadeiro ou falso
Enquanto não encontrou
Caminha a esquerda
Caminha a direita
Chegou em uma folha
public boolean remover(long v) {
if (root == null) return false;
No atual = root;
No pai = root;
boolean filho_esq = true;
while ( atual.item != v) {
pai = atual;
if ( v < atual.item ) {
atual = atual.esq;
filho_esq = true;
} else {
atual = atual.dir;
filho_esq = false;
}
if (atual == null) return false;
} // fim laço while busca
Método: remover
Entrada: item que deseja remover
Saída: verdadeiro ou falso
Se terminou o laço de busca
sem sair do método remover
quer dizer que:
 Encontrou o valor (v)
 "atual": contem a
referencia ao No a ser
eliminado
 "pai": contem a
referencia para o pai do
No a ser eliminado
 "filho_esq": é
verdadeiro se atual é filho
a esquerda do pai
Método: remover
Entrada: item que deseja remover
Saída: verdadeiro ou falso
atual.item =
pai.item =
filho_esq =
atual.item = 11
pai.item = 25
filho_esq = true
public boolean remover(long v) {
if (root == null) return false;
No atual = root;
No pai = root;
boolean filho_esq = true;
while ( atual.item != v) {
pai = atual;
if ( v < atual.item ) {
atual = atual.esq;
filho_esq = true;
} else {
atual = atual.dir;
filho_esq = false;
}
if (atual == null) return false;
} // fim laço while busca
if (atual.esq == null && atual.dir == null)
{
if (atual == root ) root = null;
else if (filho_esq) pai.esq = null;
else pai.dir = null;
}
Eliminando uma folha
atual.item = 6
pai.item = 11
filho_esq = true
Se não possui nenhum filho (é uma folha), elimine-o
Se é pai e não possui filho a direita
atual.item = 19
pai.item = 11
filho_esq = false
Substitui pela sub-árvore a direita
else if (atual.dir == null) {
if (atual == root) root = atual.esq;
else if (filho_esq) pai.esq = atual.esq;
else pai.dir = atual.esq;
}
pai.dir
atual.esq
Se é pai e não possui filho a esquerda
atual.item = 6
pai.item = 11
filho_esq = true
Substitui pela sub-árvore a esquerda
else if (atual.esq == null) {
if (atual == root) root = atual.dir;
else if (filho_esq) pai.esq = atual.dir;
else pai.dir = atual.dir;
}
pai.esq
atual.dir
Se possui mais de um filho
Se for um avô ou outro grau maior de parentesco
else {
No sucessor = no_sucessor(atual);
if (atual == root) root = sucessor;
else if (filho_esq) pai.esq = sucessor;
else pai.dir = sucessor;
sucessor.esq = atual.esq;
}
return true; // removeu item retorna true
} // fim método remover
Usando sucessor que seria a referencia ao Nó mais a esquerda da sub-
árvore a direita do Nó que deseja-se remover
No sucessor = no_sucessor(atual);
if (atual == root) root = sucessor;
else if (filho_esq) pai.esq = sucessor;
else pai.dir = sucessor;
sucessor.esq = atual.esq;
Trecho de código
atual.item = 11
pai.item = 25
filho_esq = true
1
2
3
4
5
public No no_sucessor(No apaga) {
No paidosucessor = apaga;
No sucessor = apaga;
No atual = apaga.dir;
while (atual != null) {
paidosucessor = sucessor;
sucessor = atual;
atual = atual.esq;
}
if (sucessor != apaga.dir) {
paidosucessor.esq = sucessor.dir;
sucessor.dir = apaga.dir;
}
return sucessor;
}
Método: no_sucessor
Retorno:
apaga
paisucessor
sucessor
atual
Entrada:
public No no_sucessor(No apaga) {
No paidosucessor = apaga;
No sucessor = apaga;
No atual = apaga.dir;
while (atual != null) {
paidosucessor = sucessor;
sucessor = atual;
atual = atual.esq;
}
if (sucessor != apaga.dir) {
paidosucessor.esq = sucessor.dir;
sucessor.dir = apaga.dir;
}
return sucessor;
}
Método: no_sucessor
Retorno:
apaga
sucessor
atual
paisucessor
sucessor
atual
Entrada:
paisucessor
public No no_sucessor(No apaga) {
No paidosucessor = apaga;
No sucessor = apaga;
No atual = apaga.dir;
while (atual != null) {
paidosucessor = sucessor;
sucessor = atual;
atual = atual.esq;
}
if (sucessor != apaga.dir) {
paidosucessor.esq = sucessor.dir;
sucessor.dir = apaga.dir;
}
return sucessor;
}
Método: no_sucessor
Retorno:
apaga
sucessor
atual
paisucessor
sucessor
atual
Entrada:
paisucessor
sucessor
atual = null
true
public No no_sucessor(No apaga) {
No paidosucessor = apaga;
No sucessor = apaga;
No atual = apaga.dir;
while (atual != null) {
paidosucessor = sucessor;
sucessor = atual;
atual = atual.esq;
}
if (sucessor != apaga.dir) {
paidosucessor.esq = sucessor.dir;
sucessor.dir = apaga.dir;
}
return sucessor;
}
Método: no_sucessor
Retorno:
apaga
sucessor
atual
paisucessor
sucessor
atual
sucessor
atual = null
Entrada:
true
paisucessor
sucessor
public No no_sucessor(No apaga) {
No paidosucessor = apaga;
No sucessor = apaga;
No atual = apaga.dir;
while (atual != null) {
paidosucessor = sucessor;
sucessor = atual;
atual = atual.esq;
}
if (sucessor != apaga.dir) {
paidosucessor.esq = sucessor.dir;
sucessor.dir = apaga.dir;
}
return sucessor;
}
Método: no_sucessor
Retorno:
apaga
sucessor
atual
paisucessor
sucessor
atual = null
Entrada:
true
paisucessor
sucessor
null
public No no_sucessor(No apaga) {
No paidosucessor = apaga;
No sucessor = apaga;
No atual = apaga.dir;
while (atual != null) {
paidosucessor = sucessor;
sucessor = atual;
atual = atual.esq;
}
if (sucessor != apaga.dir) {
paidosucessor.esq = sucessor.dir;
sucessor.dir = apaga.dir;
}
return sucessor;
}
Método: no_sucessor
sucessor
apaga
paisucessor
sucessor
atual
paisucessor
sucessor
atual = null
Entrada:
true
null
apaga.dir
Retorno:
atual.item = 11
pai.item = 25
filho_esq = true
pai.esq
No sucessor = no_sucessor(atual);
if (atual == root) root = sucessor;
else if (filho_esq) pai.esq = sucessor;
else pai.dir = sucessor;
sucessor.esq = atual.esq;
Trecho de código
1
2
3
4
5
sucessor
pai.esq = sucessor
Linha 3:
atual.esq
atual.item = 11
pai.item = 25
filho_esq = true
pai.esq
atual.esq
Trecho de código
1
2
3
4
5
pai.esq = sucessor
Linha 3:
sucessor
No sucessor = no_sucessor(atual);
if (atual == root) root = sucessor;
else if (filho_esq) pai.esq = sucessor;
else pai.dir = sucessor;
sucessor.esq = atual.esq;
pai.esq
atual.esq
Trecho de código
1
2
3
4
5
pai.esq= sucessor
Linha 3: Linha 5:
sucessor.esq =
atual.esq
sucessor sucessor
No sucessor = no_sucessor(atual);
if (atual == root) root = sucessor;
else if (filho_esq) pai.esq = sucessor;
else pai.dir = sucessor;
sucessor.esq = atual.esq;
public No no_sucessor(No apaga) {
No paidosucessor = apaga;
No sucessor = apaga;
No atual = apaga.dir;
while (atual != null) {
paidosucessor = sucessor;
sucessor = atual;
atual = atual.esq;
}
if (sucessor != apaga.dir) {
paidosucessor.esq = sucessor.dir;
sucessor.dir = apaga.dir;
}
return sucessor;
}
Método: no_sucessor
Vai para a sub-
arvore a direita
Caminha para o Nó
mais a esquerda
Se sucessor não é
o filho a direita do
Nó que deverá ser
eliminado
Pai herda os filhos
do sucessor que
sempre serão a
direita
Guardando a
referencia a direita
do sucessor para
quando ele
assumir a posição
correta na arvore
34
Método: caminhar
public void caminhar() {
System.out.print("n Exibindo em ordem: ");
inOrder(root);
System.out.print("n Exibindo em pos-ordem: ");
posOrder(root);
System.out.print("n Exibindo em pre-ordem: ");
preOrder(root);
System.out.print("n Altura da arvore: " + altura(root));
System.out.print("n Quantidade de folhas: " + folhas(root));
System.out.print("n Quantidade de Nós: " + contarNos(root));
if (root != null ) { // se arvore nao esta vazia
System.out.print("n Valor minimo: " + min().item);
System.out.println("n Valor maximo: " + max().item);
}
}
Chamada a métodos recursivos
Entrada: Não há
Saída: Não tem
35
Método: inOrder
public void inOrder(No atual) {
if (atual != null) {
inOrder(atual.esq);
System.out.print(atual.item + " ");
inOrder(atual.dir);
}
}
Primeiro visita o Nó a esquerda, depois a raiz (imprime o
item), finalizando com o Nó a direita.
Entrada: O Nó raiz
Saída: Não tem retorno
36
Método: posOrder
public void posOrder(No atual) {
if (atual != null) {
posOrder(atual.esq);
posOrder(atual.dir);
System.out.print(atual.item + " ");
}
}
Primeiro visita o Nó a esquerda, depois o Nó a direita,
finalizando com a raiz (imprime o item).
Entrada: O Nó raiz
Saída: Não tem retorno
37
Método: preOrder
public void preOrder(No atual) {
if (atual != null) {
System.out.print(atual.item + " ");
preOrder(atual.esq);
preOrder(atual.dir);
}
}
Primeiro visita a raiz (imprime o item), depois o Nó a
esquerda, finalizando com o Nó a direita.
Entrada: O Nó raiz
Saída: Não tem retorno
38
Método: folhas
public int folhas(No atual) {
if (atual == null) return 0;
if (atual.esq == null && atual.dir == null)
return 1;
return folhas(atual.esq) + folhas(atual.dir);
}
Entrada: O Nó raiz
Saída: Numero de folhas da arvore
39
Método: folhas
public int folhas(No atual) {
if (atual == null) return 0;
if (atual.esq == null && atual.dir == null)
return 1;
return folhas(atual.esq) + folhas(atual.dir);
}
Entrada: O Nó raiz
Saída: Numero de folhas da arvore
A arvore não possui itens ou chegou no final e não encontrou mais nenhum item
retorna zero
Retorne chamada recursiva da função contando a quantidade de folhas a
esquerda mais a direita da arvore
Se encontrou somente um item (raiz) ou chegou em uma folha,
retorna 1
40
Método: contarNos
public int contarNos(No atual) {
if (atual == null)
return 0;
else
return ( 1 + contarNos(atual.esq) +
contarNos(atual.dir) );
}
Entrada: O Nó raiz
Saída: Numero de Nós
Arvore vazia ou chegou no final e não encontrou mais nenhum item retorna zero
Senão retorne o valor 1 + chamada recursiva da função
contando a quantidade de nós a esquerda mais a direita da
arvore
41
Método: min
public No min() {
No atual = root;
No anterior = null;
while (atual != null) {
anterior = atual;
atual = atual.esq;
}
return anterior;
}
Entrada: não há
Saída: No mais a esquerda (Nó mínimo)
42
Método: min
public No min() {
No atual = root;
No anterior = null;
while (atual != null) {
anterior = atual;
atual = atual.esq;
}
return anterior;
}
Entrada: não há
Saída: No mais a esquerda (Nó mínimo)
Começa na raiz
Enquanto não encontrar um Nó
igual a null
Guarda o Nó anterior
Caminha para o filho a esquerda
43
Método: max
public No max() {
No atual = root;
No anterior = null;
while (atual != null) {
anterior = atual;
atual = atual.dir;
}
return anterior;
}
Entrada: não há
Saída: No mais a direita (Nó máximo)
44
Método: max
public No max() {
No atual = root;
No anterior = null;
while (atual != null) {
anterior = atual;
atual = atual.dir;
}
return anterior;
}
Entrada: não há
Saída: No mais a direita (Nó máximo)
Começa na raiz
Enquanto não encontrar um Nó
igual a null
Guarda o Nó anterior
Caminha para o filho a direita
Exemplo de uso da classe Tree:
class TreeBinApp {
public static void main(String[] args) {
Scanner le = new Scanner(System.in);
Tree arv = new Tree();
int opcao;
long x;
System.out.print("n Programa Arvore binaria de long");
do {
System.out.print("n***********************************");
System.out.print("nEntre com a opcao:");
System.out.print("n ----1: Inserir");
System.out.print("n ----2: Excluir");
System.out.print("n ----3: Pesquisar");
System.out.print("n ----4: Exibir");
System.out.print("n ----5: Sair do programa");
System.out.print("n***********************************");
System.out.print("n-> ");
opcao = le.nextInt();
switch(opcao) {
case 1: {
System.out.print("n Informe o valor (long) -> ");
x = le.nextLong();
x = le.nextLong();
arv.inserir(x);
break;
}
case 2: {
System.out.print("n Informe o valor (long) -> ");
x = le.nextLong();
if ( !arv.remover(x) )
System.out.print("n Valor nao encontrado!");;
break;
}
case 3: {
System.out.print("n Informe o valor (long) -> ");
x = le.nextLong();
if( arv.buscar(x) != null )
System.out.print("n Valor Encontrado");
else
System.out.print("n Valor nao encontrado!");
break;
}
case 4: {
arv.caminhar();
break;
}
} // fim switch
} while(opcao != 5);
}
}
https://gist.github.com/divanibarbosa/819e7cfcf1b9bae48c4e0f5bd74fb658
48
Atividades
1. No código Java para uma árvore, o ________ e a ________
são geralmente classes separadas.
.2. Uma sub-árvore de uma árvore binária sempre tem
(a) Uma raiz que é um filho da raiz da árvore principal
(b) Uma raiz não conectada a raiz da árvore principal
(c) Menos Nós que a árvore principal
(d) Uma irmã com mesmo número de Nós
3. Verdadeiro ou falso:
(a) Eliminar um Nó com um filho de uma árvore binária de busca envolve
encontrar o sucessor desse Nó.
(b) Nem todas as árvores são binárias.
(c) Uma árvore não balanceada é uma árvore na qual a raiz ou algum
outro Nó tenha muito mais filhos à esquerda do que filhos à direita ou
vice-versa.
49
Atividades
4. Trabalho 2 - Exercício 6. Desenhe uma arvore binária
usando a seguinte sequencia de dados de entrada:
(a) 25, 11, 42, 6, 19, 37 e 14
(b) 11, 22, 33, 44, -11, -33 e -22
(c) 14, 4, 15, 3, 9, 13, 18, 7, 11, 16, 20, 5, 17, 4 e 5
Responda: Quantas folhas, nós e qual a altura das arvores (a), (b) e (c).
Escreva a arvore (b) e (c) em pré-ordem e pós-ordem.
Desenhe as arvores (a), (b) e (c) depois da inserção do nó 21 e da
remoção do nó 11 para as arvores (a) e (b) e nó 18 para arvore (c).
5. Desenvolva um programa árvore binária de:
(a) double
(b) caracteres
(c) strings
50
Atividades
6. Desenvolva um programa árvore binária para um objeto
que represente uma agenda telefônica, use o nome como
campo chave

Mais conteúdo relacionado

Semelhante a Aula 19

Aula 17
Aula 17Aula 17
Aula 15
Aula 15Aula 15
Estrutura de Dados - Listas Encadeadas
Estrutura de Dados - Listas EncadeadasEstrutura de Dados - Listas Encadeadas
Estrutura de Dados - Listas Encadeadas
Adriano Teixeira de Souza
 
Estrutura de dados em Java - Filas
Estrutura de dados em Java - FilasEstrutura de dados em Java - Filas
Estrutura de dados em Java - Filas
Adriano Teixeira de Souza
 
Estruturas de Dados - Árvores Binárias (Binary Tree) - Parte 2
Estruturas de Dados - Árvores Binárias (Binary Tree) - Parte 2Estruturas de Dados - Árvores Binárias (Binary Tree) - Parte 2
Estruturas de Dados - Árvores Binárias (Binary Tree) - Parte 2
Erick Petrucelli
 
Aula 12
Aula 12Aula 12
Arvores b
Arvores bArvores b

Semelhante a Aula 19 (7)

Aula 17
Aula 17Aula 17
Aula 17
 
Aula 15
Aula 15Aula 15
Aula 15
 
Estrutura de Dados - Listas Encadeadas
Estrutura de Dados - Listas EncadeadasEstrutura de Dados - Listas Encadeadas
Estrutura de Dados - Listas Encadeadas
 
Estrutura de dados em Java - Filas
Estrutura de dados em Java - FilasEstrutura de dados em Java - Filas
Estrutura de dados em Java - Filas
 
Estruturas de Dados - Árvores Binárias (Binary Tree) - Parte 2
Estruturas de Dados - Árvores Binárias (Binary Tree) - Parte 2Estruturas de Dados - Árvores Binárias (Binary Tree) - Parte 2
Estruturas de Dados - Árvores Binárias (Binary Tree) - Parte 2
 
Aula 12
Aula 12Aula 12
Aula 12
 
Arvores b
Arvores bArvores b
Arvores b
 

Mais de Divani Barbosa

Banco de Dados MySQL + NetBeans Java + Interface Grafica
Banco de Dados MySQL + NetBeans Java + Interface GraficaBanco de Dados MySQL + NetBeans Java + Interface Grafica
Banco de Dados MySQL + NetBeans Java + Interface Grafica
Divani Barbosa
 
Aula 22
Aula 22Aula 22
Aula 21
Aula 21Aula 21
Aula 20
Aula 20Aula 20
Aula 16
Aula 16Aula 16
Aula14
Aula14Aula14
Aula 13
Aula 13Aula 13
Aula 11
Aula 11Aula 11
Aula 10
Aula 10 Aula 10
Aula 10
Divani Barbosa
 
Aula 9
Aula 9Aula 9
Aula 8
Aula 8Aula 8
Aula 7
Aula 7 Aula 7
Aula 6
Aula 6Aula 6
Aula 5
Aula 5 Aula 5
Aula 4
Aula 4 Aula 4
Aula 3
Aula 3Aula 3
Aula 2
Aula 2Aula 2
Aula 1
Aula 1Aula 1

Mais de Divani Barbosa (18)

Banco de Dados MySQL + NetBeans Java + Interface Grafica
Banco de Dados MySQL + NetBeans Java + Interface GraficaBanco de Dados MySQL + NetBeans Java + Interface Grafica
Banco de Dados MySQL + NetBeans Java + Interface Grafica
 
Aula 22
Aula 22Aula 22
Aula 22
 
Aula 21
Aula 21Aula 21
Aula 21
 
Aula 20
Aula 20Aula 20
Aula 20
 
Aula 16
Aula 16Aula 16
Aula 16
 
Aula14
Aula14Aula14
Aula14
 
Aula 13
Aula 13Aula 13
Aula 13
 
Aula 11
Aula 11Aula 11
Aula 11
 
Aula 10
Aula 10 Aula 10
Aula 10
 
Aula 9
Aula 9Aula 9
Aula 9
 
Aula 8
Aula 8Aula 8
Aula 8
 
Aula 7
Aula 7 Aula 7
Aula 7
 
Aula 6
Aula 6Aula 6
Aula 6
 
Aula 5
Aula 5 Aula 5
Aula 5
 
Aula 4
Aula 4 Aula 4
Aula 4
 
Aula 3
Aula 3Aula 3
Aula 3
 
Aula 2
Aula 2Aula 2
Aula 2
 
Aula 1
Aula 1Aula 1
Aula 1
 

Último

Certificado Jornada Python Da Hashtag.pdf
Certificado Jornada Python Da Hashtag.pdfCertificado Jornada Python Da Hashtag.pdf
Certificado Jornada Python Da Hashtag.pdf
joaovmp3
 
Manual-de-Credenciamento ANATER 2023.pdf
Manual-de-Credenciamento ANATER 2023.pdfManual-de-Credenciamento ANATER 2023.pdf
Manual-de-Credenciamento ANATER 2023.pdf
WELITONNOGUEIRA3
 
DESENVOLVIMENTO DE SOFTWARE I_aula1-2.pdf
DESENVOLVIMENTO DE SOFTWARE I_aula1-2.pdfDESENVOLVIMENTO DE SOFTWARE I_aula1-2.pdf
DESENVOLVIMENTO DE SOFTWARE I_aula1-2.pdf
Momento da Informática
 
História da Rádio- 1936-1970 século XIX .2.pptx
História da Rádio- 1936-1970 século XIX   .2.pptxHistória da Rádio- 1936-1970 século XIX   .2.pptx
História da Rádio- 1936-1970 século XIX .2.pptx
TomasSousa7
 
TOO - TÉCNICAS DE ORIENTAÇÃO A OBJETOS aula 1.pdf
TOO - TÉCNICAS DE ORIENTAÇÃO A OBJETOS aula 1.pdfTOO - TÉCNICAS DE ORIENTAÇÃO A OBJETOS aula 1.pdf
TOO - TÉCNICAS DE ORIENTAÇÃO A OBJETOS aula 1.pdf
Momento da Informática
 
Logica de Progamacao - Aula (1) (1).pptx
Logica de Progamacao - Aula (1) (1).pptxLogica de Progamacao - Aula (1) (1).pptx
Logica de Progamacao - Aula (1) (1).pptx
Momento da Informática
 

Último (6)

Certificado Jornada Python Da Hashtag.pdf
Certificado Jornada Python Da Hashtag.pdfCertificado Jornada Python Da Hashtag.pdf
Certificado Jornada Python Da Hashtag.pdf
 
Manual-de-Credenciamento ANATER 2023.pdf
Manual-de-Credenciamento ANATER 2023.pdfManual-de-Credenciamento ANATER 2023.pdf
Manual-de-Credenciamento ANATER 2023.pdf
 
DESENVOLVIMENTO DE SOFTWARE I_aula1-2.pdf
DESENVOLVIMENTO DE SOFTWARE I_aula1-2.pdfDESENVOLVIMENTO DE SOFTWARE I_aula1-2.pdf
DESENVOLVIMENTO DE SOFTWARE I_aula1-2.pdf
 
História da Rádio- 1936-1970 século XIX .2.pptx
História da Rádio- 1936-1970 século XIX   .2.pptxHistória da Rádio- 1936-1970 século XIX   .2.pptx
História da Rádio- 1936-1970 século XIX .2.pptx
 
TOO - TÉCNICAS DE ORIENTAÇÃO A OBJETOS aula 1.pdf
TOO - TÉCNICAS DE ORIENTAÇÃO A OBJETOS aula 1.pdfTOO - TÉCNICAS DE ORIENTAÇÃO A OBJETOS aula 1.pdf
TOO - TÉCNICAS DE ORIENTAÇÃO A OBJETOS aula 1.pdf
 
Logica de Progamacao - Aula (1) (1).pptx
Logica de Progamacao - Aula (1) (1).pptxLogica de Progamacao - Aula (1) (1).pptx
Logica de Progamacao - Aula (1) (1).pptx
 

Aula 19

  • 1. Estrutura de Dados Implementação da Arvore Binária profa. Divani Barbosa Aula 13 parte 2
  • 2. 2 É uma estrutura de dados caracterizada por:  Ou não tem elemento algum (árvore vazia).  Ou tem um elemento distinto, denominado raiz, com dois apontamentos para dois elos diferentes, denominadas sub- árvore esquerda e sub-árvore direita. Arvore Binária Exemplos: a) b)
  • 3. 3
  • 4. 4 Arvores Balanceadas  Uma arvore é considerada balanceada quando suas sub- arvores a esquerda e a direita possuem a mesma altura.  A arvore não balanceada é definida como degenerada. Exemplos: arvore binária balanceada arvore binária degenerada a) b)
  • 5. 5 Classe No Uma arvore binária precisa de uma classe de objetos Nós, assim como vimos na lista duplamente encadeada: class No { public long item; public No esq; public No dir; } espaço para armazenamento da informação (chave) Um espaço para armazenar uma referência da localização na memória onde o Nó a esquerda se encontra. Um espaço para armazenar a referência do Nó a direita.
  • 6. 6 Nó esq = dir = item = 14 Nó esq = dir = item = 4 Nó esq = dir = item = 16 Nó esq = NULL dir = NULL item = 3 Nó esq = NULL dir = NULL item = 9 Nó esq = NULL dir = NULL item = 15 Nó esq = NULL dir = NULL item = 18 As referencias são para outras sub-arvores root Elos de uma arvore binária
  • 7. 7 Nó esq = dir = item = 14 Nó esq = dir = item = 4 Nó esq = dir = item = 16 Nó esq = NULL dir = NULL item = 3 Nó esq = NULL dir = NULL item = 9 Nó esq = NULL dir = NULL item = 15 Nó esq = NULL dir = NULL item = 18 root = null A árvore pode não ter nenhum elemento (árvore vazia) Elos de uma arvore binária
  • 8. 8 Implementação private No root; Classe Tree: Campo Construtor public Tree() { root=null; } Métodos inserir: Insere itens na arvore buscar: Retorna Nó procurado ou null remover: Retorna verdadeiro se removeu item no_sucessor: Retorna o Nó sucessor ao passado no parâmetro caminhar: (inOrder, preOrder, posOrder, altura, folhas, min, max, contarNos)
  • 9. Método: inserir A inserção começa com a chave sendo atribuida a raiz, logo após a função começa com uma busca, a-partir da raiz, comparando a chave com o valor da raiz. Se a chave é menor ou igual do que a raiz, ela é introduzida num novo nó a esquerda da raiz, ou na direita caso a chave seja maior que a raiz, e assim sucessivamente, item a item, os nós são criados. Exemplo: Itens a serem adicionados: 25, 11, 42, 6, 19, 37 e 14
  • 10. Método: inserir public void inserir(long v) { No novo = new No(); novo.item = v; novo.dir = null; novo.esq = null; if (root == null) root = novo; else { // inserir aqui // trecho de código // para tratamento // caso árvore não vazia } } Entrada: item que deseja inserir Saída: não há Criando objeto Nó e armazenando na referencia novo se arvore vazia
  • 11. No atual = root; No anterior; while (true) { anterior = atual; if (v <= atual.item) { atual = atual.esq; if (atual == null) { anterior.esq = novo; return; } } else { atual = atual.dir; if (atual == null) { anterior.dir = novo; return; } } } // fim do laço while trecho de código para tratamento caso não raiz (arvore não vazia) começa a procurar desde raiz Adiciona a esquerda e sai Adiciona a direita e sai Caminha para esquerda Caminha para direita Guarda o Nó anterior
  • 12. 12 Método: buscar public No buscar(long chave) { if (root == null) return null; No atual = root; while (atual.item != chave) { if (chave < atual.item ) atual = atual.esq; else atual = atual.dir; if (atual == null) return null; } return atual; } Entrada: chave Saída: Nó que procura ou null caso não encontre a chave começa a procurar desde raiz se arvore vazia enquanto nao encontrou caminha para esquerda caminha para direita encontrou uma folha -> sai Saiu do laço while e chegou aqui é porque encontrou item
  • 13. Método: remover O processo de exclusão de um nó é o mais complexo. Para excluir um nó de uma árvore binária, deve-se considerar três casos distintos: Remoção da folha A exclusão de um nó que se encontra no fim da árvore, isto é, na folha, é o caso mais simples de exclusão. Basta remover o nó da árvore
  • 14. 14 Remoção de um nó com “filho” Caso o nó que será excluído tenha um único "filho", o "avô" herda o "filho".
  • 15. 15 Remoção de um nó com dois “filhos” Se o nó a ser excluído tiver dois "filhos", o processo de exclusão poderá operar de duas maneiras diferentes: Substituir o valor do nó a ser retirado pelo valor sucessor (o nó mais à esquerda da sub-árvore direita).
  • 16. Método: remover public boolean remover(long v) { if (root == null) return false; No atual = root; No pai = root; boolean filho_esq = true; while ( atual.item != v) { pai = atual; if ( v < atual.item ) { atual = atual.esq; filho_esq = true; } else { atual = atual.dir; filho_esq = false; } if (atual == null) return false; } // fim laço while busca Entrada: item que deseja remover Saída: verdadeiro ou falso Enquanto não encontrou Caminha a esquerda Caminha a direita Chegou em uma folha
  • 17. public boolean remover(long v) { if (root == null) return false; No atual = root; No pai = root; boolean filho_esq = true; while ( atual.item != v) { pai = atual; if ( v < atual.item ) { atual = atual.esq; filho_esq = true; } else { atual = atual.dir; filho_esq = false; } if (atual == null) return false; } // fim laço while busca Método: remover Entrada: item que deseja remover Saída: verdadeiro ou falso Se terminou o laço de busca sem sair do método remover quer dizer que:  Encontrou o valor (v)  "atual": contem a referencia ao No a ser eliminado  "pai": contem a referencia para o pai do No a ser eliminado  "filho_esq": é verdadeiro se atual é filho a esquerda do pai
  • 18. Método: remover Entrada: item que deseja remover Saída: verdadeiro ou falso atual.item = pai.item = filho_esq = atual.item = 11 pai.item = 25 filho_esq = true public boolean remover(long v) { if (root == null) return false; No atual = root; No pai = root; boolean filho_esq = true; while ( atual.item != v) { pai = atual; if ( v < atual.item ) { atual = atual.esq; filho_esq = true; } else { atual = atual.dir; filho_esq = false; } if (atual == null) return false; } // fim laço while busca
  • 19. if (atual.esq == null && atual.dir == null) { if (atual == root ) root = null; else if (filho_esq) pai.esq = null; else pai.dir = null; } Eliminando uma folha atual.item = 6 pai.item = 11 filho_esq = true Se não possui nenhum filho (é uma folha), elimine-o
  • 20. Se é pai e não possui filho a direita atual.item = 19 pai.item = 11 filho_esq = false Substitui pela sub-árvore a direita else if (atual.dir == null) { if (atual == root) root = atual.esq; else if (filho_esq) pai.esq = atual.esq; else pai.dir = atual.esq; } pai.dir atual.esq
  • 21. Se é pai e não possui filho a esquerda atual.item = 6 pai.item = 11 filho_esq = true Substitui pela sub-árvore a esquerda else if (atual.esq == null) { if (atual == root) root = atual.dir; else if (filho_esq) pai.esq = atual.dir; else pai.dir = atual.dir; } pai.esq atual.dir
  • 22. Se possui mais de um filho Se for um avô ou outro grau maior de parentesco else { No sucessor = no_sucessor(atual); if (atual == root) root = sucessor; else if (filho_esq) pai.esq = sucessor; else pai.dir = sucessor; sucessor.esq = atual.esq; } return true; // removeu item retorna true } // fim método remover Usando sucessor que seria a referencia ao Nó mais a esquerda da sub- árvore a direita do Nó que deseja-se remover
  • 23. No sucessor = no_sucessor(atual); if (atual == root) root = sucessor; else if (filho_esq) pai.esq = sucessor; else pai.dir = sucessor; sucessor.esq = atual.esq; Trecho de código atual.item = 11 pai.item = 25 filho_esq = true 1 2 3 4 5
  • 24. public No no_sucessor(No apaga) { No paidosucessor = apaga; No sucessor = apaga; No atual = apaga.dir; while (atual != null) { paidosucessor = sucessor; sucessor = atual; atual = atual.esq; } if (sucessor != apaga.dir) { paidosucessor.esq = sucessor.dir; sucessor.dir = apaga.dir; } return sucessor; } Método: no_sucessor Retorno: apaga paisucessor sucessor atual Entrada:
  • 25. public No no_sucessor(No apaga) { No paidosucessor = apaga; No sucessor = apaga; No atual = apaga.dir; while (atual != null) { paidosucessor = sucessor; sucessor = atual; atual = atual.esq; } if (sucessor != apaga.dir) { paidosucessor.esq = sucessor.dir; sucessor.dir = apaga.dir; } return sucessor; } Método: no_sucessor Retorno: apaga sucessor atual paisucessor sucessor atual Entrada: paisucessor
  • 26. public No no_sucessor(No apaga) { No paidosucessor = apaga; No sucessor = apaga; No atual = apaga.dir; while (atual != null) { paidosucessor = sucessor; sucessor = atual; atual = atual.esq; } if (sucessor != apaga.dir) { paidosucessor.esq = sucessor.dir; sucessor.dir = apaga.dir; } return sucessor; } Método: no_sucessor Retorno: apaga sucessor atual paisucessor sucessor atual Entrada: paisucessor sucessor atual = null true
  • 27. public No no_sucessor(No apaga) { No paidosucessor = apaga; No sucessor = apaga; No atual = apaga.dir; while (atual != null) { paidosucessor = sucessor; sucessor = atual; atual = atual.esq; } if (sucessor != apaga.dir) { paidosucessor.esq = sucessor.dir; sucessor.dir = apaga.dir; } return sucessor; } Método: no_sucessor Retorno: apaga sucessor atual paisucessor sucessor atual sucessor atual = null Entrada: true paisucessor sucessor
  • 28. public No no_sucessor(No apaga) { No paidosucessor = apaga; No sucessor = apaga; No atual = apaga.dir; while (atual != null) { paidosucessor = sucessor; sucessor = atual; atual = atual.esq; } if (sucessor != apaga.dir) { paidosucessor.esq = sucessor.dir; sucessor.dir = apaga.dir; } return sucessor; } Método: no_sucessor Retorno: apaga sucessor atual paisucessor sucessor atual = null Entrada: true paisucessor sucessor null
  • 29. public No no_sucessor(No apaga) { No paidosucessor = apaga; No sucessor = apaga; No atual = apaga.dir; while (atual != null) { paidosucessor = sucessor; sucessor = atual; atual = atual.esq; } if (sucessor != apaga.dir) { paidosucessor.esq = sucessor.dir; sucessor.dir = apaga.dir; } return sucessor; } Método: no_sucessor sucessor apaga paisucessor sucessor atual paisucessor sucessor atual = null Entrada: true null apaga.dir Retorno:
  • 30. atual.item = 11 pai.item = 25 filho_esq = true pai.esq No sucessor = no_sucessor(atual); if (atual == root) root = sucessor; else if (filho_esq) pai.esq = sucessor; else pai.dir = sucessor; sucessor.esq = atual.esq; Trecho de código 1 2 3 4 5 sucessor pai.esq = sucessor Linha 3: atual.esq
  • 31. atual.item = 11 pai.item = 25 filho_esq = true pai.esq atual.esq Trecho de código 1 2 3 4 5 pai.esq = sucessor Linha 3: sucessor No sucessor = no_sucessor(atual); if (atual == root) root = sucessor; else if (filho_esq) pai.esq = sucessor; else pai.dir = sucessor; sucessor.esq = atual.esq;
  • 32. pai.esq atual.esq Trecho de código 1 2 3 4 5 pai.esq= sucessor Linha 3: Linha 5: sucessor.esq = atual.esq sucessor sucessor No sucessor = no_sucessor(atual); if (atual == root) root = sucessor; else if (filho_esq) pai.esq = sucessor; else pai.dir = sucessor; sucessor.esq = atual.esq;
  • 33. public No no_sucessor(No apaga) { No paidosucessor = apaga; No sucessor = apaga; No atual = apaga.dir; while (atual != null) { paidosucessor = sucessor; sucessor = atual; atual = atual.esq; } if (sucessor != apaga.dir) { paidosucessor.esq = sucessor.dir; sucessor.dir = apaga.dir; } return sucessor; } Método: no_sucessor Vai para a sub- arvore a direita Caminha para o Nó mais a esquerda Se sucessor não é o filho a direita do Nó que deverá ser eliminado Pai herda os filhos do sucessor que sempre serão a direita Guardando a referencia a direita do sucessor para quando ele assumir a posição correta na arvore
  • 34. 34 Método: caminhar public void caminhar() { System.out.print("n Exibindo em ordem: "); inOrder(root); System.out.print("n Exibindo em pos-ordem: "); posOrder(root); System.out.print("n Exibindo em pre-ordem: "); preOrder(root); System.out.print("n Altura da arvore: " + altura(root)); System.out.print("n Quantidade de folhas: " + folhas(root)); System.out.print("n Quantidade de Nós: " + contarNos(root)); if (root != null ) { // se arvore nao esta vazia System.out.print("n Valor minimo: " + min().item); System.out.println("n Valor maximo: " + max().item); } } Chamada a métodos recursivos Entrada: Não há Saída: Não tem
  • 35. 35 Método: inOrder public void inOrder(No atual) { if (atual != null) { inOrder(atual.esq); System.out.print(atual.item + " "); inOrder(atual.dir); } } Primeiro visita o Nó a esquerda, depois a raiz (imprime o item), finalizando com o Nó a direita. Entrada: O Nó raiz Saída: Não tem retorno
  • 36. 36 Método: posOrder public void posOrder(No atual) { if (atual != null) { posOrder(atual.esq); posOrder(atual.dir); System.out.print(atual.item + " "); } } Primeiro visita o Nó a esquerda, depois o Nó a direita, finalizando com a raiz (imprime o item). Entrada: O Nó raiz Saída: Não tem retorno
  • 37. 37 Método: preOrder public void preOrder(No atual) { if (atual != null) { System.out.print(atual.item + " "); preOrder(atual.esq); preOrder(atual.dir); } } Primeiro visita a raiz (imprime o item), depois o Nó a esquerda, finalizando com o Nó a direita. Entrada: O Nó raiz Saída: Não tem retorno
  • 38. 38 Método: folhas public int folhas(No atual) { if (atual == null) return 0; if (atual.esq == null && atual.dir == null) return 1; return folhas(atual.esq) + folhas(atual.dir); } Entrada: O Nó raiz Saída: Numero de folhas da arvore
  • 39. 39 Método: folhas public int folhas(No atual) { if (atual == null) return 0; if (atual.esq == null && atual.dir == null) return 1; return folhas(atual.esq) + folhas(atual.dir); } Entrada: O Nó raiz Saída: Numero de folhas da arvore A arvore não possui itens ou chegou no final e não encontrou mais nenhum item retorna zero Retorne chamada recursiva da função contando a quantidade de folhas a esquerda mais a direita da arvore Se encontrou somente um item (raiz) ou chegou em uma folha, retorna 1
  • 40. 40 Método: contarNos public int contarNos(No atual) { if (atual == null) return 0; else return ( 1 + contarNos(atual.esq) + contarNos(atual.dir) ); } Entrada: O Nó raiz Saída: Numero de Nós Arvore vazia ou chegou no final e não encontrou mais nenhum item retorna zero Senão retorne o valor 1 + chamada recursiva da função contando a quantidade de nós a esquerda mais a direita da arvore
  • 41. 41 Método: min public No min() { No atual = root; No anterior = null; while (atual != null) { anterior = atual; atual = atual.esq; } return anterior; } Entrada: não há Saída: No mais a esquerda (Nó mínimo)
  • 42. 42 Método: min public No min() { No atual = root; No anterior = null; while (atual != null) { anterior = atual; atual = atual.esq; } return anterior; } Entrada: não há Saída: No mais a esquerda (Nó mínimo) Começa na raiz Enquanto não encontrar um Nó igual a null Guarda o Nó anterior Caminha para o filho a esquerda
  • 43. 43 Método: max public No max() { No atual = root; No anterior = null; while (atual != null) { anterior = atual; atual = atual.dir; } return anterior; } Entrada: não há Saída: No mais a direita (Nó máximo)
  • 44. 44 Método: max public No max() { No atual = root; No anterior = null; while (atual != null) { anterior = atual; atual = atual.dir; } return anterior; } Entrada: não há Saída: No mais a direita (Nó máximo) Começa na raiz Enquanto não encontrar um Nó igual a null Guarda o Nó anterior Caminha para o filho a direita
  • 45. Exemplo de uso da classe Tree: class TreeBinApp { public static void main(String[] args) { Scanner le = new Scanner(System.in); Tree arv = new Tree(); int opcao; long x; System.out.print("n Programa Arvore binaria de long"); do { System.out.print("n***********************************"); System.out.print("nEntre com a opcao:"); System.out.print("n ----1: Inserir"); System.out.print("n ----2: Excluir"); System.out.print("n ----3: Pesquisar"); System.out.print("n ----4: Exibir"); System.out.print("n ----5: Sair do programa"); System.out.print("n***********************************"); System.out.print("n-> "); opcao = le.nextInt(); switch(opcao) { case 1: { System.out.print("n Informe o valor (long) -> "); x = le.nextLong();
  • 46. x = le.nextLong(); arv.inserir(x); break; } case 2: { System.out.print("n Informe o valor (long) -> "); x = le.nextLong(); if ( !arv.remover(x) ) System.out.print("n Valor nao encontrado!");; break; } case 3: { System.out.print("n Informe o valor (long) -> "); x = le.nextLong(); if( arv.buscar(x) != null ) System.out.print("n Valor Encontrado"); else System.out.print("n Valor nao encontrado!"); break; } case 4: { arv.caminhar(); break; }
  • 47. } // fim switch } while(opcao != 5); } } https://gist.github.com/divanibarbosa/819e7cfcf1b9bae48c4e0f5bd74fb658
  • 48. 48 Atividades 1. No código Java para uma árvore, o ________ e a ________ são geralmente classes separadas. .2. Uma sub-árvore de uma árvore binária sempre tem (a) Uma raiz que é um filho da raiz da árvore principal (b) Uma raiz não conectada a raiz da árvore principal (c) Menos Nós que a árvore principal (d) Uma irmã com mesmo número de Nós 3. Verdadeiro ou falso: (a) Eliminar um Nó com um filho de uma árvore binária de busca envolve encontrar o sucessor desse Nó. (b) Nem todas as árvores são binárias. (c) Uma árvore não balanceada é uma árvore na qual a raiz ou algum outro Nó tenha muito mais filhos à esquerda do que filhos à direita ou vice-versa.
  • 49. 49 Atividades 4. Trabalho 2 - Exercício 6. Desenhe uma arvore binária usando a seguinte sequencia de dados de entrada: (a) 25, 11, 42, 6, 19, 37 e 14 (b) 11, 22, 33, 44, -11, -33 e -22 (c) 14, 4, 15, 3, 9, 13, 18, 7, 11, 16, 20, 5, 17, 4 e 5 Responda: Quantas folhas, nós e qual a altura das arvores (a), (b) e (c). Escreva a arvore (b) e (c) em pré-ordem e pós-ordem. Desenhe as arvores (a), (b) e (c) depois da inserção do nó 21 e da remoção do nó 11 para as arvores (a) e (b) e nó 18 para arvore (c). 5. Desenvolva um programa árvore binária de: (a) double (b) caracteres (c) strings
  • 50. 50 Atividades 6. Desenvolva um programa árvore binária para um objeto que represente uma agenda telefônica, use o nome como campo chave