Estrutura de Dados
• Introdução
• Árvores binárias
• Definição
• Implementação
• Ordens de percurso (caminhamentos)
• Árvores binária de busca (ABB)
• Definição
• Árvore
• Um conjunto de nós tal que:
• Existe um nó r, denominado raiz, com zero ou mais subárvores, cujas raízes estão ligadas a r
• Os nós raízes destas sebárvores são os filhos de r • Os nós internos da árvore são os nós com filhos
• As folhas ou nós externos da árvore são os nós sem filhos
• Uma árvore em que cada nodo tem zero, um ou dois
filhos, ou seja, de no máximo grau dois.
• Uma árvore binária é:
• Uma árvore vazia; ou
• Um nodo raiz com duas subárvores: - a subárvore da direita (sad)
- a subárvore da esquerda (sad)
• Além de ser uma árvore de
grau dois
ela é
ordenada
, ou seja, a ordem das subárvores
importa.
• Estritamente Binária:
Cada nodo tem 0 ou dois filhos
• Binária Completa
Toda folha está no último ou penúltimo nível
• Árvore Binária Cheia:
É aquela em que, se n é um nó com alguma de suas subárvores vazias, então n se localiza no último nível. É uma árvore que tem todos os nodos internos com dois filhos e onde todas as folhas estão na mesma profundidade.
O número máximo de nodos para uma árvore binária cheia De altura k é:
•
Zigue-zague:
nodos interiores possuem exatamente uma
subárvore vazia.
•
Exemplo de aplicação de árvores binárias
- árvores binárias representando expressões aritméticas:
- Nós folhas representam operandos - Nós internos operadores
- Exemplo: (3 + 6)*(4 – 1)+5
•
Notação textual de uma árvore binária:
- A árvore vazia é representada por <> - Árvores não vazias por <raiz sae sad>
-Exemplo:
• Propriedade fundamental de árvores
• só existe um caminho da raiz para qualquer nó
•
Altura
de uma árvore
• Como realizar a implementação?
• a altura de uma árvore com um único nó raiz é zero • a altura de uma árvore vazia é -1
• Representação de uma árvore:
• Através de um ponteiro para o nó raiz
• Representação de um nó da árvores:
• Estrutura em C contendo
• A informação propriamente dita (exemplo: um caractere) • Dois ponteiros para as subárvores, à esquerda e à direita
• Implementação das funções:
- Implementação em geral recursiva
- Usa a definição recursiva da estrutura
• Uma árvore binária é:
- Uma árvore vazia; ou
- Um nó raiz com duas subárvores:
- A subárvore da direita (sad) - A subárvore da esquerda (sae)
• Função arv_criavazia
- Cria uma árvore vazia
• Função arv_cria
- Cria um nodo raiz dadas as informações e as duas subárvores, a da esquerda e da direita
- Retorna o endereço do nó raiz criado
• Função arv_criavazia e arv_cria
- As duas funções para a criação de árvores
representam os dois casos da definição
recursiva de árvore binária:
- Uma árvore binária Arv *a;
- é vazia a = arv_criavazia();
- É composta por uma raiz e duas subárvores
a = arv_cria(c, sae, sad)
• Função arv_libera
- Libera memória alocada pela estrutura da árvore
• As subárvores devem ser liberadas antes de se liberar o nó raiz
- Retorna uma árvore vazia, representada por NULL
• Função arv_imprime
- Percorre recursivamente a árvore, visitando todos os nós e imprimindo sua informação
• Exemplo:
criar a árvore <a<b<><d<><>>><c<e<><>><f<><>> > >
• Exemplo: acrescenta nós x, y e z
• Exemplo: libera nós
•
Pré-ordem:
- Trata raiz, percorre sae, percorre sad - Exemplo: a b d c e f
•
Ordem simétrica (ou In-Ordem):
- Percorre sae, trata raiz, percorre sad - Exemplo: b d a e c f
•
Pós-ordem:
• Pré-ordem:
• Ordem simétrica (ou In-Ordem):
• Pós-ordem:
• Fazer percurso de pré-ordem, in-ordem e
pós-ordem:
• Fazer percurso de pré-ordem, in-ordem e
pós-ordem:
• Pré-Ordem
+*+-36-415
• In-Ordem
Estrutura de Dados
• Uma árvore que se encontra organizada de tal
forma que:
• O valor associado à raiz é sempre maior que o valor associado a qualquer nó da subárvore à esquerda (sae) e
• O valor associado à raiz é sempre menor que o valor associado a qualquer nó da subárvore à direita (sad)
• Diferenciação
• Em uma ABB é possível encontrar
qualquer chave existente
caminhando na árvore:
• Compare o valor dado com o valor associado à raiz
• Se for igual, o valor foi encontrado
• Se for menor, a busca continua na sae • Se for maior, a busca continua na sad
• Os nós internos têm todos, ou quase todos,
dois filhos
• Qualquer nó pode ser alcançado a partir da
raiz em O(log n) passos
• Todos os nós têm apenas
um filho, com exceção da
(única) folha
• Qualquer nó pode ser
alcançado a partir da raiz
em O(n) passos
• A mesma estrutura de uma árvore binária.
• Dado que a definição de árvores é recursiva,
geralmente suas operações também são definidas
recursivamente
•
Criação:
Árvore vazia representada por NULL:
•
Impressão:
•
Busca:
- explora a propriedade de ordenação da árvore
- Possui desempenho computacional proporcional à altura (O(log n) para o caso de árvore balanceada)
•
Inserção:
- 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 mantém v
- Se a (sub)árvore não for vazia
- Compare v com o valor na raiz
• Inserção:
• Inserção:
• Inserção:
• Inserção:
•
Remoção:
- Recebe um valor v a ser retirado
- Retorna a eventual nova raiz da árvore - Para remover v, faça:
- Se a árvore for vazia
- Nada tem de 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
•
Remoção:
• Para retirar a raiz da árvore, há três 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
•
Remoção de folha
• 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
• Remoção de pai de filho único
• 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
• Remoção de pai de dois filhos
• 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)
• Retire 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)