You are on page 1of 42

rvores Binrias

Profa. Patrcia A. Jaques Luiz Gonzaga Jr Contribuies

Algumas transparncias so da profa. Renata Galante da II/UFRGS com permisso

rvore Binria uma rvore onde cada n pode conter nenhum, 1 ou 2 filhos apenas
Grau=2.

Uma rvore binria formada por ns onde cada n contm um valor, um ponteiro esquerdo e um ponteiro direito.
A B C

G
Nivelamento - PIPCA 2012/1 2

rvore Binria 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 ns B e C e estes dois so irmos.
A
filho esquerdo de A B C filho direito de A

Nivelamento - PIPCA 2012/1

Tipos de rvores Binrias: Estritamente Binria

Ocorre quando todo n que no folha tiver sub-arvores esquerda e direita no vazias.
todo n tem 0 ou 2 filhos.

Nmero de ns em uma rvore estritamente binria com n folhas:


2n-1 Estritamente Binria

bibliografia:Szwarcfiter, J. & Markenzon, Lilian. Estrturas de Dados e seus Algoritmos. Rio de Janeiro: LTC, 1994

Nivelamento - PIPCA 2012/1

Tipos de rvores Binrias: Binria Completa uma rvore estritamente binria onde todos os ns folhas se encontram ou no ltimo ou no penltimo nvel da rvore.

Binria Completa
bibliografia:Szwarcfiter, J. & Markenzon, Lilian. Estrturas de Dados e seus Algoritmos. Rio de Janeiro: LTC, 1994

Nivelamento - PIPCA 2012/1

Tipos de rvores Binrias: Binria Cheia


bibliografia:Szwarcfiter, J. & Markenzon, Lilian. Estrturas de Dados e seus Algoritmos. Rio de Janeiro: LTC, 1994

Binria Cheia

rvore estritamente binria onde os ns folhas se encontram no ltimo nvel. O nmero total de ns em (tn) em uma rvore binria cheia de altura h :
Assim, pela mesma frmula podemos afirmar que, numa rvore binria completa, a altura h de uma rvore dada por: Embora a rvore binria completa possua muitos ns, a distncia da raiz at qualquer folha (profundidade) relativamente pequena.
Nivelamento - PIPCA 2012/1 6
h= log2(tn+1) tn=2h-1

rvores Binrias: representao


Endereo da raiz

A B
D E F

referncia para filho esquerdo

C
B C

referncia para filho direito

G
D
chave do n
Nivelamento - PIPCA 2012/1 7

Aplicao de rvores Binrias Representao de expresses aritmticas em rvores binrias


Dada uma expresso aritmtica, sua representao em rvore binria feita de tal forma que a ordem de prioridade das operaes fica implcita.

Regra: O operador de menor prioridade aparece na raiz; A sub-expresso esquerda desse operador d origem sub-rvore esquerda; A sub-expresso direita do operador d origem sub-rvore direita.

Nivelamento - PIPCA 2012/1

Representao de expresses aritmticas em rvores binrias

B
Ex: A + B * C

Obs. Operandos sempre aparecem como folhas; operadores, nunca.

Nivelamento - PIPCA 2012/1

Representao de expresses aritmticas em rvores binrias

Caminhamentos: Em pos-ordem Notao polonesa ps fixada.


Ex: A B C * + (na primeira expresso);

Em in-ordem Forma original (infixada) sem parnteses.


Ex: A + B * C (primeira expresso);

Em pr-ordem Notao polonesa prefixada (sem grande utilidade).


Ex: + A * B C (primeira expresso);

Obs. A notao polonesa ps fixada muito til (principalmente para as mquinas), pois exibe os operadores na ordem de execuo das operaes.
Nivelamento - PIPCA 2012/1 10

Algoritmo para gerar uma rvore binria a partir de uma expresso aritmtica em notao infixa
Procedimento Interpretar(string)->ponteiro COMEO 1. fazer uma rvore com a string como nico n; 2. procurar por operadores de MENOR precedncia (+ ou -) que no estejam dentro de ( e ), pois estes sero considerados um operando.

3. repetir o procedimento 2 com operadores de MDIA precedncia (* e /) S EM NS FOLHA; 4. repetir o procedimento para operadores com MAIOR precedncia (s o ^); 5. percorrer os nos folha (todos contm operandos)
se o operando nmero ou varivel, no mexe. se o operando expresso entre parntesis, substituir esse n por Interpretar(expresso sem os parntesis);

se tem, substitua a rvore por uma com o operador no n raiz e com os operandos nos ns folha. (se voc procurar o PRIMEIRO operando com menor precedncia, basta dividir a rvore como explicado e aplicar esse procedimento de procurar operador de menor precedncia recursivamente no n da DIREITA). Lembre-se que um operando um nmero, uma varivel uma expresso entre parntesis ou uma funo.

FIM Interpretar.

Nivelamento - PIPCA 2012/1

11

Algoritmo para avaliar a rvore (calcular a expresso)


Algoritmo eval (BinaryTreeNode v) { /* recebe n raiz como parmetro: a classe BinaryTreeNode, alm dos ponteiros para filhos esquerdo e direito, tambm contm outros dois atributos: 1) char operador; 2) double operando; real retorno 0; if v == null { no tem rvore - devolve valor zero } then retorno 0; else if v.operador== /* se operando igual , ento n guarda operando*/ then return v.operando; //devolve valor contido no nodo else switch a.operador { //operador - executa operao 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

12

rvore Binria de Pesquisa Tambm chamada de:


rvore binria de busca ou rvore binria ordenada

apresentam uma relao de ordem entre os nodos ordem definida por um campo denominado chave no permite chaves duplicadas, ou seja, cada n tem um valor de chave diferente
esq chave dir

Nivelamento - PIPCA 2012/1

13

rvore Binria de Pesquisa no h chaves duplicadas 500


filho da esquerda: valor da chave menor que o valor da chave do n pai

raiz
filho da direita: valor da chave maior que o valor da chave do n pai

300

800

150

400

600

900

fazer exerccio: criar rvore inserindo ns na seguinte ordem: f, a, t, b, e, u, i, c, d, a, e

Nivelamento - PIPCA 2012/1

14

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

15

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 16

Busca de um valor
A procura de um valor em uma rvore binria algo mais rpido 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, seno v para a sub-rvore direita.

A busca pra quando for encontrado o n ou quando no h mais meios de continuar (n folha), pois a chave no est na rvore. A complexidade pode ser medida pelo nmero de comparaes feitas durante o processo de busca. Isso depende do nmero de ns encontrados no nico caminho que leva da raiz ao n procurado. Ento a complexidade, depende da forma da rvore e da posio do n procurado na rvore. O nmero mdio de comparaes em uma busca (lg n), pois a altura de uma rvore binria completa (perfeitamente balanceada) h=lg (n+1) .
Nivelamento - PIPCA 2012/1 17

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 referncia 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 no foi achada, retorna null return null; }

Nivelamento - PIPCA 2012/1

18

Inserindo uma nova chave


public boolean insert (int el) { BSTNode p = root, prev = null; // caso o valor j exista na rvore, no 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

19

Caminhamento (percurso) em rvore binria 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 ns em uma linha ou a linearizao da rvore. Os percursos podem ser em extenso ou em profundidade.
Percursos em extenso: visitam todos os ns de cada nvel, nvel por nvel (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 20

Caminhamento (percurso) em rvore binria de pesquisa

Os trs mais comuns tipos de percursos em profundidade, definidos recursivamente, so:


PR-ORDEM (raiz-esquerda-direita):
visita o n; percorre a sub-rvore esquerda; percorre a sub-rvore direita;

PS-ORDEM (esquerda-direita- raiz):


percorre a sub-rvore esquerda; percorre a sub-rvore direita; visita o n;

IN-ORDEM (esquerda-raiz-direita):
percorre a sub-rvore esquerda; visita o n; percorre a sub-rvore direita.

Nivelamento - PIPCA 2012/1

21

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 22

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 23

Percurso em ps-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 24

Remoo de um n

Na remoo 3 situaes podem ocorrer :


Caso 1: Excluso de uma folha O n uma folha e no tem filhos: O ponteiro do seu pai ajustado para nulo.

antes

50

depois

50

30

80

30
90

80

15

40

60

40

60

90
25

Nivelamento - PIPCA 2012/1

Remoo 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
90
Nivelamento - PIPCA 2012/1

80

40

60

60

90
26

Remoo de um n Caso 3: O n tem 2 filhos. Neste caso podemos fazer a remoo de duas maneiras:
remoo por cpia; remoo por fuso

antes

50

30

80

15

40

60

90
27

Nivelamento - PIPCA 2012/1

Remoo por cpia 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 ento removendo o n que contem k2 (que ser um dos casos simples: folha, ou n com apenas um filho).

Nivelamento - PIPCA 2012/1

28

Remoo por cpia 1 2 3

Final

Nivelamento - PIPCA 2012/1

29

N que retorna referncia 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; }

Remoo por cpia


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 no 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 no 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 remoo por cpia BSTNode tmp = node.left; // 1. pegando sub-arvore esquerda while (tmp.right != null) // 2. acha a posio 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 subrvore 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

31

Remoo por fuso A soluo consiste em fusionar as duas subrvores do n a ser deletado em uma. Para tanto, como na organizao da rvore binria, todos os valores da sub-rvore a esquerda so 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. Tambm pode-se procurar o n com menor valor da sub-rvore direita. Remove a chave, removendo o n que contm a chave. E o pai do n removido passa a apontar para a nova sub-rvore.

Nivelamento - PIPCA 2012/1

32

Remoo por fuso 1 2 3

Final

Nivelamento - PIPCA 2012/1

33

Remoo por fuso


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 no 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 no 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 deleo por fuso 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 (father.left == node) father.left = node.left; else father.right = node.left; } } else if (root != null) System.out.println("el " + el + " is not in the tree"); Nivelamento - PIPCA 2012/1 34 else System.out.println("the tree is empty"); }

Heap uma estrutura de dados baseada em rvore (especializada) Propriedade do heap se B filho de um n A, ento a chave(A) >= chave (B) (maior elemento na raiz). Chamada max heap. Pode-se comparar ao contrrio, dai temos o min heap. Usado para implementar priority queues Applet: vamos ver o funcionamento http://people.ksp.sk/~kuko/bak/index.html

Max HEAP

Demo: construo da heap

http://students.ceid.upatras.gr/~perisian/data_struct ure/HeapSort/heap_applet.html

Implementao A remoo do heap feita ordenando os elementos. Implementao do heap atravs de array a:

Indexao
filhos a[2i+1] e a[2i+2] pais a[floor((i1)/2)]

Heap binrio -> usa-se rvore binria

Heap binrio um heap criado usando-se rvore binria, com duas restries:
Propriedade de shape: rvore completa (todos os nveis da rvores preenchidos, exceto possivelmente o ltimo...) preenchimento da esquerda para a direita Propriedade de heap: cada n maior do que seus filhos

Operaes:
Insero Remoo

Nivelamento - PIPCA 2012/1

40

Exemplos Insero

Remoo da raiz do heap (maior elemento)

Nivelamento - PIPCA 2012/1

41

Outros tipos Kd-tree 2-d 3-d

BSP

Quadtree

Octree

Nivelamento - PIPCA

42

You might also like