Um heap é uma árvore binária completa onde cada pai satisfaz a propriedade heap - seja sempre menor (heap mínimo) ou sempre maior (heap máximo) que seus filhos. "Completo" significa que todos os níveis estão cheios, exceto possivelmente o último, que é preenchido da esquerda para a direita.
1 Min-heap
/ \
3 5
/ \
7 4
Por estar completo, nós o armazenamos em um flat array - sem necessidade de ponteiros. Para índice i: filho esquerdo = 2i + 1, filho direito = 2i + 2, pai = (i - 1) // 2.
| Propriedade | Heap mínimo | Heap máximo | |----------|----------|----------| | Raiz | Elemento menor | Maior elemento | | Pai ≤ Filhos? | ✅ Sim | ❌ Não (≥) | | Extrato dá | Mínimo | Máximo |
O heapq do Python é um min-heap por padrão. Para um heap máximo, negue os valores na inserção e negue novamente na extração.
Inserir - pressione até o final e, em seguida, aumente a bolha (troque com o pai enquanto menor):
import heapq
h = [1, 3, 5, 7]
heapq.heappush(h, 2) # h becomes [1, 2, 5, 7, 3]
Extrair min - troque a raiz com o último elemento, pop por último e peneire (troque com o filho menor):
smallest = heapq.heappop(h) # returns 1
Ambas as operações são executadas em O(log n) porque a altura da árvore é log n.
Chamar converte uma lista em um heap em O(n), não em O(n log n). Ele funciona de baixo para cima, analisando cada nó que não é folha. Este é um dos resultados de complexidade mais surpreendentes em CS.
Entrar participar da discussão
heapq.heapify(arr)Uma fila de prioridade permite que você sempre acesse primeiro o item de maior prioridade. Heaps são a implementação ideal porque tanto a inserção quanto a extração são O (log n). Use um sempre que precisar "dê-me o melhor item até agora".
"Encontre os K maiores elementos em uma matriz não classificada."
Mantenha um min-heap de tamanho K. Para cada elemento, empurre-o; se o heap exceder K, coloque o menor. O que resta são os K maiores.
import heapq
def top_k(nums, k):
return heapq.nlargest(k, nums)
Tempo: O(n log k) - muito melhor do que classificar quando k ≪ n.
Você precisa das 5 maiores pontuações de 1 milhão de entradas. Qual tipo e tamanho de heap?
Empurre o cabeçalho de cada lista para um heap mínimo. Abra o menor e, em seguida, pressione o próximo elemento da mesma lista. Repita até que todas as listas se esgotem. Tempo: O(N log K) onde N é o total de elementos.
Mantenha dois heaps: um max-heap para a metade inferior e um min-heap para a metade superior. Equilibre seus tamanhos para que difiram no máximo 1. A mediana está sempre em uma ou ambas as raízes.
Lower half (max-heap): [1, 2, 3] ← max = 3
Upper half (min-heap): [4, 5, 6] ← min = 4
Median = (3 + 4) / 2 = 3.5
Na abordagem mediana de dois heaps, para onde vai primeiro um novo elemento?
Muitos brilham no agendamento: salas de reunião (monitorar o horário de término mais cedo), agendamento de tarefas com resfriamento ou filas de tarefas da CPU. O principal insight é que um heap rastreia com eficiência “o que termina em seguida”.
| Necessidade | Melhor escolha | Por que | |------|-------------|-----| | Extração min/máx repetida | Pilha | O(log n) inserir + extrair | | Dados estáticos, classificação única | Matriz ordenada | O(n log n) uma vez, acesso O(1) | | Consultas de intervalo + estatísticas de pedidos | BST balanceado | O(log n) para tudo | | Top-K de uma transmissão | Monte de tamanho K | O(n log k) total |
Qual operação é O(1) em um min-heap?
| Operação | Tempo | |-----------|------| | Inserir | O(logn) | | Extrair mín/máx | O(logn) | | Espiar mín/máx | O(1) | | Heapificar | Sobre(n) | | Top-K de n itens | O(n log k) |