힙이란?
- 완전 이진트리의 일종으로 우선순위큐(PriorityQueue)를 위하여 만들어진 자료구조
- 큐에 우선순위가 적용되어 있으므로 최대값이나 최소값을 빠르게 찾아내기 위한 자료구조
(큐는 가장 먼저 들어온 데이터가 먼저 나가지만 우선순위큐는 해당 우선순위 데이터가 가장 먼저 나간다) - 단 모든 값들이 정렬되어 있지 않은 일종의 반정렬(느슨한 정렬) 상태이며 최소값 혹은 최대값 만을 보장
(최소 최대가 모두 필요할 때는 이중 힙 구조를 써야함) - 삽입 및 삭제가 BST보다 빠르며 모든 삭제나 삽입이 배열의 가장 끝에서 발생
힙의 추가
- 추가되는 숫자는 가장 마지막 레벨 빈 자리(왼쪽부터 채워짐)로 저장 됨
- 부모의 숫자가 클 때는 조건을 만족하지 않으므로 부모와 자식을 교환
- 교환이 발생하지 않을 때까지 반복하여 처리
힙의 삭제
- 힙에서 숫자를 꺼낼 때에는 가장 위에 있는 숫자를 선택
- 가장 마지막 레벨 오른쪽에 있는 숫자를 가장 위로 보냄
- 부모늬 숫자가 자식 숫자보다 작은 경우 자식의 좌우 중 작은쪽과 교환함
- 교환이 발생하지 않을 때까지 반복하여 처리
최대 힙
- 부모 노드의 키 값이 자식 노드의 키 값보다 크거나 같은 완전 이진 트리최소 힙
- 부모 노드의 키 값이 자식 노드의 키 값보다 작거나 같은 완전 이진 트리
- 파이썬 pop 메서드는 가장 작은 항목을 반환함
언제 힙, 우선순위큐를 사용하는가?
- 삽입작업과 최대/최소값을 pop() 작업이, 각각 O(logN), O(1) 밖에 걸리지 않는다.
- 힙에 값을 삽입을 한 번에 하는 것이 아니라 여러 번에 걸쳐서 한다.
- 여러 시점에 해당 시점의 최소 혹은 최대값을 요구한다.
- 위와 같은 삽입, 최대/최소값 확인이 여러차례 필요하다.
파이썬에서 힙, 우선순위큐의 활용
heapq.heappush(heap, item)
- 힙 불변성을 유지하면서, item 값을 heap으로 푸시heapq.heappop(heap)
- 힙 불변성을 유지하면서, heap에서 가장 작은 항목을 팝하고 반환
- 힙이 비어 있으면, IndexError가 발생(팝 하지 않고 가장 작은 항목에 액세스하려면, heap[0] 사용)
파이썬에서 최대힙의 활용
- heapq 모듈은 최소 힙(min heap)을 기능만을 동작
- 따라서 힙에 (우선 순위, 값) 구조의 튜플(tuple)을 원소로 추가하거나 삭제하면, 튜플 내에서 맨 앞에 있는 값을 기준으로 최소 힙이 구성되는 원리를 이용할 수 있다.
- 힙에서 값을 읽어올 때는 각 튜플의 인덱스 1값을 취하면 되고 예제로 확인 가능하다.
import heapq as hq
nums = [10, 15, 1, 4, 6]
heap = []
for num in nums:
hq.heappush(heap, (-num, num))
priority, num = hq.heappop(heap)
print(num
예제 문제
단어 정리
- 완전 이진 트리 : 마지막 레벨을 제외한 모든 레벨의 노드가 완전히 채워져 있는 구조
- 우선순위큐 : 큐 자료구조에 우선순위가 있는 구조
'자료구조' 카테고리의 다른 글
[자료구조]해시테이블, hash function (0) | 2021.07.06 |
---|---|
[자료구조]배열과 연결리스트 (0) | 2021.07.05 |
[자료구조] 트리, 이진트리, 이진탐색트리, 완전이진트리 (0) | 2021.03.19 |
[자료구조]Array, Linked list 차이 (0) | 2021.03.17 |
Set, List 자료형 remove 시간복잡도 O(1), O(n) (0) | 2021.01.30 |