October 24, 2021
최댓값과 최솟값을 빠르게 찾기 위해 고안된 자료구조
완전 이진트리 형태임
이진트리
: 각각의 노드가 최대 두 개의 자식 노드를 가지는 트리 자료구조완전 이진트리
: 마지막 레벨을 제외하고 모든 레벨이 완전히 채워져 있으며, 마지막 레벨의 모든 노드는 왼쪽부터 채워져있다부모 노드와 자식 노드 사이에는 대소관계가 성립한다.
최대 힙
최소 힙
따라서 힙 구조에서는 가장 높은(혹은 가장 낮은) 우선순위를 가지는 노드가 항상 Root에 오게 되는 특징이 있으며, 이를 이용하면 우선순위 큐
와 같은 추상적 자료형을 구현할 수 있다.
[이미지 출처] 위키백과 - 최대 힙 예시
파이썬 내장 모듈로, 일반 리스트를 최소 힙처럼 다룰 수 있게 해줌
✅ 모듈 임포트
import heapq
✅ 원소 추가 : heapq.heappush()
heap = []
# 힙에 원소 추가
heapq.heappush(heap, 4)
heapq.heappush(heap, 1)
heapq.heappush(heap, 7)
heapq.heappush(heap, 3)
print(heap) # [1, 3, 7, 4]
✅ 원소 삭제 (최솟값 추출) : heapq.heappop()
heap = [1, 3, 7, 4]
print(heapq.heappop(heap)) # 1
print(heap) # [3, 7, 4]
✅ 리스트를 힙으로 변환 : heapq.heapify()
nums = [4,5,7,9,2,3,1]
heapq.heapify(nums)
print(nums) # [1, 2, 3, 9, 5, 4, 7]
✅ 첫번째 ~ n번째 큰 값 / 작은 값 찾기 : heapq.nlargest()
/ heapq.nsmallest()
heap = [4,5,7,9,2,3,1]
print(heapq.nlargest(3, heap)) # [9, 7, 5]
print(heapq.nsmallest(2, heap)) # [1, 2]
✅ 최대 힙 만들기
nums = [4,5,7,9,2,3,1]
heap = []
for n in nums:
heapq.heappush(heap, (-n, n))
# 힙에 튜플을 저장하면 튜플의 첫 번째 원소를 기준으로 힙이 구성됨.
# 즉 -n은 최소 힙이 아니라 최대 힙을 구성하기 위한 우선순위 표시를 위한 것
while heap:
print(heapq.heappop(heap[1]))
✅ 힙 정렬 : 루트에 항상 최솟값이 온다는 힙 자료구조의 성질을 이용한 정렬 방법
시간복잡도 : O(nlogn)
def heap_sort(nums):
heap = []
for n in nums:
heapq.heappush(heap, n)
sorted_nums = []
while heap:
sorted_nums.append(heapq.heappop(heap)) # 값이 작은 순으로 차례대로 들어가게 됨
return sorted_nums
print(heap_sort([4,5,7,9,2,3,1])) # [1, 2, 3, 4, 5, 7, 9]