| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | |||
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| 12 | 13 | 14 | 15 | 16 | 17 | 18 |
| 19 | 20 | 21 | 22 | 23 | 24 | 25 |
| 26 | 27 | 28 | 29 | 30 |
Tags
- isalpha()
- 그래프 탐색
- LSTM
- Deque
- isdigit()
- Python
- Dynamic Programming
- 프로그래머스
- 코테
- 동적 프로그래밍
- isalnum()
- 알고리즘
- DP
- 정렬
- find()
- Recommendation
- 우선순위 큐
- Stack
- Knowledge graph
- explainable recommendation
- kg
- knowledge
- Algorithm
- 파이썬
- isnumeric()
- bfs
- 백준
- 자료구조
- 추천시스템
- 그래프
Archives
- Today
- Total
데린이 고인물되기
[TIL] 250629 우선순위 큐(힙(Heap)) 본문
반응형
1. 개념 정리: 힙(Heap) = 우선순위 큐
- 우선순위 큐는 일반적인 큐와 달리, 값의 크기에 따라 먼저 나가는 순서가 결정됨
- 파이썬의 heapq는 최소 힙(min heap) 기반:
- 항상 가장 작은 값이 먼저 나옴
- 최대 힙(max heap)을 쓰고 싶을 땐 값을 음수로 저장해서 우회
2. 힙 사용법 (파이썬 heapq)
- 최소 힙 (기본 동작)
import heapq
heap = []
# 삽입: heappush
heapq.heappush(heap, 4)
heapq.heappush(heap, 1)
heapq.heappush(heap, 7)
# 출력 (가장 작은 값)
print(heapq.heappop(heap)) # 1
print(heapq.heappop(heap)) # 4
print(heapq.heappop(heap)) # 7
- 최대 힙 (음수 활용)
import heapq
heap = []
# 값을 음수로 넣어 최대 힙처럼 사용
heapq.heappush(heap, -4)
heapq.heappush(heap, -1)
heapq.heappush(heap, -7)
# pop할 때 다시 음수로 바꿔줌
print(-heapq.heappop(heap)) # 7
print(-heapq.heappop(heap)) # 4
print(-heapq.heappop(heap)) # 1
3. 힙 주요 함수 정리
| 함수명 | 설명 | 시간 복잡도 |
| heapq.heappush(heap, item) | item을 힙에 추가 | O(log n) |
| heapq.heappop(heap) | 가장 작은 item을 제거하고 반환 | O(log n) |
| heapq.heapify(list) | 기존 리스트를 in-place로 힙으로 만듦 | O(log n) |
| heapq.heappushpop(heap, item) | item을 넣고, 가장 작은 값 바로 꺼냄 (더 빠름) | O(n) |
| heapq.nlargest(n, iterable) | 가장 큰 n개 요소 리턴 (정렬 아님) | O(n log k) |
| heapq.nsmallest(n, iterable) | 가장 작은 n개 요소 리턴 | O(n log k) |
4. 우선순위가 튜플일 경우
(우선순위, 값) 형식으로 넣으면 우선순위 기준 정렬됨
import heapq
tasks = []
heapq.heappush(tasks, (2, "cleaning"))
heapq.heappush(tasks, (1, "study"))
heapq.heappush(tasks, (3, "sleep"))
print(heapq.heappop(tasks)) # (1, 'study') -> 가장 우선순위 높은 작업
5. heapq.nsmallest(n, iterable)
heapq.nsmallest(n, iterable)는 iterable(반복 가능한 자료)에서 가장 작은 값 n개를 찾아서 정렬된 리스트로 반환해주는 함수
사용법
import heapq
nums = [10, 4, 1, 20, 7]
# 가장 작은 3개 원소 반환
smallest = heapq.nsmallest(3, nums)
print(smallest) # [1, 4, 7]
- 정렬된 결과를 반환함 (min → max)
- 내부적으로는 최대 힙(Max Heap) 크기 n 유지 → 시간 복잡도: O(n log k)
nsmallest + key 인자 (정렬 기준 커스텀)
students = [
{"name": "Alice", "score": 82},
{"name": "Bob", "score": 91},
{"name": "Charlie", "score": 78}
]
# 점수(score)가 가장 낮은 2명
top2 = heapq.nsmallest(2, students, key=lambda x: x["score"])
for s in top2:
print(s["name"], s["score"])
# 출력:
# Charlie 78
# Alice 82
6. 튜플로 여러 우선순위를 동시에 설정하기
- 파이썬은 튜플을 비교할 때 자동으로 사전식(lexicographical) 비교를 수행함.
즉 (a, b, c)끼리 비교할 때는- 첫 요소 a를 먼저 비교하고
- 같으면 두 번째 요소 b를 비교하며
- 그래도 같으면 세 번째 요소 c를 기준으로 비교합니다.
import heapq
heap = []
heapq.heappush(heap, (priority1, priority2, data))
- priority1이 작을수록 더 우선
- 같다면 priority2 비교
- 또 같으면 data(또는 다른 요소)까지 비교
이렇게 다중 우선순위 기준을 쉽게 적용할 수 있음
실전 예제: 세 가지 기준으로 정렬되는 힙
학생들을 (등급, 나이, 이름) 기준으로 우선순위를 주려고 한다면:
import heapq
students = [
('A', 22, 'Charlie'),
('B', 20, 'Alice'),
('A', 20, 'Bob'),
('A', 22, 'Anne'),
]
heap = []
for grade, age, name in students:
heapq.heappush(heap, (grade, age, name))
while heap:
print(heapq.heappop(heap))
결과는 아래와 같음
('A', 20, 'Bob')
('A', 22, 'Anne')
('A', 22, 'Charlie')
('B', 20, 'Alice')
- 등급 A 우선,
- 나이 같다면 20살 먼저,
- 나이도 같다면 이름 알파벳 순
이렇게 튜플을 그대로 넣는 것만으로 다중 우선순위를 적용할 수 있음
반응형
'Algorithm > 정리' 카테고리의 다른 글
| [TIL] 250916 - defaultdict에 원소가 있는 리스트를 디폴트로 넣는 방법 (0) | 2025.09.17 |
|---|---|
| [TIL] 250630 - 파이썬 itertools.product 사용법 (1) | 2025.07.01 |
| [TIL]250629 - 스택, 큐, 덱 (파이썬) (0) | 2025.06.29 |
| [TIL] 250629 - 정렬 기반 최빈값 탐색 패턴 2가지 비교 (0) | 2025.06.29 |
| [TIL] 250629 - 정렬 (0) | 2025.06.29 |