Un montón es un árbol binario completo donde cada padre satisface la propiedad del montón, ya sea siempre más pequeño (montón mínimo) o siempre más grande (montón máximo) que sus hijos. "Completo" significa que todos los niveles están llenos excepto posiblemente el último, que se llena de izquierda a derecha.
1 Min-heap
/ \
3 5
/ \
7 4
Como está completo, lo almacenamos en una matriz plana; no se necesitan punteros. Para el índice i: hijo izquierdo = 2i + 1, hijo derecho = 2i + 2, padre = (i - 1) // 2.
| Propiedad | Montón mínimo | Montón máximo | |----------|----------|----------| | Raíz | Elemento más pequeño | Elemento más grande | | ¿Padre ≤ hijos? | ✅ Sí | ❌ No (≥) | | Extracto da | Mínimo | Máximo |
El heapq de Python es un montón mínimo de forma predeterminada. Para un montón máximo, niegue los valores al insertar y niegue nuevamente al extraer.
Insertar: presione hasta el final, luego haga burbujas (intercambie con el padre cuando sea más pequeño):
import heapq
h = [1, 3, 5, 7]
heapq.heappush(h, 2) # h becomes [1, 2, 5, 7, 3]
Extraer mínimo: intercambie la raíz con el último elemento, haga estallar el último, luego tamice hacia abajo (intercambie con un elemento más pequeño):
smallest = heapq.heappop(h) # returns 1
Ambas operaciones se ejecutan en O(log n) porque la altura del árbol es log n.
Iniciar sesión unirse a la discusión
Llamar a heapq.heapify(arr) convierte una lista en un montón in situ en O(n), no en O(n log n). Funciona de abajo hacia arriba, filtrando cada nodo que no es hoja. Este es uno de los resultados de complejidad más sorprendentes en la informática.
Una cola de prioridad le permite acceder siempre primero al elemento de mayor prioridad. Los montones son la implementación preferida porque tanto la inserción como la extracción son O (log n). Úselo cada vez que necesite "dame el mejor artículo hasta ahora".
"Encuentra los K elementos más grandes en una matriz sin clasificar".
Mantenga un mínimo montón de tamaño K. Para cada elemento, empújelo; si el montón excede K, extraiga el más pequeño. Lo que queda son los K más grandes.
import heapq
def top_k(nums, k):
return heapq.nlargest(k, nums)
Tiempo: O(n log k) - mucho mejor que ordenar cuando k ≪ n.
Necesita las 5 puntuaciones más altas de 1 millón de entradas. ¿Qué tipo y tamaño de montón?
Empuje el encabezado de cada lista en un montón mínimo. Haga estallar el más pequeño y luego presione el siguiente elemento de esa misma lista. Repita hasta que se agoten todas las listas. Tiempo: O(N log K) donde N es el total de elementos.
Mantenga dos montones: un montón máximo para la mitad inferior y un montón mínimo para la mitad superior. Equilibre sus tamaños para que difieran como máximo en 1. La mediana siempre está en una o ambas raíces.
Lower half (max-heap): [1, 2, 3] ← max = 3
Upper half (min-heap): [4, 5, 6] ← min = 4
Median = (3 + 4) / 2 = 3.5
En el enfoque de la mediana de dos montones, ¿adónde va primero un nuevo elemento?
Hay muchas cosas que brillan en la programación: salas de reuniones (realizan un seguimiento de la hora de finalización más temprana), programación de tareas con tiempos de reutilización o colas de trabajos de CPU. La idea clave es que un montón rastrea eficientemente "lo que termina a continuación".
| Necesidad | La mejor elección | Por qué | |------|-------------|-----| | Extracción mínima/máxima repetida | Montón | O(log n) insertar + extraer | | Datos estáticos, clasificación única | Matriz ordenada | O(n log n) una vez, O(1) acceso | | Consultas de rango + estadísticas de pedidos | BST equilibrada | O(log n) para todo | | Top-K de una secuencia | Montón de tamaño K | O(n Iniciar sesión k) total |
¿Qué operación es O(1) en un montón mínimo?
| Operación | Hora | |-----------|--------------| | Insertar | O(log n) | | Extraer mín./máx. | O(log n) | | Vistazo mínimo/máximo | O(1) | | Amontonar | O(n) | | Top-K de n artículos | O(n Iniciar sesión k) |