heapq max-heap: filas de prioridade máximas

Publicado em: 19/09/2026
Tempo de leitura: 5 minutos
Código Python representando uma fila de prioridade com heapq max-heap

O módulo heapq sempre foi uma das ferramentas mais úteis da biblioteca padrão para implementar filas de prioridade. Durante muito tempo, sua interface foi orientada principalmente a min-heaps: o menor valor permanece no topo e pode ser removido com eficiência. Nas versões recentes do Python, a API passou a incluir operações explícitas para max-heaps, facilitando casos em que o maior elemento deve ter prioridade. Neste guia, você aprenderá a usar essas funções, entender quando elas fazem sentido e evitar erros comuns em algoritmos reais.

O que é um heap

Um heap é uma estrutura de dados parcialmente ordenada. Em um min-heap, o primeiro item é sempre o menor. Em um max-heap, o primeiro item é sempre o maior. Isso não significa que toda a lista esteja ordenada. O ganho está em inserir e remover o elemento prioritário com custo logarítmico, sem pagar o preço de ordenar toda a coleção após cada alteração.

Esse comportamento é ideal para agendadores, filas de tarefas, seleção dos maiores ou menores valores, algoritmos de grafos, simulações, processamento de eventos e sistemas que precisam atualizar prioridades continuamente.

Por que uma API nativa de max-heap ajuda

Antes das funções específicas para max-heap, era comum inverter números com sinal negativo. Para guardar prioridades 10, 20 e 30, por exemplo, armazenavam-se -10, -20 e -30. A técnica funciona para números, mas deixa o código menos legível e complica tuplas, objetos e comparações customizadas. Uma API explícita evita essa transformação mental e reduz bugs.

import heapq

prioridades = [10, 30, 20, 50, 40]
heapq.heapify_max(prioridades)
print(prioridades[0])  # 50

A função heapify_max reorganiza a lista existente no lugar. O custo é linear, portanto é melhor do que inserir todos os elementos individualmente quando os dados já estão disponíveis.

Inserindo elementos

Depois de criar o heap, use heappush_max para inserir novos valores preservando a propriedade de max-heap.

heapq.heappush_max(prioridades, 60)
print(prioridades[0])  # 60

A inserção não ordena a lista inteira. Ela apenas move o novo item pelos níveis necessários. Por isso, o custo típico é O(log n).

Removendo o maior valor

Use heappop_max para remover e retornar o maior elemento.

maior = heapq.heappop_max(prioridades)
print(maior)

Essa operação também custa O(log n). Em aplicações de fila de prioridade, normalmente o primeiro item representa a tarefa mais urgente, a maior pontuação ou o evento com maior peso.

Substituição eficiente

Quando você precisa remover o maior item e inserir outro imediatamente, heapreplace_max evita duas operações separadas.

removido = heapq.heapreplace_max(prioridades, 25)

A função remove o maior item atual e adiciona o novo valor. É importante notar que o item inserido pode ser maior ou menor do que o removido. Verifique a semântica antes de usar em filtros de tamanho fixo.

Push e pop em uma só etapa

heappushpop_max insere um item e depois remove o maior, de forma otimizada.

removido = heapq.heappushpop_max(prioridades, 35)

Ela é útil quando o heap mantém uma janela de valores e você quer controlar seu tamanho. Ainda assim, a ordem lógica difere de heapreplace_max. Em uma função, o novo valor participa da escolha do maior; na outra, o topo antigo é removido antes da inserção.

Fila de tarefas com prioridade

Em sistemas reais, normalmente armazenamos tuplas. O primeiro campo define a prioridade e os demais servem como desempate e dados da tarefa.

import heapq
from itertools import count

contador = count()
fila = []

def adicionar(prioridade, nome):
    heapq.heappush_max(fila, (prioridade, -next(contador), nome))

def proxima():
    prioridade, _, nome = heapq.heappop_max(fila)
    return prioridade, nome

adicionar(5, "gerar relatório")
adicionar(10, "corrigir indisponibilidade")
adicionar(7, "revisar logs")
print(proxima())

O contador evita comparar diretamente nomes ou objetos quando as prioridades empatam. Em max-heaps, o sinal e a direção do desempate precisam ser escolhidos com cuidado para preservar a ordem desejada.

Objetos personalizados

Você pode usar dataclasses ordenáveis para tornar o código mais expressivo.

from dataclasses import dataclass, field

@dataclass(order=True)
class Tarefa:
    prioridade: int
    sequencia: int
    descricao: str = field(compare=False)

Somente os campos comparáveis participam da ordenação. Se dois objetos não puderem ser comparados, as operações do heap lançarão TypeError. Teste empates explicitamente.

Quando usar min-heap ou max-heap

Use min-heap quando o menor prazo, custo ou distância tiver prioridade. Use max-heap quando a maior pontuação, urgência, receita ou carga precisar sair primeiro. Em alguns algoritmos, um min-heap de tamanho limitado encontra os maiores elementos com eficiência; em outros, um max-heap simplifica a leitura do problema.

Para aprofundar estruturas de dados, consulte o conteúdo sobre estruturas de dados em Python. Também vale revisar listas em Python, tuplas em Python e funções em Python.

Erros comuns

O primeiro erro é tratar o heap como lista ordenada. Apenas o topo tem garantia direta. O segundo é misturar funções de min-heap e max-heap na mesma lista. Isso corrompe a propriedade estrutural. O terceiro é alterar manualmente um item interno sem reconstruir o heap. Se uma prioridade mudar, remova e reinsira o item ou use uma estratégia de invalidação.

Outro problema aparece com valores NaN, comparações inconsistentes ou objetos mutáveis. A relação de ordem deve ser previsível. Em filas concorrentes, proteja o heap com sincronização adequada ou use abstrações prontas.

Desempenho e testes

Teste cenários vazios, um único elemento, prioridades repetidas e grandes volumes. Operações de remoção em heap vazio geram IndexError. Se a entrada vier do usuário, valide antes. Para medir desempenho, use dados representativos e o módulo timeit, evitando conclusões baseadas em coleções minúsculas.

A documentação oficial do módulo heapq é a referência principal. Para entender a análise assintótica, consulte também a visão geral de heaps como estrutura de dados.

Conclusão

As operações nativas de max-heap deixam o código Python mais claro, especialmente quando a regra do domínio realmente privilegia o maior valor. heapify_max, heappush_max, heappop_max, heapreplace_max e heappushpop_max cobrem os principais fluxos de criação, inserção, remoção e substituição. A escolha correta entre essas funções depende da ordem exata das operações e do tamanho que o heap deve manter. Com testes de empate, validação de comparabilidade e uma estratégia clara de atualização de prioridades, o max-heap se torna uma ferramenta eficiente para filas, rankings, agendadores e algoritmos de seleção.

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Conteúdo do artigo

    Artigos relacionados

    Servidores representando workers paralelos do ProcessPoolExecutor
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    ProcessPoolExecutor kill_workers: encerre processos

    Aprenda terminate_workers e kill_workers no ProcessPoolExecutor para encerrar processos travados com segurança e controlar tarefas pendentes.

    Ler mais

    Tempo de leitura: 6 minutos
    19/09/2026
    Terminal de linha de comando usado em uma ferramenta Python com argparse
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    argparse suggest_on_error: melhore erros de CLI

    Aprenda argparse suggest_on_error no Python para sugerir opções corretas, melhorar erros de CLI e manter compatibilidade entre versões.

    Ler mais

    Tempo de leitura: 5 minutos
    18/09/2026
    Código e estrutura de arquivos para compressão Zstandard no Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    compression.zstd: compacte dados com Zstandard

    Aprenda a compactar e descompactar dados com compression.zstd no Python, usando streams, dicionários e limites seguros.

    Ler mais

    Tempo de leitura: 5 minutos
    18/09/2026
    Programador gerenciando uma fila assíncrona com asyncio.Queue.shutdown
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    asyncio.Queue.shutdown: encerre filas sem deadlocks

    Aprenda asyncio.Queue.shutdown no Python para encerrar filas, liberar workers, drenar tarefas e evitar deadlocks em pipelines assíncronos.

    Ler mais

    Tempo de leitura: 6 minutos
    17/09/2026
    Depuração de processo Python em execução com pdb -p
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    pdb -p no Python: depure processos

    Aprenda a usar pdb -p no Python para anexar o depurador a processos em execução, analisar travamentos e investigar pilhas

    Ler mais

    Tempo de leitura: 7 minutos
    17/09/2026
    Código Python processado em lotes com itertools.batched
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    itertools.batched strict: valide lotes completos

    Aprenda itertools.batched com strict no Python para criar lotes, validar grupos completos e processar dados com segurança.

    Ler mais

    Tempo de leitura: 6 minutos
    16/09/2026