• Nenhum resultado encontrado

Algoritmos e Estruturas de Dados. Décima primeira aula: Árvores chanfradas

N/A
N/A
Protected

Academic year: 2021

Share "Algoritmos e Estruturas de Dados. Décima primeira aula: Árvores chanfradas"

Copied!
25
0
0

Texto

(1)

Algoritmos

e Estruturas de Dados

Décima primeira aula: Árvores chanfradas

(2)

20-06-2012 Algoritmos e Estruturas de Dados I - 11 © Pedro Guerreiro 2

Nesta aula vamos

• Estudar as árvores chanfradas, que são umas árvores absolutamente fantásticas. • Há outras classes de árvores fantásticas,

mas não temos tempo para todas: so

many trees, so little time. 

• Mesmo assim, mencionaremos as árvores AVL, as árvores rubinegras e as B-trees.

(3)

20-06-2012 Algoritmos e Estruturas de Dados I - 11 © Pedro Guerreiro 3

Árvores chanfradas

(splay trees)

• As árvores chanfradas (splay trees) são árvores binárias de busca auto-ajustáveis. Depois de

uma operação de acesso, o elemento acedido é

promovido até à raiz.

• A ideia é acelerar os acessos subsequentes aos nós mais recentemente acedidos.

• A promoção é feita de dois em dois níveis, excepto quando o nó está no primeiro nível.

• Foram inventadas por Sleator e Tarjan em 1985. Daniel Sleator é professor na Universidade

Carnagie-Mellon e Robert Tarjan é professor na Universidade de Princeton.

(4)

20-06-2012 Algoritmos e Estruturas de Dados I - 11 © Pedro Guerreiro 4

Promoção

• Promover um nó é subi-lo de nível,

fazendo descer o pai pelo lado contrário.

X Y c a b Y X c a b

Em ambas as árvores, num percurso directo primeiro vamos ao a, depois ao X, depois ao b, depois ao Y e depois ao c.

(5)

20-06-2012 Algoritmos e Estruturas de Dados I - 11 © Pedro Guerreiro 5

Rotação para a direita

• A ligação XY roda para a direita:

X Y c a b Y X c a b

A promoção de um nó faz-se por meio de uma rotação da ligação ao seu pai. Neste caso, é uma rotação para a direita.

(6)

20-06-2012 Algoritmos e Estruturas de Dados I - 11 © Pedro Guerreiro 6

Rotação para a esquerda

• A ligação XY roda para a esquerda:

Y X c a b X Y c a b

Em qualquer dos casos, se a árvore for uma árvore de busca, após a rotação continua a ser uma árvore de busca.

(7)

20-06-2012 Algoritmos e Estruturas de Dados I - 11 © Pedro Guerreiro 7

tree_promote

• A promoção envolve um subtil rearranjo dos apontadores. • É “só” preciso ter cuidado:

Tree tree_promote (Tree t) {

int side = tree_side (t); Tree p = t−>parent;

t −> parent = p−>parent; if (t−>parent != NULL)

t −> parent −> child [tree_side (p)] = t;

p −> child [side] = t−>child [!side]; if (p −> child [side] != NULL)

p −> child [side] −> parent = p; t −> child [!side] = p; p−>parent = t; return t; } Veja com cuidado!

Note que esta função roda para o lado certo, sem usar if’s.

Mudam seis apontadores

(8)

20-06-2012 Algoritmos e Estruturas de Dados I - 11 © Pedro Guerreiro 8

Ziguezague

• Nas árvores chanfradas, quando filho e pai estão de lados diferentes, promove-se em ziguezague:

X Y c a b d Z Y X b c a d Z Z Y b c a d X

Chama-se ziguezague porque as rotações são em sentido diferente: neste caso, primeiro

para a esquerda, depois para a direita.

Depois do ziguezague, a árvore está localmente

equilibrada no nó promovido e tanto este como as suas subárvores estão mais perto da raiz.

(9)

20-06-2012 Algoritmos e Estruturas de Dados I - 11 © Pedro Guerreiro 9

Ziguezigue

• Quando filho e pai estão do mesmo lado, promove-se em “ziguezigue”: X Y b c a d Z Z Y d b c a X Z X b c a d Y

Note bem: neste caso primeiro promove-se o pai do nó e depois o nó.

As duas rotações são para o mesmo lado, (neste caso para a direita). Por oposição ao ziguezague, isto chama-se ziguezigue.

Depois do ziguezigue, as subárvores do nó promovido estão mais próximas da raiz.

(10)

20-06-2012 Algoritmos e Estruturas de Dados I - 11 © Pedro Guerreiro 10

Chanfrando

• Chanfrar (to splay) um nó é promovê-lo até à raiz em ziguezague e em

ziguezigue, excepto eventualmente a

última promoção que poderá ser simples se a profundidade inicial era ímpar.

• Após aceder a um nó, chanframo-lo. Assim, se ele for acedido de novo, em

breve, será apanhado mais depressa, em média.

(11)

20-06-2012 Algoritmos e Estruturas de Dados I - 11 © Pedro Guerreiro 11

Tree tree_splay (Tree t) {

assert (t != NULL);

while (t −> parent != NULL && t−>parent−>parent != NULL) if (tree_side (t) == tree_side (t−>parent))

{ // zigzig tree_promote (t−>parent); tree_promote (t); } else { // zigzag tree_promote (t); tree_promote (t); } if (t −> parent != NULL) tree_promote (t); return t; }

tree_splay

Enquanto não o nó t não chegar à raiz ou aos filhos da raiz, promove-se, em ziguezigue ou em ziguezague.

Se ficou num filho da raiz, promove-se mais uma vez, simplesmente.

(12)

20-06-2012 Algoritmos e Estruturas de Dados I - 11 © Pedro Guerreiro 12

splay_tree_find

• Ao procurar, se encontramos, chanframos o nó; se não encontramos, chanframos o pai “virtual” (isto é, o nó que seria o pai do nó encontrado se o valor procurado existisse):

Tree splay_tree_find (Tree t, int x) {

Tree result = NULL; Tree p = t;

Tree q = NULL;

while (p && p−>value != x) { q = p; p = p−>child [p−>value < x]; } if (p == NULL) { if (q != NULL) result = tree_splay (q); } else result = tree_splay (p) ; return result; } Não encontrámos: chanframos o pai. Encontrámos: chanframos o nó.

(13)

20-06-2012 Algoritmos e Estruturas de Dados I - 11 © Pedro Guerreiro 13

splay_tree_put

• Depois de pôr, chanframos o nó. • Isto é, se o valor não existia, chanframos o novo nó. Se já existia, chanframos o nó respectivo

Tree splay_tree_put (Tree t, int x) {

Tree result = NULL; Tree p = t;

Tree q = NULL; int side = 0;

while (p && p−>value != x) {

q = p;

p = p−>child [side = p−>value < x]; }

if (p == NULL)

{

assert (q == NULL || q−>value != x); result = tree_cons (x, NULL, NULL); if (q != NULL)

q−>child [side] = result; result−>parent = q;

} else

result = p;

result = tree_splay (result); return result; } Novo nó. O valor já existia, e está no nó apontado por p.

(14)

20-06-2012 Algoritmos e Estruturas de Dados I - 11 © Pedro Guerreiro 14

splay_tree_remove

• Remove-se e chanfra-se o pai do nó removido:

Tree splay_tree_remove (Tree t) {

Tree result = NULL;

search_tree_remove (&t); if (t != NULL)

result = tree_splay (t); return result;

(15)

20-06-2012 Algoritmos e Estruturas de Dados I - 11 © Pedro Guerreiro 15

void test_find (void) {

Tree t = NULL; int n;

int limit; int x;

scanf ("%d%d", &n, &limit); t = search_tree_rand (n, limit);

tree_write_diagram (stdout, "%d", t, 3, 0); tree_writeln_star (stdout, t);

tree_writeln (stdout, " %d", t); printf ("−−−−−−−−−−\n");

while (scanf ("%d", &x) != EOF) {

t = splay_tree_find (t, x);

if (t == NULL || t −> value != x) printf ("not found.\n");

tree_write_diagram (stdout, "%d", t, 3, 0); tree_writeln_star (stdout, t); tree_writeln (stdout, " %d", t); printf ("−−−−−−−−−−\n"); } tree_free (&t); }

Experimentando o

splay_tree_find

Cria uma árvore com n nós, com valores aleatórios entre 0 e n.

(16)

20-06-2012 Algoritmos e Estruturas de Dados I - 11 © Pedro Guerreiro 16

Árvores perfeitamente equilibradas

• Uma árvore é perfeitamente equilibrada se para cada nó o tamanho das suas subárvores diferir de 1 no máximo. Exemplos: 65 80 32 71 81 44 12 24 99 31 16 4 52 5 61 91 32 2 14 11 59 41 12 33 42 54 7 1 Esta não é perfeitamente equilibrada.

(17)

20-06-2012 Algoritmos e Estruturas de Dados I - 11 © Pedro Guerreiro 17

Árvores equilibradas

• Uma árvore é equilibrada se para cada nó a altura da suas subárvores diferir de 1 no máximo. 4 12 8 9 14 15 1

• Manter uma árvore equilibrada é menos complicado do que

mantê-la perfeitamente equilibrada, ao pôr e ao remover.

Esta é equilibrada mas não perfeitamente

(18)

20-06-2012 Algoritmos e Estruturas de Dados I - 11 © Pedro Guerreiro 18

Árvores AVL

• Uma árvore AVL é uma árvore de busca equilibrada.

• “AVL” são as iniciais dos inventores, os matemáticos russos Adelson-Velskii e Landis (1962).

• Em certas implementações, os nós das árvores AVL têm um membro que guarda a altura da subárvore cuja raiz é esse nó (ou a diferença da altura com a subárvore “irmã”).

(19)

20-06-2012 Algoritmos e Estruturas de Dados I - 11 © Pedro Guerreiro 19

Árvores rubinegras (

red

-black)

• Uma árvore rubinegra (red-black tree) é uma árvore binária de busca, com

sentinela, em que cada nó tem uma de duas cores: vermelho ou preto.

• Restringindo as maneiras de colorir os nós ao longo dos caminhos da raiz até às

folhas, garante-se que nenhum caminho tem mais do dobro dos nós do que

qualquer outro. Assim, a árvore fica “aproximadamente” equilibrada.

(20)

Sentinela

20-06-2012 Algoritmos e Estruturas de Dados I - 11 © Pedro Guerreiro 20

Propriedades das árvores

rubinegras

• Cada nó ou é vermelho ou é preto. • A raiz é preta. • A sentinela é preta. • Se um nó é vermelho, os seus dois filhos são

pretos. • Todos os caminhos desde um nó até à sentinela têm o mesmo número de nós pretos. 3 34 20 22 21 37 55 29

(21)

20-06-2012 Algoritmos e Estruturas de Dados I - 11 © Pedro Guerreiro 21

B-trees

• Uma b-tree é uma árvore de busca equilibrada, desenhada para ter um bom desempenho em dispositivos de memória secundária de acesso directo.

• Os nós das b-trees podem ter muitos filhos (e não apenas dois).

• As b-trees são uma generalização das árvores binárias de busca, como mostra o exemplo:

134

24 70 160 215 244

(22)

20-06-2012 Algoritmos e Estruturas de Dados I - 11 © Pedro Guerreiro 22

Propriedades das B-trees

• Numa b-tree, cada nó tem vários valores e vários filhos. Os nós que são folhas não têm filhos. Os nós internos que tenham n valores têm n+1 filhos.

• O número mínimo de filhos num nó interno de uma

árvore é o grau mínimo da árvore. Se o grau mínimo

for t cada nó tem pelo menos t−1 valores. Numa b-tree de grau mínimo t, o número máximo de valores num nó é 2t−1 e, portanto, o número máximo de

filhos é 2t.

• Os valores num nó estão ordenados e separam os valores das subárvores correspondentes.

• Ao pôr e ao remover, é preciso garantir que as propriedades da b-tree se mantêm.

(23)

20-06-2012 Algoritmos e Estruturas de Dados I - 11 © Pedro Guerreiro 23

Exercícios

• Programe as AVL com campo para a altura.

• Investigue e programa as árvores rubinegras.

(24)

20-06-2012 Algoritmos e Estruturas de Dados I - 11 © Pedro Guerreiro 24

Controlo

• Que tipos de árvores estudámos?

• O que é o ziguezigue? E o ziguezague? • Chanframos o quê, quando o que

procuramos não existe?

• Quem inventou as splay trees? E as AVL? • Qual é a diferença entre as árvores

equilibradas e as árvores perfeitamente equilibradas.

(25)

20-06-2012 Algoritmos e Estruturas de Dados I - 11 © Pedro Guerreiro 25

Na próxima aula

• Abandonaremos as árvores e passaremos para a estrutura de dados seguinte: as

Referências

Documentos relacionados

A licença simples é transmissível por morte do seu titular para os seus herdeiros legais, sendo válida para o ano a que disser respeito. Para o caso de pessoas colectivas a

Conhecer outras variáveis que possam influenciar a altura arbórea é importante para o direcionamento de práticas de manejo florestal que busquem sua maximização.. As principais

Essa pesquisa tem como objetivo geral relacionar alterações na paisagem da região florestal denominada de “Matas de São Patrício” (MSP), com delimitação da

Os jogos nos ajudam a definir o profissional mais adequado para o perfil do cargo, de forma mais rápida e eficaz, uma vez que, nos permite visualizar seu desempenho em

– Os elementos devem estar ordenados – Realizar a busca pelo meio do vetor.

Utilizar árvores binárias com altura da mesma ordem de grandeza ( O(log 2 n) ) que a de uma árvore completa de mesmo número de nós (1+log 2 n). É desejável também que

não é necessário construir a árvore a partir do nó raiz, como é feito para árvores em memória. principal e para as

c) Pressione a softkey Armazenar; em seguida, gire o botão Entrada para destacar PNG e aperte o botão Entrada para selecionar esse como o tipo de arquivo;.. d) Pressione