
์ฝ๋ฉํ ์คํธ์์ ์ต์๊ฐ์ด๋ ์ต๋๊ฐ์ ๋ฐ๋ณตํด์ ๊ด๋ฆฌํด์ผ ํ๋ ๋ฌธ์ ์์ ์์ฃผ ์ฌ์ฉ๋๋ ์๋ฃ๊ตฌ์กฐ๊ฐ Heap์ ๋๋ค.
๋จ์ํ ๊ฐ์ฅ ์์ ๊ฐ์ ํ ๋ฒ ์ฐพ๋ ๊ฒ์ด๋ผ๋ฉด min()์ ์ฌ์ฉํ ์ ์์ง๋ง,
๋ฐ์ดํฐ๋ฅผ ๊ณ์ ์ถ๊ฐํ๋ฉด์ ๊ทธ๋๊ทธ๋ ๊ฐ์ฅ ์์ ๊ฐ ๋๋ ๊ฐ์ฅ ํฐ ๊ฐ์ ๊บผ๋ด์ผ ํ๋ค.
์ ๊ฐ์ ์ํฉ์์๋ ๋งค๋ฒ ์ ์ฒด ๋ฐ์ดํฐ๋ฅผ ํ์ํ๋ ๊ฒ๋ณด๋ค Heap์ ์ฌ์ฉํ๋ ๊ฒ์ด ํจ์จ์ ์ ๋๋ค.
Python์์๋ heapq ๋ชจ๋์ ์ด์ฉํด Heap์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
Heap์ ์์ ์ด์ง ํธ๋ฆฌ(Complete Binary Tree)๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ํ๋ ์๋ฃ๊ตฌ์กฐ์ ๋๋ค.

ํฌ๊ฒ ๋ ์ข ๋ฅ๊ฐ ์์ต๋๋ค.
Min Heap
โ ๊ฐ์ฅ ์์ ๊ฐ์ด Root์ ์์น
Max Heap
โ ๊ฐ์ฅ ํฐ ๊ฐ์ด Root์ ์์น
์ต์ ํ์์๋
๋ถ๋ชจ โค ์์
์ต๋ ํ์์๋
๋ถ๋ชจ โฅ ์์
๊ด๊ณ๊ฐ ์ ์ง๋ฉ๋๋ค.
์๋ฅผ ๋ค์ด ์ต์ ํ์ ๋ค์๊ณผ ๊ฐ์ ํํ๋ฅผ ๊ฐ์ง ์ ์์ต๋๋ค.
1
/ \
3 2
/ \ /
7 5 4
๊ฐ์ฅ ์์ ๊ฐ์ธ 1์ด Root์ ์์นํฉ๋๋ค.
์ฌ๊ธฐ์ Heap์ ์ ์ฒด ๋ฐ์ดํฐ๊ฐ ์ ๋ ฌ๋ ์๋ฃ๊ตฌ์กฐ๋ ์๋๋๋ค.
์ต์ ํ์ด๋ผ๋ฉด ๋ถ๋ชจ๊ฐ ์์๋ณด๋ค ์๊ฑฐ๋ ๊ฐ๋ค๋ ์กฐ๊ฑด์ ์ ์งํ๋ฉด์ Root๊ฐ ํญ์ ์ต์๊ฐ์ด๋ผ๋ ์ ์ ๋ณด์ฅํฉ๋๋ค.
์์ ์ด์ง ํธ๋ฆฌ๋ ๋ง์ง๋ง ๋ ๋ฒจ์ ์ ์ธํ ๋ชจ๋ ๋ ๋ฒจ์ด ์ฑ์์ ธ ์๊ณ , ๋ง์ง๋ง ๋ ๋ฒจ์ ์ผ์ชฝ๋ถํฐ ์ฐจ๋ก๋๋ก ์ฑ์์ง๋ ๊ตฌ์กฐ์ ๋๋ค.
์ด๋ฌํ ๊ตฌ์กฐ ๋๋ถ์ ๋ณ๋์ Node ๊ฐ์ฒด ์์ด List๋ก ํํํ ์ ์์ต๋๋ค.
1
/ \
3 2
/ \ /
7 5 4
heap = [1, 3, 2, 7, 5, 4]
์ธ๋ฑ์ค๋ฅผ ํจ๊ป ๋ณด๋ฉด
๊ฐ 1 3 2 7 5 4
index 0 1 2 3 4 5
ํน์ ์์น i๋ฅผ ๊ธฐ์ค์ผ๋ก ๋ถ๋ชจ์ ์์ ์์น๋ฅผ ๊ณ์ฐํ ์ ์์ต๋๋ค.
๋ถ๋ชจ
โ (i - 1) // 2
์ผ์ชฝ ์์
โ 2 * i + 1
์ค๋ฅธ์ชฝ ์์
โ 2 * i + 2
์๋ฅผ ๋ค์ด i = 1์ธ ๊ฐ 3์ ์์์
์ผ์ชฝ ์์
โ 2 * 1 + 1
โ index 3
โ 7
์ค๋ฅธ์ชฝ ์์
โ 2 * 1 + 2
โ index 4
โ 5
๊ฐ ๋ฉ๋๋ค.
Python์ heapq ์ญ์ ์ด๋ฐ ๋ฐฉ์์ผ๋ก List๋ฅผ Heap์ฒ๋ผ ๊ด๋ฆฌํฉ๋๋ค.
์ค์ ๋ก ์ฌ์ฉํ ๋ ์ด ๊ณต์์ ์ง์ ๊ณ์ฐํ ์ผ์ ๊ฑฐ์ ์๊ณ , heapq๊ฐ ๋ด๋ถ์ ์ผ๋ก ์ฒ๋ฆฌํด ์ค๋๋ค.
๋ค์๊ณผ ๊ฐ์ List๊ฐ ์๋ค๊ณ ํด๋ด ์๋ค.
arr = [8, 3, 5, 1, 9, 2]
์ผ๋ฐ์ ์ธ List์์ ์ต์๊ฐ์ ์ฐพ์ผ๋ฉด
min(arr)
์ ์ฒด ๋ฐ์ดํฐ๋ฅผ ํ์ธํด์ผ ํ๊ธฐ ๋๋ฌธ์
O(N)
์ ์๊ฐ์ด ํ์ํฉ๋๋ค.
๋ฐ๋ฉด ์ต์ ํ์์๋ ๊ฐ์ฅ ์์ ๊ฐ์ด ํญ์ Root์ ์กด์ฌํฉ๋๋ค.
Python์ Heap์ List๋ก ๊ด๋ฆฌํ๋ฏ๋ก
heap[0]
์ผ๋ก ์ต์๊ฐ์ ๋ฐ๋ก ํ์ธํ ์ ์์ต๋๋ค.
์ต์๊ฐ ํ์ธ
โ O(1)
๋ํ ๋ฐ์ดํฐ๋ฅผ ์ถ๊ฐํ๊ฑฐ๋ ์ ๊ฑฐํ ๋ค Heap ๊ตฌ์กฐ๋ฅผ ๋ค์ ์ ์งํ๋ ๊ณผ์ ์
O(log N)
์ผ๋ก ์ฒ๋ฆฌํ ์ ์์ต๋๋ค.
๋ฐ๋ผ์ Heap์
์ต์๊ฐ์ด๋ ์ต๋๊ฐ์ ํ ๋ฒ ์ฐพ๋ ๊ฒ์ด ์๋๋ผ ๊ณ์ ์ถ๊ฐํ๊ณ ๊บผ๋ด์ผ ํ๋ ์ํฉ
์์ ํนํ ์ ์ฉํฉ๋๋ค.
Python์์๋ heapq ๋ชจ๋์ ์ด์ฉํด Heap์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
import heapq
heapq๋ ๊ธฐ๋ณธ์ ์ผ๋ก Min Heap์ผ๋ก ๋์ํฉ๋๋ค.
Heap์ ๋ฐ์ดํฐ๋ฅผ ์ถ๊ฐํฉ๋๋ค.
import heapq
heap = []
heapq.heappush(heap, 5)
heapq.heappush(heap, 2)
heapq.heappush(heap, 7)
heapq.heappush(heap, 1)
print(heap)
Heap์ ์กฐ๊ฑด์ ์ ์งํ๋ฉด์ ๊ฐ์ด ์ถ๊ฐ๋ฉ๋๋ค.
์๊ฐ๋ณต์ก๋
โ O(log N)
๊ฐ์ฅ ์์ ๊ฐ์ ์ ๊ฑฐํ๋ฉด์ ๋ฐํํฉ๋๋ค.
print(heapq.heappop(heap))
1
๋ค์ ์คํํ๋ฉด
print(heapq.heappop(heap))
2
์ฒ๋ผ ์์ ๊ฐ๋ถํฐ ๊บผ๋ผ ์ ์์ต๋๋ค.
์๊ฐ๋ณต์ก๋
โ O(log N)
์ต์๊ฐ์ ์ ๊ฑฐํ์ง ์๊ณ ํ์ธ๋ง ํ๊ณ ์ถ๋ค๋ฉด
heap[0]
์ ์ฌ์ฉํฉ๋๋ค.
์๊ฐ๋ณต์ก๋
โ O(1)
๋จ,
heap[1]
heap[2]
๊ฐ ๋ ๋ฒ์งธ, ์ธ ๋ฒ์งธ๋ก ์์ ๊ฐ์ด๋ผ๋ ์๋ฏธ๋ ์๋๋๋ค.
์ต์ ํ์์ ํ์คํ๊ฒ ๋ณด์ฅ๋๋ ๊ฒ์
heap[0]
์ด ์ต์๊ฐ์ด๋ผ๋ ์ ์ ๋๋ค.
์ด๋ฏธ ์กด์ฌํ๋ List๋ฅผ Heap์ผ๋ก ๋ฐ๊ฟ ๋ ์ฌ์ฉํฉ๋๋ค.
import heapq
numbers = [5, 3, 8, 1, 2]
heapq.heapify(numbers)
print(numbers)
heapify()๋ ์๋ก์ด List๋ฅผ ๋ฐํํ๋ ๊ฒ์ด ์๋๋ผ ๊ธฐ์กด List ์์ฒด๋ฅผ Heap์ผ๋ก ๋ณ๊ฒฝํฉ๋๋ค.
heapq.heappop(numbers)
์ดํ ๋ฐ๋ก Heap์ฒ๋ผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
์๊ฐ๋ณต์ก๋
โ O(N)
| ๊ธฐ๋ฅ | Python | ์๊ฐ๋ณต์ก๋ |
|---|---|---|
| ๋ฐ์ดํฐ ์ถ๊ฐ | heappush() | O(log N) |
| ์ต์๊ฐ ์ญ์ / ๋ฐํ | heappop() | O(log N) |
| ์ต์๊ฐ ํ์ธ | heap[0] | O(1) |
| List โ Heap | heapify() | O(N) |
์ฝ๋ฉํ ์คํธ์์๋ ์ฐ์ ์ด ๋ค ๊ฐ์ง๋ฅผ ๊ธฐ์ตํด๋๋ฉด ๋ฉ๋๋ค.
Python์ heapq๋ ๊ธฐ๋ณธ์ ์ผ๋ก Min Heap์
๋๋ค.
์ฝ๋ฉํ
์คํธ์์ Max Heap์ด ํ์ํ๋ค๋ฉด ์ฃผ๋ก ๊ฐ์ -๋ฅผ ๋ถ์ด๋ ๋ฐฉ๋ฒ์ ์ฌ์ฉํฉ๋๋ค.
์๋ฅผ ๋ค์ด
5
2
8
1
์
-5
-2
-8
-1
๋ก ์ ์ฅํฉ๋๋ค.
Min Heap ์
์ฅ์์๋ -8์ด ๊ฐ์ฅ ์์ ๊ฐ์ด๊ธฐ ๋๋ฌธ์ ๊ฐ์ฅ ๋จผ์ ๋์ค๊ฒ ๋ฉ๋๋ค.
๊บผ๋ธ ๋ค ๋ค์ -๋ฅผ ๋ถ์ด๋ฉด
-(-8)
โ 8
์๋์ ์ต๋๊ฐ์ ์ป์ ์ ์์ต๋๋ค.
import heapq
heap = []
heapq.heappush(heap, -5)
heapq.heappush(heap, -2)
heapq.heappush(heap, -8)
heapq.heappush(heap, -1)
max_value = -heapq.heappop(heap)
print(max_value)
8
๋ฐ๋ผ์ Max Heap์ ๋ค์ ํํ๋ก ๊ธฐ์ตํ ์ ์์ต๋๋ค.
# ๋ฃ์ ๋
heapq.heappush(heap, -value)
# ๊บผ๋ผ ๋
value = -heapq.heappop(heap)
Heap๊ณผ ํจ๊ป ์์ฃผ ๋ฑ์ฅํ๋ ๊ฐ๋ ์ด Priority Queue(์ฐ์ ์์ ํ)์ ๋๋ค.
์ผ๋ฐ์ ์ธ Queue๋ FIFO ๊ตฌ์กฐ์ ๋๋ค.
First In First Out
๋จผ์ ๋ค์ด์จ ๋ฐ์ดํฐ
โ ๋จผ์ ๋๊ฐ
์๋ฅผ ๋ค์ด
A โ B โ C
์์๋ก ๋ค์ด์ค๋ฉด
A โ B โ C
์์๋ก ๋์ต๋๋ค.
๋ฐ๋ฉด Priority Queue๋ ๋ค์ด์จ ์์๋ณด๋ค ์ฐ์ ์์๋ฅผ ๊ธฐ์ค์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ๊บผ๋ ๋๋ค.
์๋ฅผ ๋ค์ด
์์
์ฐ์ ์์
A 3
B 1
C 2
์ด๊ณ ์ซ์๊ฐ ์์์๋ก ์ฐ์ ์์๊ฐ ๋๋ค๋ฉด
B โ C โ A
์์๋ก ์ฒ๋ฆฌ๋ฉ๋๋ค.
Heap๊ณผ Priority Queue๋ ๊ฐ์ ๊ฐ๋ ์ ์๋๋๋ค.
Priority Queue
โ ์ฐ์ ์์๊ฐ ๋์ ๋ฐ์ดํฐ๋ฅผ ๋จผ์ ๊บผ๋ด๋ ๋ฐฉ์
Heap
โ Priority Queue๋ฅผ ํจ์จ์ ์ผ๋ก ๊ตฌํํ ๋ ์์ฃผ ์ฌ์ฉํ๋ ์๋ฃ๊ตฌ์กฐ
Heap์ ์ด์ฉํ๋ฉด ๋ฐ์ดํฐ์ ์ฝ์ ๊ณผ ์ญ์ ๋ฅผ
O(log N)
์ผ๋ก ์ฒ๋ฆฌํ ์ ์๊ธฐ ๋๋ฌธ์ Priority Queue ๊ตฌํ์ ์์ฃผ ์ฌ์ฉ๋ฉ๋๋ค.
Python์ Heap์๋ Tuple๋ ๋ฃ์ ์ ์์ต๋๋ค.
import heapq
heap = []
heapq.heappush(heap, (2, "Task B"))
heapq.heappush(heap, (1, "Task A"))
heapq.heappush(heap, (3, "Task C"))
Tuple์ ์์ ๊ฐ๋ถํฐ ๋น๊ตํ๊ธฐ ๋๋ฌธ์
heapq.heappop(heap)
๊ฒฐ๊ณผ๋
(1, 'Task A')
๊ฐ ๋ฉ๋๋ค.
๋ฐ๋ผ์
(priority, data)
ํํ๋ก ์ ์ฅํ๋ฉด Priority Queue์ฒ๋ผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
heapq.heappush(heap, (priority, value))
์ฝ๋ฉํ ์คํธ์์๋ ๋ค์๊ณผ ๊ฐ์ ํํ๋ ์์ฃผ ๋ณผ ์ ์์ต๋๋ค.
heapq.heappush(heap, (distance, node))
์๋ฅผ ๋ค์ด ๋ค์ต์คํธ๋ผ ์๊ณ ๋ฆฌ์ฆ์์๋ ํ์ฌ๊น์ง์ ๊ฑฐ๋ฆฌ๋ฅผ ์ฐ์ ์์๋ก ์ฌ์ฉํ์ฌ ๊ฑฐ๋ฆฌ๊ฐ ์งง์ Node๋ถํฐ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค.
| ์๋ฃ๊ตฌ์กฐ | ๋ฐ์ดํฐ๋ฅผ ๊บผ๋ด๋ ๊ธฐ์ค |
|---|---|
| Queue | ๋จผ์ ๋ค์ด์จ ๋ฐ์ดํฐ |
| Priority Queue | ์ฐ์ ์์๊ฐ ๋์ ๋ฐ์ดํฐ |
์ฆ ๋ฌธ์ ์์
๋จผ์ ๋ค์ด์จ ์์๋๋ก ์ฒ๋ฆฌํ๋ค.
๋ผ๋ฉด Queue๋ฅผ,
๊ฐ์ฅ ์์ ๊ฐ์ด๋ ์ฐ์ ์์๊ฐ ๋์ ๊ฐ๋ถํฐ ๊ณ์ ์ฒ๋ฆฌํ๋ค.
๋ผ๋ฉด Priority Queue์ Heap์ ์๊ฐํด๋ณผ ์ ์์ต๋๋ค.
Heap์ ํนํ ๋ค์๊ณผ ๊ฐ์ ์ํฉ์์ ์๊ฐํด๋ณผ ์ ์์ต๋๋ค.
ํ์ฌ ๋ฐ์ดํฐ ์ค ๊ฐ์ฅ ์์ ๊ฐ์ ๊บผ๋ธ๋ค.
์๋ก์ด ๋ฐ์ดํฐ๋ฅผ ์ถ๊ฐํ๋ค.
๋ค์ ๊ฐ์ฅ ์์ ๊ฐ์ ๊บผ๋ธ๋ค.
heapq.heappush(heap, value)
min_value = heapq.heappop(heap)
heapq.heappush(heap, -value)
max_value = -heapq.heappop(heap)
heapq.heappush(heap, (priority, task))
์ ์ฒด ๋ฐ์ดํฐ๋ฅผ ๋งค๋ฒ ์ ๋ ฌํ๋ ๋์ ์ผ์ ํฌ๊ธฐ์ Heap๋ง ์ ์งํ๋ ๋ฐฉ์์ผ๋ก ์ฌ์ฉํ ์ ์์ต๋๋ค.
์๋ฅผ ๋ค์ด ๊ฐ์ฅ ํฐ 3๊ฐ์ ๊ฐ๋ง ์ ์งํ๋ค๋ฉด
if len(heap) < 3:
heapq.heappush(heap, value)
else:
...
์ ๊ฐ์ ๋ฐฉ์์ผ๋ก ์ ๊ทผํ ์ ์์ต๋๋ค.
๋ค์ต์คํธ๋ผ ์๊ณ ๋ฆฌ์ฆ์์๋
heapq.heappush(heap, (distance, node))
ํํ๋ก ์ฌ์ฉํ์ฌ ํ์ฌ๊น์ง ๊ฑฐ๋ฆฌ๊ฐ ๊ฐ์ฅ ์งง์ Node๋ถํฐ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค.
๋ฌธ์ ์์
๊ฐ์ฅ ์์ ๋ ๊ฐ์ ๊บผ๋ธ๋ค.
๋ ๊ฐ์ ํฉ์น๋ค.
ํฉ์น ๊ฐ์ ๋ค์ ๋ฃ๋๋ค.
๊ณผ ๊ฐ์ ๊ณผ์ ์ด ๋ฐ๋ณต๋๋ค๋ฉด Heap์ ์๊ฐํด๋ณผ ์ ์์ต๋๋ค.
a = heapq.heappop(heap)
b = heapq.heappop(heap)
heapq.heappush(heap, a + b)
import heapq
heap = []
heapq.heappush(heap, value)
value = heapq.heappop(heap)
minimum = heap[0]
arr = [5, 3, 1, 7, 2]
heapq.heapify(arr)
heapq.heappush(heap, -value)
maximum = -heapq.heappop(heap)
heapq.heappush(heap, (priority, value))
priority, value = heapq.heappop(heap)
์ต์๊ฐ ํ์ธ
โ O(1)
heappush
โ O(log N)
heappop
โ O(log N)
heapify
โ O(N)
Heap์
์ต์๊ฐ์ด๋ ์ต๋๊ฐ์ ํจ์จ์ ์ผ๋ก ๊ด๋ฆฌํ๊ธฐ ์ํ ์๋ฃ๊ตฌ์กฐ
๋ผ๊ณ ์๊ฐํ๋ฉด ๋ฉ๋๋ค.

ํนํ ์ฝ๋ฉํ ์คํธ์์
์ต์๊ฐ / ์ต๋๊ฐ์ ๊ณ์ ๊บผ๋ธ๋ค.
๋ฐ์ดํฐ๋ฅผ ์ถ๊ฐํ๋ฉด์
์ต์๊ฐ / ์ต๋๊ฐ์ ๊ณ์ ๊ด๋ฆฌํ๋ค.
์ฐ์ ์์๊ฐ ๋์ ๋ฐ์ดํฐ๋ฅผ ๋จผ์ ์ฒ๋ฆฌํ๋ค.
์ ๊ฐ์ ์ํฉ์ด ๋์จ๋ค๋ฉด Heap์ ๋ ์ฌ๋ ค๋ณผ ์ ์์ต๋๋ค.
Queue
โ ๋จผ์ ๋ค์ด์จ ๋ฐ์ดํฐ๋ถํฐ ์ฒ๋ฆฌ
Priority Queue
โ ์ฐ์ ์์๊ฐ ๋์ ๋ฐ์ดํฐ๋ถํฐ ์ฒ๋ฆฌ
Heap
โ Priority Queue๋ฅผ ํจ์จ์ ์ผ๋ก ๊ตฌํํ ๋ ์์ฃผ ์ฌ์ฉํ๋ ์๋ฃ๊ตฌ์กฐ
Python์์๋ heapq๋ฅผ ์ด์ฉํด Min Heap์ ์ฌ์ฉํ ์ ์๊ณ , ์ฝ๋ฉํ
์คํธ์์๋ ์ฐ์
heapq.heappush()
heapq.heappop()
heapq.heapify()
heap[0]
์ ๋๋ฅผ ์ตํ๋๋ฉด ์ข์ต๋๋ค.
๊ฒฐ๊ตญ Heap ๋ฌธ์ ์์๋ ๋ฉ์๋ ์์ฒด๋ฅผ ์ธ์ฐ๋ ๊ฒ๋ณด๋ค
"์ต์๊ฐ์ด๋ ์ต๋๊ฐ์ ๋ฐ๋ณตํด์ ๊ด๋ฆฌํด์ผ ํ๋๊ฐ?"
๋ฅผ ๋ฌธ์ ์์ ๋ฐ๊ฒฌํ๋ ๊ฒ์ด ๊ฐ์ฅ ์ค์ํฉ๋๋ค.