Lição
A teoria — Heap binário: uma fila de prioridades num vetor
Um heap mínimo binário é um vetor em que a chave de cada posição i é menor ou igual às chaves das posições 2i + 1 e 2i + 2, os seus filhos; o pai da posição i está em ⌊(i − 1) / 2⌋. Assim interpretado, o vetor representa uma árvore binária completa. A menor chave está sempre na posição 0, a raiz. Para inserir uma chave, coloque-a no fim e faça-a subir, trocando-a com o pai enquanto for menor do que ele. Para extrair a menor chave, passe a última para a raiz e faça-a descer, trocando-a com o menor dos filhos enquanto esse filho for menor do que ela. Um heap usado desta forma é uma fila de prioridades.
O que significa cada símbolo
n- número de chaves no heap
i- posição no vetor, a contar de 0
h- altura de uma posição: número de níveis abaixo dela, ⌊log₂(n / (i + 1))⌋
- Pressupõe
- Uma comparação confronta uma chave com outra; uma troca permuta as chaves de duas posições. Passar a última chave para a raiz durante uma extração não conta como nenhuma destas operações. Uma chave igual ao pai ou ao menor dos filhos fica onde está. Se os filhos forem iguais, escolhe-se o da esquerda. Este heap mantém a menor chave na raiz; num heap máximo, inverte-se o sentido de todas as comparações. A ferramenta permite até quinze chaves, de 0 a 99, para que a árvore inteira caiba no ecrã de um telemóvel. As permutações contadas na última linha são de chaves distintas.
Problema resolvido na íntegra
-
Quantas comparações exige cada método com mil chaves? 4 passos
Prima Decrescente, uma a uma e depois Decrescente, último pai. Explique os valores 34 e 22. Considere agora 1.023 chaves que chegam por ordem decrescente. Quantas comparações faz cada método?
Abrir este problema na ferramenta
-
A posição i tem profundidade ⌊log₂(i + 1)⌋: uma posição à profundidade 0, duas à profundidade 1, quatro à profundidade 2 e oito à profundidade 3. Por ordem decrescente, cada nova chave é a menor até ao momento e sobe até à raiz, com uma comparação e uma troca por nível: 0 + 2 · 1 + 4 · 2 + 8 · 3 = 34.
-
Na construção a partir do último pai, conta a altura: 3 para a raiz, 2 para as posições 1 e 2, 1 para as quatro posições à profundidade 2 e 0 para as oito folhas. A soma é 11. Por ordem decrescente, cada chave desce até ao fundo. Com quinze chaves, todos os pais têm dois filhos, pelo que cada nível exige duas comparações: 22 comparações e 11 trocas.
-
1.023 = 2¹⁰ − 1 corresponde a uma árvore perfeita com dez níveis e 2ᵈ posições à profundidade d. Na inserção uma a uma, o número de comparações é a soma das profundidades: 1 · 2 + 2 · 4 + 3 · 8 + ⋯ + 9 · 512 = 8.194. Há outras tantas trocas.
-
A construção a partir do último pai exige o dobro da soma das alturas. Há 2⁹ posições de altura 0, 2⁸ de altura 1, e assim sucessivamente até à raiz, de altura 9: 1 · 256 + 2 · 128 + ⋯ + 9 · 1 = 1.013. Este valor é 1.023 menos os dez algarismos 1 da sua representação binária. O dobro dá 2.026 comparações, com 1.013 trocas.
Resposta
8.194 comparações na inserção uma a uma e 2.026 na construção a partir do último pai: cerca de oito por chave no primeiro método e duas no segundo. A maioria das posições de um heap tem grande profundidade e pequena altura. O custo da inserção depende da profundidade; o da construção a partir do último pai depende da altura. A ferramenta admite até quinze chaves, para as quais o mesmo cálculo dá os valores 34 e 22 apresentados.
-
Percurso de aprendizagem
O que custa pouco numa estrutura de dados
Referências (2)
- Heapsort as first published: J. W. J. Williams, "Algorithm 232: Heapsort," Communications of the ACM 7(6), 347–348, June 1964.
- The heap-based sort published six months later, close to the version used today: Robert W. Floyd, "Algorithm 245: Treesort 3," Communications of the ACM 7(12), 701, December 1964.