Menu
Coddy logo textTech

Heap Sort

Última atualização

O heap sort trata o array como um heap binário. Primeiro ele constrói um max-heap, de modo que o maior elemento fica na raiz (índice 0). Depois troca repetidamente a raiz com o último elemento não ordenado - fixando o máximo no lugar - e afunda a nova raiz para restaurar a propriedade do heap. Pressione reproduzir acima para ver a construção do heap e as extrações.

O heap sort garante tempo O(n log n) como o merge sort, mas ordena no local com apenas O(1) de espaço extra. Não é estável e tende a ter pior comportamento de cache que o quicksort, por isso costuma ser escolhido quando tanto um limite garantido quanto memória constante importam.

Complexidade de tempo e espaço

CasoComplexidadeNotas
Melhor casoO(n log n)Construção + n extrações
Caso médioO(n log n)Ordem aleatória
Pior casoO(n log n)Garantido
EspaçoO(1)No local
EstávelNãoO afundamento reordena elementos iguais

Passo a passo

PassoO que acontece
1Construir um max-heap a partir do array (afundar a partir do último pai).
2Trocar a raiz (máximo) com o último elemento do heap.
3Reduzir o heap em um - aquele último espaço agora está ordenado.
4Afundar a nova raiz para restaurar a propriedade do max-heap.
5Repetir até o heap ter um único elemento.

Exemplo resolvido

Ordenando [3, 1, 6, 5, 2, 4]. A barra | marca o limite entre o heap que encolhe e a cauda ordenada:

PassagemArrayAção
Construir heap[6, 5, 4, 1, 2, 3]Afundar a partir do último pai para construir o max-heap; 6 agora está na raiz.
1[5, 3, 4, 1, 2 | 6]Trocar a raiz 6 com o último espaço, reduzir o heap e afundar 3.
2[4, 3, 2, 1 | 5, 6]Retirar a raiz 5, depois afundar 2 para que 4 suba à raiz.
3[3, 1, 2 | 4, 5, 6]Retirar a raiz 4, depois afundar 1 para que 3 suba à raiz.
4[2, 1 | 3, 4, 5, 6]Retirar a raiz 3; 2 já satisfaz a propriedade do heap.
5[1 | 2, 3, 4, 5, 6]Retirar a raiz 2; resta um elemento, então o array está ordenado.

Quando usar o heap sort

Use quandoEvite quando
Você precisa de um pior caso garantido de O(n log n) sem risco de O(n²).Você precisa de uma ordenação estável que preserve a ordem de chaves iguais.
A memória é escassa - ordena no local com apenas O(1) de espaço extra.O desempenho de cache importa e os dados cabem na memória - o quicksort costuma ser mais rápido.
Você já mantém um heap (por exemplo, uma fila de prioridade) sobre os dados.Você quer o menor número de comparações - merge sort e quicksort costumam fazer menos na prática.
Uma entrada não confiável poderia disparar o pior caso do quicksort e você não pode aleatorizar.Os dados estão quase ordenados - o insertion sort roda em tempo quase linear sobre eles.

Código de Heap Sort

Uma implementação limpa e executável de Heap Sort em Python, JavaScript, Java, C++, C. Escolha uma linguagem, copie o código ou abra-o já carregado no Playground da Coddy.

Código de Heap Sort em Python

Python
1def heap_sort(a):2    n = len(a)3    # Build a max-heap, deepest parent first4    for i in range(n // 2 - 1, -1, -1):5        sift_down(a, i, n)6    # Repeatedly move the max to the end and shrink the heap7    for end in range(n - 1, 0, -1):8        a[0], a[end] = a[end], a[0]9        sift_down(a, 0, end)10    return a11
12
13def sift_down(a, i, size):14    while True:15        largest = i16        left, right = 2 * i + 1, 2 * i + 217        if left < size and a[left] > a[largest]:18            largest = left19        if right < size and a[right] > a[largest]:20            largest = right21        if largest == i:22            return23        a[i], a[largest] = a[largest], a[i]24        i = largest25
26
27nums = [12, 11, 13, 5, 6, 7]28print("Before:", nums)29heap_sort(nums)30print("After: ", nums)
Execute este código no Playground de Python

Perguntas frequentes sobre Heap Sort

Qual é a complexidade de tempo do heap sort?
O heap sort é O(n log n) no melhor, no médio e no pior caso. Construir o heap é O(n) e cada uma das n extrações custa O(log n). Ele usa O(1) de espaço extra.
O heap sort é estável?
Não. A operação de afundamento pode mover elementos iguais uns sobre os outros, então o heap sort não preserva a ordem relativa de chaves iguais.
Quando devo usar o heap sort?
Use o heap sort quando precisar de um pior caso garantido de O(n log n) com apenas O(1) de memória extra. Ele evita o risco de O(n²) do quicksort sem o buffer de O(n) do merge sort, ao custo de estabilidade e desempenho de cache.
Qual é a diferença entre heap sort e quicksort?
Ambos ordenam no local, mas o quicksort tem um pior caso de O(n²) enquanto o heap sort garante O(n log n). Na prática o quicksort costuma ser mais rápido por causa da melhor localidade de cache e menos trocas, então o heap sort é preferido principalmente quando o limite do pior caso precisa ser garantido.
Como o heap sort se relaciona com uma fila de prioridade?
Um heap binário é a implementação padrão de uma fila de prioridade, e o heap sort consiste essencialmente em retirar repetidamente o máximo dessa fila. Se você já mantém seus dados em um heap, extrair os elementos um a um lhe dá a ordem ordenada de graça.
O heap sort precisa de um max-heap ou de um min-heap?
Para ordenar em ordem crescente no local, use um max-heap: o maior elemento é trocado para o fim em cada passagem, fazendo a cauda ordenada crescer a partir da direita. Um min-heap produziria ordem decrescente no local, ou crescente se você extrair para um array separado.
Coddy programming languages illustration

Domine algoritmos com a Coddy

COMEÇAR