Estrutura de dados - Árvores Binárias

50.406 visualizações

Publicada em

Publicada em: Tecnologia
1 comentário
20 gostaram
Estatísticas
Notas
Sem downloads
Visualizações
Visualizações totais
50.406
No SlideShare
0
A partir de incorporações
0
Número de incorporações
2
Ações
Compartilhamentos
0
Downloads
1.944
Comentários
1
Gostaram
20
Incorporações 0
Nenhuma incorporação

Nenhuma nota no slide

Estrutura de dados - Á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ó raizstruct noArv { int info; struct noArv* esq; struct noArv* dir;};typedef struct noArv NoArv;
  26. 26.  Árvore vazia representada por NULL:NoArv* abb_cria (void){ return NULL;}
  27. 27.  Imprime os valores da árvore em ordem crescente, percorrendo os nós em ordem simétrica void abb_imprime (NoArv* a) { if (a != NULL) { abb_imprime(a->esq); printf("%dn",a->info); abb_imprime(a->dir); } }
  28. 28.  Explora a propriedade de ordenação da árvore Possui desempenho computacional proporcional à altura NoArv* abb_busca (NoArv* r, int v) { if (r == NULL) return NULL; else if (r->info > v) return abb_busca (r->esq, v); else if (r->info < v) return abb_busca (r->dir, v); else return r; }
  29. 29.  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
  30. 30. NoArv* abb_insere (NoArv* a, int v){ if (a==NULL) { a = (NoArv*)malloc(sizeof(NoArv)); a->info = v; é necessário atualizar os ponteiros para a->esq = a->dir = NULL; as sub-árvores à esquerda ou à direita quando da chamada recursiva da função, } pois a função de inserção pode alterar o valor do ponteiro para a raiz da (sub-)árvore. else if (v < a->info) a->esq = abb_insere(a->esq,v); else /* v >= a->info */ a->dir = abb_insere(a->dir,v); return a;}
  31. 31. Criainsere 6insere 8insere 4insere 5insere 2insere 3insere 1insere 9insere 7
  32. 32.  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
  33. 33.  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
  34. 34.  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
  35. 35.  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
  36. 36.  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)
  37. 37. NoArv* abb_retira (NoArv* r, int v){ if (r == NULL) return NULL; else if (r->info > v) r->esq = abb_retira(r->esq, v); else if (r->info < v) r->dir = abb_retira(r->dir, v); else { /* achou o nó a remover */ /* nó sem filhos */ if (r->esq == NULL && r->dir == NULL) { free (r); r = NULL; } /* nó só tem filho à direita */ else if (r->esq == NULL) { NoArv* t = r; r = r->dir; free (t); }
  38. 38. /* só tem filho à esquerda */ else if (r->dir == NULL) { NoArv* t = r; r = r->esq; free (t); } /* nó tem os dois filhos */ else { NoArv* f = r->esq; while (f->dir != NULL) { f = f->dir; } r->info = f->info; /* troca as informações */ f->info = v; r->esq = abb_retira(r->esq,v); } } return r;}

×