A apresentação está carregando. Por favor, espere

A apresentação está carregando. Por favor, espere

Árvores Binárias Profa. Patrícia A. Jaques Luiz Gonzaga Jr

Apresentações semelhantes


Apresentação em tema: "Árvores Binárias Profa. Patrícia A. Jaques Luiz Gonzaga Jr"— Transcrição da apresentação:

1 Árvores Binárias Profa. Patrícia A. Jaques Luiz Gonzaga Jr
Contribuições Algumas transparências são da profa. Renata Galante da II/UFRGS com permissão

2 É uma árvore onde cada nó pode conter nenhum, 1 ou 2 filhos apenas
Árvore Binária É uma árvore onde cada nó pode conter nenhum, 1 ou 2 filhos apenas Grau=2. Uma árvore binária é formada por nós onde cada nó contém um valor, um ponteiro esquerdo e um ponteiro direito. A D C B E F G Nivelamento - PIPCA 2012/1

3 Árvore Binária O nó A é a raiz da árvore. Como B é a raiz da sua sub-árvore esquerda dizemos que B é o filho esquerdo de A, do mesmo modo, C é o filho direito de A. Por isso A é o pai dos nós B e C e estes dois são irmãos. A D C B E F G filho esquerdo de A filho direito de A Nivelamento - PIPCA 2012/1

4 Tipos de Árvores Binárias: Estritamente Binária
Ocorre quando todo nó que não é folha tiver sub-arvores esquerda e direita não vazias. todo nó tem 0 ou 2 filhos. Número de nós em uma árvore estritamente binária com n folhas: 2n-1 Estritamente Binária bibliografia:Szwarcfiter, J. & Markenzon, Lilian. Estrturas de Dados e seus Algoritmos. Rio de Janeiro: LTC, 1994 Nivelamento - PIPCA 2012/1

5 Tipos de Árvores Binárias: Binária Completa
É uma árvore estritamente binária onde todos os nós folhas se encontram ou no último ou no penúltimo nível da árvore. Binária Completa bibliografia:Szwarcfiter, J. & Markenzon, Lilian. Estrturas de Dados e seus Algoritmos. Rio de Janeiro: LTC, 1994 Nivelamento - PIPCA 2012/1

6 Tipos de Árvores Binárias: Binária Cheia
bibliografia:Szwarcfiter, J. & Markenzon, Lilian. Estrturas de Dados e seus Algoritmos. Rio de Janeiro: LTC, 1994 Binária Cheia Árvore estritamente binária onde os nós folhas se encontram no último nível. O número total de nós em (tn) em uma árvore binária cheia de altura h é: tn=2h-1 Assim, pela mesma fórmula podemos afirmar que, numa árvore binária completa, a altura h de uma árvore é dada por: h= log2(tn+1) Embora a árvore binária completa possua muitos nós, a distância da raiz até qualquer folha (profundidade) é relativamente pequena. Nivelamento - PIPCA 2012/1

7 Árvores Binárias: representação
Endereço da raiz A C B D G F E referência para filho esquerdo referência para filho direito A C B G F E D chave do nó Nivelamento - PIPCA 2012/1

8 Aplicação de Árvores Binárias
Representação de expressões aritméticas em árvores binárias Dada uma expressão aritmética, sua representação em árvore binária é feita de tal forma que a ordem de prioridade das operações fica implícita. Regra: O operador de menor prioridade aparece na raiz; A sub-expressão à esquerda desse operador dá origem à sub-árvore esquerda; A sub-expressão à direita do operador dá origem à sub-árvore direita. Nivelamento - PIPCA 2012/1

9 Representação de expressões aritméticas em árvores binárias
+ A * B C Ex: A + B * C Obs. Operandos sempre aparecem como folhas; operadores, nunca. Nivelamento - PIPCA 2012/1

10 Representação de expressões aritméticas em árvores binárias
Caminhamentos: Em pos-ordem  Notação polonesa pós fixada. Ex: A B C * + (na primeira expressão); Em in-ordem  Forma original (infixada) sem parênteses. Ex: A + B * C (primeira expressão); Em pré-ordem  Notação polonesa prefixada (sem grande utilidade). Ex: + A * B C (primeira expressão); Obs. A notação polonesa pós fixada é muito útil (principalmente para as máquinas), pois exibe os operadores na ordem de execução das operações. Nivelamento - PIPCA 2012/1

11 Algoritmo para gerar uma árvore binária a partir de uma expressão aritmética em notação infixa
Procedimento Interpretar(string)->ponteiro COMEÇO 1. fazer uma árvore com a string como único nó; 2. procurar por operadores de MENOR precedência (+ ou -) que não estejam dentro de “(“ e “)”, pois estes serão considerados um operando. se tem, substitua a árvore por uma com o operador no nó raiz e com os operandos nos nós folha. (se você procurar o PRIMEIRO operando com menor precedência, basta dividir a árvore como explicado e aplicar esse procedimento de procurar operador de menor precedência recursivamente no nó da DIREITA). Lembre-se que um operando é um número, uma variável uma expressão entre parêntesis ou uma função. 3. repetir o procedimento 2 com operadores de MÉDIA precedência (* e /) SÓ EM NÓS FOLHA; 4. repetir o procedimento para operadores com MAIOR precedência (só o ^); 5. percorrer os nos folha (todos contém operandos) se o operando é número ou variável, não mexe. se o operando é expressão entre parêntesis, substituir esse nó por Interpretar(expressão sem os parêntesis); FIM Interpretar. Nivelamento - PIPCA 2012/1

12 Algoritmo para avaliar a árvore (calcular a expressão)
Algoritmo eval (BinaryTreeNode v) { /* recebe nó raiz como parâmetro: a classe BinaryTreeNode, além dos ponteiros para filhos esquerdo e direito, também contém outros dois atributos: 1) char operador; 2) double operando; real retorno 0; if v == null { não tem árvore - devolve valor zero } then retorno  0; else if v.operador==’’ /* se operando é igual ‘’, então nó guarda operando*/ then return v.operando; //devolve valor contido no nodo else switch a.operador { //operador - executa operação case “+”: retorno  eval(v.left) + eval(v.right); case “-” : retorno  eval(v.left) - eval(v.right); case “*” : retorno  eval(v.left) * eval(v.right); case “/” : retorno  eval(v.left) / eval(v.right); } return retorno; Nivelamento - PIPCA 2012/1

13 Árvore Binária de Pesquisa
Também chamada de: árvore binária de busca ou árvore binária ordenada apresentam uma relação de ordem entre os nodos ordem é definida por um campo denominado chave não permite chaves duplicadas, ou seja, cada nó tem um valor de chave diferente esq chave dir Nivelamento - PIPCA 2012/1

14 Árvore Binária de Pesquisa
não há chaves duplicadas raiz 500 300 800 150 400 900 600 filho da esquerda: valor da chave menor que o valor da chave do nó pai filho da direita: valor da chave maior que o valor da chave do nó pai fazer exercício: criar árvore inserindo nós na seguinte ordem: f, a, t, b, e, u, i, c, d, a, e Nivelamento - PIPCA 2012/1

15 Classe representando um nó
public class BSTNode { protected int key; protected BSTNode left, right; public BSTNode() { left = right = null; } public BSTNode(int num) { this(num,null,null); public BSTNode(int num, BSTNode lt, BSTNode rt) { this.key = num; left = lt; right = rt; public int getKey() { return key; public void setKey(int key) { this.key = key; public BSTNode getLeft() { return left; } public void setLeft(BSTNode left) { this.left = left; public BSTNode getRight() { return right; public void setRight(BSTNode right) { this.right = right; Nivelamento - PIPCA 2012/1

16 Classe representando árvore
public class BST { private BSTNode root = null; public BST() { } public void clear() { root = null; public boolean isEmpty() { return root == null; public BSTNode getRootNode (){ return root; Nivelamento - PIPCA 2012/1

17 Busca de um valor A procura de um valor em uma árvore binária é algo mais rápido do que a procura em listas encadeadas ou vetores. Para cada nó, compare a chave a ser localizada com o valor armazenado no nó correntemente apontado. Se a chave for menor, vá para a sub-árvore esquerda e tente novamente, senão vá para a sub-árvore direita. A busca pára quando for encontrado o nó ou quando não há mais meios de continuar (nó folha), pois a chave não está na árvore. A complexidade pode ser medida pelo número de comparações feitas durante o processo de busca. Isso depende do número de nós encontrados no único caminho que leva da raiz ao nó procurado. Então a complexidade, depende da forma da árvore e da posição do nó procurado na árvore. O número médio de comparações em uma busca é  (lg n), pois a altura de uma árvore binária completa (perfeitamente balanceada) é h=lg (n+1) . Nivelamento - PIPCA 2012/1

18 Busca public BSTNode search (int el) { return search(root,el); }
private BSTNode search (BSTNode p, int el) { while (p != null) { /* se valor procurado == chave do nó, retorna referência ao nó */ if (el==p.key) return p; /* se valor procurado < chave do nó, procurar na sub-árvore esquerda deste nó */ else if (el<p.key) p = p.left; /* se valor procurado > chave do nó, procurar na sub-árvore direita deste nó */ else p = p.right; // caso chave não foi achada, retorna null return null; Nivelamento - PIPCA 2012/1

19 Inserindo uma nova chave
public boolean insert (int el) { BSTNode p = root, prev = null; // caso o valor já exista na árvore, não inserir e retornar false if (search(el)!=null) return false; // procurando um lugar para colocar o novo nó while (p != null) { prev = p; if (el<p.key) p = p.left; else p = p.right; } // se árvore vazia if (root == null) root = new BSTNode(el); else if (prev.key<el) prev.right = new BSTNode(el); else prev.left = new BSTNode(el); return true; Nivelamento - PIPCA 2012/1

20 Caminhamento (percurso) em árvore binária de pesquisa
É o processo de visitar cada nó da árvore exatamente uma vez. Visitar: Fazer algo com o nó como exibi-lo, gravá-lo, etc. O percurso pode ser interpretado como colocar todos os nós em uma linha ou a linearização da árvore. Os percursos podem ser em extensão ou em profundidade. Percursos em extensão: visitam todos os nós de cada nível, nível por nível (indo do mais alto ao mais baixo, ou vice-versa). Percursos em profundidade: percorre os caminhos das árvores. Percorre primeiramente todo o caminho mais a esquerda, e assim por diante. Nivelamento - PIPCA 2012/1

21 Caminhamento (percurso) em árvore binária de pesquisa
Os três mais comuns tipos de percursos em profundidade, definidos recursivamente, são: PRÉ-ORDEM (raiz-esquerda-direita): visita o nó; percorre a sub-árvore esquerda; percorre a sub-árvore direita; PÓS-ORDEM (esquerda-direita- raiz): IN-ORDEM (esquerda-raiz-direita): percorre a sub-árvore direita. Nivelamento - PIPCA 2012/1

22 public void inorder() { inorder(root); }
Percurso in-ordem public void inorder() { inorder(root); } private void inorder (BSTNode p) { if (p != null) { inorder(p.left); System.out.print(p.key + " "); inorder(p.right); Nivelamento - PIPCA 2012/1

23 public void preorder() { preorder(root); }
Percurso em pre-ordem public void preorder() { preorder(root); } private void preorder(BSTNode p) { if (p != null) { System.out.print(p.key + " "); preorder(p.left); preorder(p.right); Nivelamento - PIPCA 2012/1

24 public void postorder() { postorder(root); }
Percurso em pós-ordem public void postorder() { postorder(root); } private void postorder(BSTNode p) { if (p != null) { postorder(p.left); postorder(p.right); System.out.print(p.key + " "); Nivelamento - PIPCA 2012/1

25 Na remoção 3 situações podem ocorrer :
Remoção de um nó Na remoção 3 situações podem ocorrer : Caso 1: Exclusão de uma folha O nó é uma folha e não tem filhos: O ponteiro do seu pai é ajustado para nulo. antes 50 depois 50 30 80 30 80 15 40 60 90 40 60 90 Nivelamento - PIPCA 2012/1

26 Caso 2: O nó tem um filho: o ponteiro do pai aponta para o filho deste
Remoção de um nó Caso 2: O nó tem um filho: o ponteiro do pai aponta para o filho deste antes 50 depois 50 30 80 40 80 40 60 90 60 90 Nivelamento - PIPCA 2012/1

27 Remoção de um nó Caso 3: O nó tem 2 filhos. Neste caso podemos fazer a remoção de duas maneiras: remoção por cópia; remoção por fusão antes 50 30 80 15 40 60 90 Nivelamento - PIPCA 2012/1

28 remove uma chave k1 (chave do nó que se quer remover):
Remoção por cópia remove uma chave k1 (chave do nó que se quer remover): sobrescrevendo-a por uma outra chave k2 (o maior valor na sub-árvore esquerda, pois este vai ser maior que todos os valores da sub-árvore esquerda) e então removendo o nó que contem k2 (que será um dos casos simples: folha, ou nó com apenas um filho). Nivelamento - PIPCA 2012/1

29 Remoção por cópia 3 1 2 Final Nivelamento - PIPCA 2012/1

30 Nó que retorna referência ao nó pai de uma chave
protected BSTNode searchFather (int el) { BSTNode p = root; BSTNode prev = null; // acha o nó p com a chave el while (p != null && !(p.key==el)) { prev = p; if (p.key<el) p = p.right; else p = p.left; } if (p!=null && p.key==el) return prev; return null;

31 Remoção por cópia Nivelamento - PIPCA 2012/1
public void deleteByCopying (int el) { BSTNode node, father = null; node = search (el) ; // procura nó a ser deletado if (node != null && node.key==el) { if (node!=root) father = searchFather (el); // procura pai do nó a ser deletado if (node.right == null){ // nó não tem filho direito (caso 2 ou caso 1); if (node==root) root= node.left; else if (father.left == node) father.left = node.left; else father.right = node.left; } else if (node.left == null) { // nó não tem filho esquerdo (caso 2) if (node==root) root= node.right; else if (father.left == node) father.left = node.right; else father.right = node.right; else { // nó tem ambos os filhos: fazer remoção por cópia BSTNode tmp = node.left; // 1. pegando sub-arvore esquerda while (tmp.right != null) // 2. acha a posição mais a direita da sub-árvore esquerda do nó tmp = tmp.right; deleteByCopying (tmp.key); // remove por copia o nó que possui o maior valor // da sub-arvore esquerda do nó a ser deletado node.key = tmp.key; // copia o valor da chave do maior nó da subárvore esquerda else if (root != null) System.out.println("el " + el + " is not in the tree"); else System.out.println("the tree is empty"); Nivelamento - PIPCA 2012/1

32 Remoção por fusão A solução consiste em fusionar as duas sub-árvores do nó a ser deletado em uma. Para tanto, como na organização da árvore binária, todos os valores da sub-árvore a esquerda são menores que os valores da sub-árvore a direita, deve se encontrar o maior valor na sub-árvore esquerda e torná-lo a raiz da sub-árvore direita. Também pode-se procurar o nó com menor valor da sub-árvore direita. Remove a chave, removendo o nó que contém a chave. E o pai do nó removido passa a apontar para a nova sub-árvore. Nivelamento - PIPCA 2012/1

33 Remoção por fusão 1 2 3 Final Nivelamento - PIPCA 2012/1

34 Remoção por fusão Nivelamento - PIPCA 2012/1
public void deleteByMerging (int el) { BSTNode tmp, node,father = null; node = search (el) ; // procura nó a ser deletado if (node != null && node.key==el) { // procura pai do nó a ser removido if (node!=root) father = searchFather (el); if (node.right == null){ // nó não tem filho direito (caso 2); if (root==node) root=node.left; else if (father.left == node) father.left = node.left; else father.right = node.left; } else if (node.left == null) { // nó não tem filho esquerdo (caso 2) if (root==node) root=node.right; else if (father.left == node) father.left = node.right; else father.right = node.right; else { // se tem dois filhos, faz deleção por fusão tmp = node.left; // pega sub-arvore esquerda while (tmp.right != null) tmp = tmp.right; // pega filho mais a direita da sub-arvore esquerda tmp.right = node.right; // o filho mais a direita da sub-arvore esquerda passa a ter // como filho direito o filho direito do nó a ser deletado if (root==node) root = node.left; else if (root != null) System.out.println("el " + el + " is not in the tree"); else System.out.println("the tree is empty"); Nivelamento - PIPCA 2012/1

35 Heap É uma estrutura de dados baseada em árvore (especializada) Propriedade do heap se B é filho de um nó A, então a chave(A) >= chave (B) (maior elemento na raiz). Chamada max heap. Pode-se comparar ao contrário, dai temos o min heap. Usado para implementar priority queues Applet: vamos ver o funcionamento

36 Max HEAP

37 Demo: construção da heap

38 A remoção do heap é feita ordenando os elementos.
Implementação A remoção do heap é feita ordenando os elementos. Implementação do heap através de array a: Indexação filhos a[2i+1] e a[2i+2] pais a[floor((i−1)/2)]

39 Heap binário -> usa-se árvore binária

40 É um heap criado usando-se árvore binária, com duas restrições:
Heap binário É um heap criado usando-se árvore binária, com duas restrições: Propriedade de shape: árvore completa (todos os níveis da árvores preenchidos, exceto possivelmente o último...) - preenchimento da esquerda para a direita Propriedade de heap: cada né á maior do que seus filhos Operações: Inserção Remoção Nivelamento - PIPCA 2012/1

41 Remoção da raiz do heap (maior elemento)
Exemplos Inserção Remoção da raiz do heap (maior elemento) Nivelamento - PIPCA 2012/1

42 Outros tipos Kd-tree d 2-d Quadtree Octree BSP Nivelamento - PIPCA


Carregar ppt "Árvores Binárias Profa. Patrícia A. Jaques Luiz Gonzaga Jr"

Apresentações semelhantes


Anúncios Google