Árvores Equilibradas Sumário Splay B-tree Vermelho-Preto AA e BB Multidimensionais quaternárias k-d Pesquisa Lexicográfica tries multivia tries binárias PATRICIA VP Árvores Vermelho-Pretas correspondem a uma transformação de árvores-B, em particular a de ordem 4 para uma representação em árvore binária de pesquisa os filhos de um nó da árvore-B podem ser representados por uma lista ligada ou por outra estrutura, como as árvores binárias de pesquisa os ramos desta, internos a um nó da árvore-B, são os ramos vermelhos e os ramos que ligam diferentes nós da árvore-B são os ramos pretos (a cor de um nó é a cor do ramo que lhe fica imediatamente acima; a raiz é preta) a pesquisa e a travessia é a de uma árvore binária; inserção e apagamento leva em conta a cor; processamentos O(log n) Uma árvore vermelho-preta é uma árvore binária de pesquisa em que cada nó tem a cor vermelho ou preto e que satisfaz 1. Cada caminho simples da raiz até uma subárvore vazia passa pelo mesmo número de nós pretos (equilíbrio). 2. Se um nó é vermelho, então tem um pai e este é preto. - a condição 2 garante a identificação das subestruturas internas a cada nó VP Árvore-B como Vermelho-Preta j f m d s u h e b g i k o c a l n p w r t v x VP Transformação de nós b a b c T1 T2 T3 a T1 T4 c T2 T3 T4 a a b b b a T1 T1 T2 T3 T3 T2 T3 T1 T2 VP Inserção genericamente, o algoritmo de inserção começa na raiz, compara as chaves para escolher a subárvore e é recursivo até encontrar uma subárvore vazia, onde cria um nó o novo nó é vermelho, para garantir a condição preta (nas árvores-B a inserção também começava por ser num nó pre-existente) se o pai do novo nó for preto, termina; se for vermelho, viola-se a condição 2; adia-se a correcção do problema; retorna-se indicação de estado de que se processou um nó vermelho está-se agora no pai: se for preto, tudo bem; se for vermelho, anota-se no estado o problema, em conjunto com a indicação de o filho ser esquerdo ou direito estamos no avô, que tem que existir e é preto; neste nível recursivo corrige-se o problema do neto: - se o tio for preto (ou não existir), basta fazer uma rotação simples ou dupla, para o lado do tio; - se o tio for vermelho, troca-se o pai e o tio para preto e o avô para vermelho o problema recomeça, agora entre o avô e o bisavô, com a indicação de estado de nó vermelho; pode-se chegar a mudar a cor da raiz para vermelho, o que obriga a chamada exterior a repor a cor em preto VP Repor condições de vermelho e preto avô pai pai tio T4 filho T1 avô filho tio T3 Rotação à direita T1 T2 T3 T4 T2 avô filho pai tio T4 Dupla rotação à direita filho avô pai T1 tio T2 T3 T1 T2 T3 T4 VP Repor condições de vermelho e preto avô pai avô pai tio Mudança de cor filho T1 T2 filho T3 T1 T2 avô pai tio T3 avô pai tio tio Mudança de cor T1 filho T2 T3 T1 filho T2 T3 VP Árvores BB e AA Árvore BB: B e Binária vermelho-preto cada nó tem no máximo 1 filho vermelho Árvores AA como BB mas só filhos direitos podem ser vermelhos reduz casos de reequilíbrio remoção: filho único de nó interno é vermelho (da condição VP); chave do nó a apagar é substituída pela menor da subárvore direita em vez de cor, nível do nó nível = 1 nível = nível do pai nível = nível do pai -1 nas folhas em nó “vermelho” em nó “preto” VP Árvores AA Propriedades filho esquerdo tem nível 1 unidade abaixo do do pai filho direito tem nível 0 ou 1 unidade abaixo do do pai ligação ao filho direito: horizontal 30 70 15 5 10 50 20 35 40 60 55 85 65 80 90 VP Árvores AA - Equilíbrio Desequilíbrio por ligação horizontal à esquerda resolve com rotação à direita (skew) X A 2 P B X C A 5 10 P B C Desequilíbrio por ligação horizontal à esquerda resolve com rotação à esquerda (split) 35 40 45 R X R G X G C A B C A B VP Inserção em Árvores AA insere(Elemento x, Arvore t) if ( x < t.elemento) t.left = insere( x, t.left); else if (x > t.elemento) t.right = insere( x, t.right); else return t; t = skew(t); t = split(t); skew: split: rotação com filho esquerdo se rotação com filho direito se t.left.level == t.level t.right.right.level == t.level VP Árvores AA - Inserir 3 30 70 2 15 50 60 85 1 5 10 20 35 40 45 depois de split em 35 ... 80 90 3 ... 70 3 70 2 40 35 65 depois de skew em 50 2 1 55 50 45 ... 60 55 65 40 1 35 50 45 ... 60 55 65 VP Árvores AA - Inserir depois de split em 40 3 30 ... 70 50 2 40 85 60 1 35 55 45 65 80 90 depois de skew em 70 3 30 70 50 2 40 ... 1 35 85 60 45 55 65 80 90 VP Árvores AA - Inserir depois de split em 30 4 50 3 70 30 2 15 40 85 60 1 5 10 20 35 45 55 65 80 90 Árvore aumentou 1 nível Crescimento é na raiz, à maneira das árvores B VP Árvores AA - Remover Nó que não é folha tem filho direito (se tem filho esquerdo, pela condição de Vermelho-Preto) pode substituir-se pelo menor da subárvore direita - este tem de estar ao nível 1 porque não pode ter filho esquerdo (é o menor) e se tiver filho direito é do mesmo nível para remover, descer na árvore mantendo registo do nó a apagar e do mínimo ao chegar ao fundo da árvore: substituir nó a apagar pelo mínimo e remover o mínimo ajustar nós e seus níveis, e reequilibrar se necessário 5 2 1 3 4 6 7 Ao apagar 1: . 2 passa a ser nível 1 . 5 passa a ser nível 1 Se 5 é nível 1, . 6 e 7 são nível 1 . Ligação a 3 é horizontal . 3 e 4 são de nível 1 VP Árvores AA - Remover 5 2 1 3 2 3 4 6 3 4 5 6 7 depois de skew em 5 (com 4) 2 7 3 depois de split em 2 4 5 6 7 depois de split em 4 3 2 6 4 7 depois de skew em 5 (com 3) 2 5 3 4 5 6 7 2 5 4 6 7 VP Treaps Características Nó da árvore: 1 elemento, 2 nós filhos e a prioridade Prioridade de um nó não inferior à do seu pai Propriedades nó de menor prioridade é raiz colecção de elementos distintos com prioridades distintas: árvore é única código simples eficiência esperada O(log N) Operações Inserção: inserir folha e rodar para cima até satisfazer prioridades Apagamento: pesquisar elemento, passar prioridade a , rodar para baixo até ser folha, apagar VP