170 likes | 266 Views
Árvores Balanceadas. André Lopes Pereira Luiz Carlos Barboza Júnior. Roteiro. Árvores de busca binárias: Organização; Algoritmos de busca, inserção e remoção em árvores de busca (custos envolvidos); Desvantagens de uma árvore desbalanceada: Aplicação de AVL;
E N D
Árvores Balanceadas André Lopes Pereira Luiz Carlos Barboza Júnior
Roteiro • Árvores de busca binárias: Organização; • Algoritmos de busca, inserção e remoção em árvores de busca (custos envolvidos); • Desvantagens de uma árvore desbalanceada: Aplicação de AVL; • Aplicação de nó crítico e fator de equilíbrio; • Rotações simples de dupla; • AVL implementada em C.
Árvores de busca binária Operações: Busca Inserir Deletar Definição: Todas as chaves da sub-árvore à esquerda são menores do que a chave da raiz, e as chaves da sub-árvore à direita são maiores. Essa regra define árvore de busca binária.
Busca Busca (root, x) Entrada: root (ponteiro pra raiz da árvore) e x número a ser procurado Saída: node (ponteiro que aponta para o nó contendo x ou nil se o nó não existir) início seroot = nil ou root^.keyentãonode := root // root^ e´o conteudo do endereco de root senao sex < root^.keyentão Busca (root^.left,x) senão Busca (root^.right,x) fim.
Inserir (root,x) Entrada: root (ponteiro pra raiz da árvore) e x número a ser inserido Saída: árvore modificada início seroot = nilentão crie um novo nó apontado por child; root := child; root^.key := x; senao node := root; child := root; //para inicializar e ele nao seja null enquantonode != nil e child != nilfaça senode^.key = xentãochild := nil senão parent := node; sex < node^.keyentãonode := node^.left senãonode := node^.right sechild != nilentão crie um novo nó apontado por child; child^.key := x; child^.left := nil; child^.right := nil; sex < parent^.keyentãoparent^.left := child senãoparent^.right := child fim Inserir
Deletar Deletar (root,x) Entrada: root (ponteiro pra raiz ) e x número a ser deletado Saída: árvore modificada início node := root; enquantonode != nil e node^.key != xfaça parent := node; sex < node^.keyentãonode := node^.left; senãonode := node^.right; senode = nilentãoimprima ("x não está na árvore"); sair senode != rootentão senode^.left = nilentão sex <= parent^.keyentãoparent^.letf := node^.right senãoparent^.right := node^.right senãosenode^.right = nilentão sex <= parent^.keyentãoparent^.left := node^.left senãoparent^.right := node^.left senão// o caso de 2 filhos node1 := node^.left parent1 := node enquanto node^.right != nil do parent1:= node1; node1:= node1^.right; parent1^.right := node1^.left node^.key := node1^.key fim
Deletar: folhas (...) senode^.left = nilentão sex <= parent^.key então parent^.letf := node^.right senão parent^.right := node^.right senãosenode^.right = nil então sex <= parent^.key então parent^.left := node^.left senão parent^.right := node^.left (...)
Deletar: nó com único filho (...) senode^.left = nilentão sex <= parent^.key então parent^.letf := node^.right senão parent^.right := node^.right senãosenode^.right = nil então sex <= parent^.key então parent^.left := node^.left senão parent^.right := node^.left (...)
Deletar: nó com dois filhos (...) senão// o caso de 2 filhos node1 := node^.left parent1 := node enquanto node^.right != nil do parent1:= node1; node1:= node1^.right; parent1^.right := node1^.left node^.key := node1^.key fim
Custos envolvidos Pior caso: Percorrer a árvore da raiz até a folha mais distante para localizar o nó desejado Tempo de execução dos outros passos é constante Custo O (log n) Árvore balanceada O (n) Lista encadeada AVL
AVL (Adel’son-Vel’skii e Landis) Definição: Árvore de busca binária que, para cada nó, a diferença entre as alturas de suas sub-árvores é no máximo 1
Balance Definição: Fator que indica a diferença entre a altura das sub-árvores da esquerda e da direita, precedido do sinal + (caso a da direita seja maior) ou - (caso a maior seja a da esquerda).
Balance Balance (root) Entrada: root (ponteiro pra raiz da arvore) Saída: todos os nós da árvore com o valor de balance início seroot = nil altura := -1 senãoroot^.left = nil e root^.right = nilentão altura := 0; root^.balance := 0; // se o no for um folha seu balance e´ 0 (zero) senão Esq := Balance (root^.left); Dir := Balance (root^.right); root^.balance := Dir - Esq; altura := Max (Esq, Dir); retorna (altura + 1) fim
Nó crítico (...) sebalance mudou de 0 para +1 ou -1 então retorne sim sebalance mudou de +1 ou -1 para 0 então retorne não se a resposta for simentão se o sim for pela direitaentãobalance := balance + 1 se o sim for pela esquerdaentãobalance := balance - 1 sebalance => 2 ou balance <= -2 então esse é o nó crítico. Aplique a rotação de acordo com a tabela:
Rotação simples Temp := B^.dir; B^.dir := A; A^.esq := temp;
Rotação dupla Temp := B^.dir; B^.dir := B^.dir^.esq; A^.esq := B^.dir^.dir; Temp^.esq := B; Temp^.dir := A;
Conclusão • Tipos de dados abstratos que manipulam estas três operações são chamados de dicionários (ordem lexicográfica); • A eficiência da árvore de busca é diretamente relacionada à sua altura. A estratégia é manter a árvore com a altura mínima possível utilizando as regras de AVL;