Heap은 우선순위 큐(Priority Queues)를 구현하는데 널리 사용되는 자료 구조 중 하나.
파이썬에서는 heapq 모듈을 사용하면 된다.
우선순위가 높은 원소부터 먼저 추출된다.
-> 작업 스케줄링, 네트워크 패킷 라우팅, 이벤트 처리, 작업 예약, 우선순위에 따른 데이터 처리 등에 유용하게 활용됨.
heap 자료구조는 삽입, 반환시 항상 정렬을 유지한다.
heapq 모듈은 이진트리 기반의 최소 힙 자료구조로 최대 힙이나 최소 힙을 구현할 수 있다.
import heapq
# 배열 초기화
li = [3, 7, 8, 9]
# list를 heap으로 변환
heap.heapify(li)
import heapq
li = [5, 7, 9, 1, 3]
heapq.heapify(li)
# li에 4 넣기
heapq.heappush(li, 4)
# 1 반환
heapq.heappop(li)
import heapq
li1 = [5, 1, 9, 4, 3]
li2 = [5, 7, 9, 4, 3]
heapq.heapify(li1)
heapq.heapify(li2)
# 2 삽입, 1 반환
heapq.heappushpop(li1, 2)
# 3 반환, 2 삽입
heapq.heapreplace(li2, 2)
원소 삭제 x
import heapq
# initializing list
li1 = [6, 7, 9, 4, 3, 5, 8, 10, 1]
heapq.heapify(li1)
# 가장 큰 원소 3개 10, 9, 8 반환
heapq.nlargest(3, li1)
# 가장 작은 원소 3개 1, 3, 4 반환
heapq.nsmallest(3, li1)
가장 작은 원소 1개 찾고 싶으면 heappop()을 이용해도 된다.
heapq.heappop(li)
힙을 배웠다면 활용해서 알고리즘 문제를 풀어보자!
풀이
import sys
import heapq
input = sys.stdin.readline
n = int(input())
que = []
for _ in range(n):
x = int(input())
if x == 0:
if len(que) == 0:
print(0)
else:
print(heapq.heappop(que))
else:
heapq.heappush(que, x)
heappop으로 쉽게 가장 작은 원소를 []에서 삭제, 반환할 수 있다.
풀이
import sys
import heapq
input = sys.stdin.readline
n = int(input())
li = []
for _ in range(n):
# 최대 힙 구현을 위해 -1을 곱해 역순으로 li에 들어가게 함
x = int(input()) * -1
if x == 0:
if len(li) == 0:
print(0)
else:
# 출력시 다시 -1을 곱해 원래 숫자로 돌려줌
print(-heapq.heappop(li))
else:
heapq.heappush(li, x)
heappush, heappop 함수들이 이미 힙 속성을 유지하도록 구현되어 있기 때문에 heapq.heapify(li) 코드를 생략해도 된다.
-1을 곱해서 []에 넣어 최소 힙의 반대인 최대 힙을 구현할 수 있다. 꺼낼 때 다시 -1 곱해주면 값 복구.
heap-data-structure
heapq-in-python
Python-우선순위-큐-heapq
최소-힙-최대-힙