Estrutura de dados em Java - Árvores Binárias

21,243 views
21,041 views

Published on

Published in: Technology
0 Comments
7 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
21,243
On SlideShare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
584
Comments
0
Likes
7
Embeds 0
No embeds

No notes for slide

Estrutura de dados em Java - Árvores Binárias

  1. 1. Prof. Adriano Teixeira de Souza
  2. 2.  São estruturas de dados adequadas para a representação de hierarquias. Uma árvore é composta por um conjunto de nós. Existe um nó r, denominado raiz, que contém zero ou mais subárvores, cujas raízes são ligadas diretamente a r. A raiz se liga a um ou mais elementos, e cada um destes forma uma nova subárvore. Esses elementos são seus galhos ou filhos.
  3. 3.  Fundamentos básicos ◦ GRAU – número de subárvores de um nó. ◦ FOLHA – um nó que possui grau zero, ou seja, não possui subárvores. ◦ FILHOS – são as raízes das subárvores de um nó. ◦ Nó não terminal é um nó que não é uma folha e é diferente da raiz.
  4. 4.  Fundamentos básicos ◦ A altura de uma árvore é o comprimento do caminho mais longo da raiz até uma das folhas. ◦ Uma árvore nula tem altura 0. ◦ Todos os nós são acessíveis a partir da raiz. ◦ Existe um único caminho entre a raiz e qualquer outro nó.
  5. 5.  Formas de representação gráfica
  6. 6.  Árvore Binária: Uma árvore binária é uma árvore que pode ser nula, ou então tem as seguintes características: ◦ Existe um nó especial denominado raiz; ◦ Nenhum nó tem grau superior a 2 (dois), isto é, nenhum nó tem mais de dois filhos; ◦ Existe um “senso de posição”, ou seja, distingue-se entre uma subárvore esquerda e uma subárvore direita.
  7. 7.  Atravessamento (ou caminhamento) de árvore é a passagem de forma sistemática por cada um de seus nós; Diferentes formas de percorrer os nós de uma árvore: ◦ Pré-ordem ou prefixa (busca em profundidade) ◦ Em ordem ou infixa (ordem central) ◦ Pós-ordem ou posfixa ◦ Em nível
  8. 8.  Pré-ordem (prefixa) ◦ visitar a raiz; ◦ caminhar na subárvore à esquerda, segundo este caminhamento; ◦ caminhar na subárvore à direita, segundo este caminhamento.
  9. 9.  Atravessamento em ordem (infixa) ◦ caminhar na subárvore à esquerda, segundo este caminhamento; ◦ visitar a raiz; ◦ caminhar na subárvore à direita, segundo este caminhamento.
  10. 10.  Atravessamento pós-ordem (posfixa) ◦ a) caminhar na subárvore à esquerda, segundo este caminhamento; ◦ b) caminhar na subárvore à direita, segundo este caminhamento; ◦ c) visitar a raiz.
  11. 11.  Atravessamento em nível ◦ Percorre-se a árvore de cima para baixo e da direita para a esquerda.
  12. 12.  Árvore Estritamente Binária: ◦ É uma árvore binária na qual todo nó tem 0 ou 2 subárvores, ou seja, nenhum nó tem “filho único”.
  13. 13.  Árvore Binária Cheia ◦ Todos os nós, exceto os do último nível, possuem exatamente duas subárvores. ◦ Uma árvore binária cheia de altura h tem 2h – 1 nós.
  14. 14.  Árvore Degenerada ◦ Cada nó possui exatamente um filho, e a árvore tem o mesmo número de níveis que de nós
  15. 15.  Uma árvore é denominada árvore binária de busca se: ◦ Todo elemento da subárvore esquerda é menor que o elemento raiz; ◦ Nenhum elemento da subárvore direita é menor que o elemento raiz; ◦ As subárvores direita e esquerda também são árvores de busca binária.
  16. 16.  Busca ◦ Se o valor for igual à raiz, o valor existe na árvore. ◦ Se o valor for menor do que a raiz, então deve buscar-se na subárvore da esquerda, e assim recursivamente, em todos os nós da subárvore. ◦ Se o valor for maior que a raiz, deve-se buscar na subárvore da direita, até alcançar-se o nó folha da árvore, encontrando ou não o valor requerido.
  17. 17.  Inserção ◦ Se a árvore estiver vazia, cria um novo no e insere as informações do novo nó. ◦ Compara a chave a ser inserida com a chave do nó analisado:  Se menor, insere a chave na subárvore esquerda;  Se maior, insere a chave na subárvore direita.
  18. 18.  Inserção Exemplo: ◦ Inserir os seguintes elementos: 7, 13, 20, 4, 1, 18, 5, 11 .
  19. 19.  Remoção A remoçã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: ◦ Remoção na folha ◦ Remoção de um nó com um filho ◦ Remoção de um nó com dois filhos
  20. 20.  Remoção na folha ◦ A exclusão na folha é a mais simples, basta removê-lo da árvore.
  21. 21.  Remoção de um nó com um filho ◦ Excluindo-o, o filho sobe para a posição do pai.
  22. 22.  Remoção de um nó com dois filhos ◦ Neste caso, pode-se operar de duas maneiras diferentes:  Substitui-se o valor do nó a ser retirado pelo valor sucessor (o nó mais à esquerda da subárvore direita);  Substitui-se o valor do nó a ser retirado pelo valor antecessor (o nó mais à direita da subárvore esquerda)
  23. 23.  Remoção de um nó com dois filhos ◦ Exemplo de remoção substituindo o nó pelo seu antecessor.
  24. 24.  Remoção de um nó com dois filhos ◦ Exemplo de remoção substituindo o nó pelo seu sucessor.
  25. 25.  Árvore é representada pelo ponteiro para o nó raiz public class NoArvore { int info; NoArvore direita; NoArvore esquerda; }
  26. 26.  Imprime os valores da árvore em ordem crescente, percorrendo os nós em ordem simétrica void abb_imprime (NoArvore a) { if (a != null) { abb_imprime(a.esquerda); System.out.println(a.info+"n"); abb_imprime(a.direita); } }
  27. 27.  Explora a propriedade de ordenação da árvore Possui desempenho computacional proporcional à alturaNoArvore abb_busca (NoArvore r, int v){ if (r == null) return null; else if (r.info > v) return abb_busca (r.esquerda, v); else if (r.info < v) return abb_busca (r.direita, v); else return r;}
  28. 28.  recebe um valor v a ser inserido retorna o eventual novo nó raiz da (sub-)árvore para adicionar v na posição correta, faça: ◦ se a (sub-)árvore for vazia  crie uma árvore cuja raiz contém v ◦ se a (sub-)árvore não for vazia  compare v com o valor na raiz  insira v na sae ou na sad, conforme o resultado da comparação
  29. 29. NoArvore abb_insere (NoArvore a, int v){ é necessário atualizar os ponteiros para if (a==null) { as sub-árvores à esquerda ou à direita a = new NoArvore(); quando da chamada recursiva da função, pois a função de inserção pode alterar a.info = v; o valor do ponteiro para a raiz da (sub-)árvore. a.esquerda = a.direita = null; } else if (v < a.info) a.esquerda = abb_insere(a.esquerda,v); else /* v >= a->info */ a.direita = abb_insere(a.direita,v); return a;}
  30. 30. Criainsere 6insere 8insere 4insere 5insere 2insere 3insere 1insere 9insere 7
  31. 31.  recebe um valor v a ser inserido retorna a eventual nova raiz da árvore para remover v, faça: ◦ se a árvore for vazia  nada tem que ser feito ◦ se a árvore não for vazia  compare o valor armazenado no nó raiz com v  se for maior que v, retire o elemento da sub-árvore à esquerda  se for menor do que v, retire o elemento da sub- árvore à direita  se for igual a v, retire a raiz da árvore
  32. 32.  para retirar a raiz da árvore, há 3 casos: ◦ caso 1: a raiz que é folha ◦ caso 2: a raiz a ser retirada possui um único filho ◦ caso 3: a raiz a ser retirada tem dois filhos
  33. 33.  Caso 1: a raiz da sub-árvore é folha da árvore original ◦ libere a memória alocada pela raiz ◦ retorne a raiz atualizada, que passa a ser NULL
  34. 34.  Caso 2: a raiz a ser retirada possui um único filho ◦ libere a memória alocada pela raiz ◦ a raiz da árvore passa a ser o único filho da raiz
  35. 35.  Caso 3: a raiz a ser retirada tem dois filhos ◦ encontre o nó N que precede a raiz na ordenação ◦ (o elemento mais à direita da sub-árvore à esquerda) ◦ troque o dado da raiz com o dado de N ◦ retire N da sub-árvore à esquerda ◦ (que agora contém o dado da raiz que se deseja retirar)  retirar o nó N mais à direita é trivial, pois N é um nó folha ou  N é um nó com um único filho (no caso, o filho da direita nunca existe)
  36. 36. NoArvore abb_retira (NoArvore r, int v){ if (r == null) return null; else if (r.info > v) r.esquerda = abb_retira(r.esquerda, v); else if (r.info < v) r.direita = abb_retira(r.direita, v); else { /* achou o nó a remover */ /* nó sem filhos */ if (r.esquerda == null && r.direita == null) { //free (r); r = null; } /* nó só tem filho à direita */ else if (r.esquerda == null) { NoArvore t = r; r = r.direita; //free (t); }
  37. 37. /* só tem filho à esquerda */ else if (r.direita == null) { NoArvore t = r; r = r.esquerda; //free (t); } /* nó tem os dois filhos */ else { NoArvore f = r.esquerda; while (f.direita != null) { f = f.direita; } r.info = f.info; /* troca as informações */ f.info = v; r.esquerda = abb_retira(r.esquerda,v); } } return r;}

×