์๋ ํ์ธ์~
์ค๋์ ํ ์๋ฃ๊ตฌ์กฐ์ ๋ํด์ ์ ๋ฆฌํ๊ฒ ์ต๋๋ค.
ํ(Heap)์ด๋?
๋ฐ์ดํฐ์์ ์ต๋๊ฐ๊ณผ ์ต์๊ฐ์ ๋น ๋ฅด๊ฒ ์ฐพ๊ธฐ ์ํด ๊ณ ์๋ ์์ ์ด์งํธ๋ฆฌ๋ฅผ ๊ธฐ๋ณธ์ผ๋ก ํ ์๋ฃ๊ตฌ์กฐ์ ๋๋ค.
์์ ์ด์งํธ๋ฆฌ
์๋์ ์ด๋ฏธ์ง์ฒ๋ผ
์ผ์ชฝ ์์ ๋ ธ๋๋ถํฐ ์ฑ์๊ฐ๋ฉฐ ๋ง์ง๋ง ๋ ๋ฒจ์ ์ ์ธํ๊ณ
๋ชจ๋ ์์ ๋ ธ๋๊ฐ ์ฑ์์ ธ ์๋ ํธ๋ฆฌ๋ฅผ ๋งํฉ๋๋ค.
ํ์ ์ข ๋ฅ
์์ ์ค๋ช ์์ ํ์
์ต๋๊ฐ๊ณผ ์ต์๊ฐ์ ๋น ๋ฅด๊ฒ ์ฐพ๊ธฐ ์ํด์ ๋ง๋ค์ด์ง ์๋ฃ๊ตฌ์กฐ๋ผ๊ณ ํ๋๋ฐ
์ฌ๊ธฐ์ ์ต๋๊ฐ๊ณผ ์ต์๊ฐ์ ๋น ๋ฅด๊ฒ ์ฐพ๊ธฐ ์ํด์
ํ์ ๋๊ฐ์ง๊ฐ ์กด์ฌํฉ๋๋ค.
์ต๋ ํ
์์ ๋ ธ๋์ ๊ฐ์ด ์์ ์ ๊ฐ๋ณด๋ค ์๊ฑฐ๋ ๊ฐ์ ํ์ ๋งํฉ๋๋ค.
๋ฐ๋ผ์ ๋ฃจํธ ๋ ธ๋์ ๊ฐ์ ํญ์ ์ต๋๊ฐ์ด ๋ฉ๋๋ค.
์ต์ ํ
์์ ๋ ธ๋์ ๊ฐ์ด ์์ ์ ๊ฐ๋ณด๋ค ํฌ๊ฑฐ๋ ๊ฐ์ ํ์ ๋งํฉ๋๋ค.
๋ฐ๋ผ์ ๋ฃจํธ ๋ ธ๋์ ๊ฐ์ ํญ์ ์ต์๊ฐ์ด ๋ฉ๋๋ค.
์์ ๋๊ฐ์ง ๋ชจ๋ BST(Binary Search Tree)์๋ ๋ค๋ฅด๊ฒ ์ผ์ชฝ ์์, ์ค๋ฅธ์ชฝ ์์ ๋ ธ๋ ๊ฐ์ ๋์๋ ์๊ด์์ต๋๋ค.
์ฆ, ์ผ์ชฝ์ด๋ ์ค๋ฅธ์ชฝ์ด๋ ํฌ๊ฑฐ๋ ์์๋ ์๊ด์๋ค๋ ์ด์ผ๊ธฐ์ ๋๋ค.
โ๏ธ Swift๋ก ๊ตฌํํด ๋ณด๊ธฐ
์ผ์ชฝ ๋ ธ๋๋ถํฐ ๊ฐ์ ์ฑ์๊ฐ๋ ํน์ง์ผ๋ก ์ธํด
ํ์ ๋ฐฐ์ด๋ก ๊ตฌํ์ด ๊ฐ๋ฅํฉ๋๋ค.
๋ฐ๋ผ์ ๋ ธ๋์ ์์๋ฅผ index๋ก ํํํ ์ ์๊ฒ ๋ฉ๋๋ค.
์ธ๋ฑ์ค
์์ ์ด๋ฏธ์ง๋ฅผ ๊ธฐ์ค์ผ๋ก ์ค๋ช ํด ๋ณด๋ฉด
๊ฐ์ด 4์ธ ๋ ธ๋์ index๋ 2์ ๋๋ค.
์ผ์ชฝ ์์ ๋ ธ๋๋ (๋ถ๋ชจ๋ ธ๋์ ์ธ๋ฑ์ค * 2)์ธ 4๊ฐ ๋๊ณ
์ค๋ฅธ์ชฝ ์์ ๋ ธ๋๋ (๋ถ๋ชจ๋ ธ๋์ ์ธ๋ฑ์ค * 2 + 1)์ธ 5๊ฐ ๋ฉ๋๋ค.
๋ฐ๋๋ก ์์๋ ธ๋๋ฅผ ๊ธฐ์ค์ผ๋ก
๋ถ๋ชจ๋ ธ๋๋ (์์๋ ธ๋์ ์ธ๋ฑ์ค / 2)๋ก ( 4 / 2, 5 / 2)์ธ 2๊ฐ ๋ฉ๋๋ค.
์ด๋ฌํ ํน์ฑ์ผ๋ก ์ธํด ์ฒซ ๋ฒ์งธ ์ธ๋ฑ์ค๋ฅผ 0๋ฒ์ด ์๋
1๋ฒ ์ธ๋ฑ์ค๋ถํฐ ์ฌ์ฉํ์ฌ
์ฝ๋์ ๋ณต์ก์ฑ์ ํด์์ํต๋๋ค.
1. Heap
class Heap<T: Comparable> {
var heap: Array<T> = []
init() { }
init(data: T) {
// ์์์ ์ค๋ช
ํ๋ ๊ฒ์ฒ๋ผ 0๋ฒ ์ธ๋ฑ์ค๋ ์ฌ์ฉํ์ง ์๊ธฐ ๋๋ฌธ์ ์ฒ์ ๋ฐ์ ๋ฐ์ดํฐ๋ก ์ฑ์๋ก๋๋ค.
// ๋ฃจํธ๋
ธ๋๊ฐ ์๋๋๋ค.
heap.append(data)
// 1๋ฒ ์ธ๋ฑ์ค
// ๋ฃจํธ ๋
ธ๋์
๋๋ค.
heap.append(data)
}
}
2. ์ฝ์
์ฝ์ ์ ์์ ์ด์งํธ๋ฆฌ์ด๋ฏ๋ก
๊ฐ์ฅ ํ์์ ์ผ์ชฝ ๋ ธ๋์ ๋จผ์ ๋ฐ์ดํฐ๋ฅผ ๋ฃ์ต๋๋ค.
์ดํ์ ์์ ์ ๋ถ๋ชจ๋ ธ๋์ ๊ฐ์ ๋น๊ตํ๋ฉด์ ์์ ์ด ๋ค์ด๊ฐ ์์น๋ฅผ ๊ฒฐ์ ํ๊ฒ ํฉ๋๋ค.
์ต๋ํ์ผ ๊ฒฝ์ฐ ์์ ๋ณด๋ค ๋ถ๋ชจ๊ฐ ๊ฐ์ด ์๋ค๋ฉด ์๋ก์ ์์น๋ฅผ ์ค์์นญํ๊ณ
์ต์ํ์ผ ๊ฒฝ์ฐ ์์ ๋ณด๋ค ๋ถ๋ชจ์ ๊ฐ์ด ํฌ๋ค๋ฉด ์๋ก์ ์์น๋ฅผ ์ค์์นญํ๊ฒ ๋๋ ๊ฒ์ ๋๋ค.
์๋์ ์ฝ๋๋ ์ต๋ํ์ ๊ธฐ์ค์ผ๋ก ์์ฑํ์ต๋๋ค.
func insert(_ data: T) {
if heap.count == 0 {
heap.append(data)
heap.append(data)
return
}
heap.append(data)
heapifyUp()
}
func heapifyUp() {
var index = heap.count - 1
// ์ถ๊ฐ๋ ๋ฐ์ดํฐ๋ ๊ฐ์ฅ ํ์๋
ธ๋์ ์ผ์ชฝ ๋
ธ๋. ์ฆ, ์ธ๋ฑ์ค์ ๊ฐ์ฅ ๋์
๋๋ค.
var parent = Int(i / 2)
// ์์ ์ค๋ช
ํ ๊ฒ ์ฒ๋ผ ๋ถ๋ชจ๋
ธ๋๋ ์์ ์ ์ธ๋ฑ์ค / 2 ์
๋๋ค.
// ์ต๋ํ
while True {
// ์์ ๋ณด๋ค ๋ถ๋ชจ๋
ธ๋์ ๊ฐ์ด ๋ ์๋ค๋ฉด ๋์ ์๋ฆฌ๋ฅผ ๋ฐ๊ฟ์ค๋๋ค.
if heap[index] > heap[parent] {
heap.swapAt(index, parent)
// ์์ ์ ์ธ๋ฑ์ค๊ฐ ๋ถ๋ชจ์ ์ธ๋ฑ์ค๋ก ๋ณ๊ฒฝ๋์์ผ๋ ๋ถ๋ชจ์ ์ธ๋ฑ์ค๋ฅผ ์์ ์ ์ธ๋ฑ์ค๋ก ๋ณ๊ฒฝํฉ๋๋ค.
index = parent
// ๋ค์ ๋น๊ตํ ๋ถ๋ชจ์ธ๋ฑ์ค๋ฅผ ๊ณ์ฐํฉ๋๋ค.
parent = Int(i / 2)
} else {
// ๋ถ๋ชจ๋
ธ๋์ ๊ฐ์ด ํฌ๋ค๋ฉด ๋ฃจํ์์ ํ์ถํฉ๋๋ค.
break
}
}
}
3. ์ถ์ถ
์ต๋ํ์ ์ต๋๊ฐ์ ๊บผ๋ด๋ ๊ฒ์ ๋งํ๊ณ
์ต์ํ์ ์ต์๊ฐ์ ๊บผ๋ด๋ ๊ฒ์ ๋งํฉ๋๋ค.
๋ฐ๋ผ์ ๋ฃจํธ๋ ธ๋์ ๊ฐ์ ๊บผ๋ด๊ณ
๊ฐ์ฅ ํ์๋ ธ๋์ ์ค๋ฅธ์ชฝ ๋ ธ๋๋ฅผ ์ต์์ ๋ ธ๋๋ก ์ฎ๊น๋๋ค.
์ดํ์ ์ฝ์ ๊ณผ๋ ๋ฐ๋๋ก ์์๋ ธ๋๋ค๊ณผ ๊ฐ์ ๋น๊ตํด ์์ ์ ์์น๋ฅผ ๊ฒฐ์ ํฉ๋๋ค.
์ต๋ํ์ ๊ฒฝ์ฐ, ์์ ๋ณด๋ค ์์๋ ธ๋์ ๊ฐ์ด ํฌ๋ค๋ฉด ๊ณ์ํด์ ์ค์์นญํ๋ฉด์ ๋ด๋ ค๊ฐ๋๋ค.
์ต์ํ์ ๊ฒฝ์ฐ, ์์ ๋ณด๋ค ์์๋ ธ๋์ ๊ฐ์ด ์๋ค๋ฉด ๊ณ์ํด์ ์ค์์นญํ๋ฉด์ ๋ด๋ ค๊ฐ๊ฒ ๋ฉ๋๋ค.
func pop<T : data>() -> T {
// popํ๋ ค๋ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅ
var popItem = heap[1]
// ๋ฃจํธ๋
ธ๋์ ๊ฐ์ ๊ฐ์ฅ ๋ง์ง๋ง ๋
ธ๋๋ก ๋ฐ๊ฟ์ค๋๋ค.
heap[1] = heap[heap.count - 1]
heap.popLast()
heapifyDown(index: 1)
return popItem
}
func heapifyDown(index: Int) {
var left = index * 2
var right = index * 2 + 1
var max = index
// ์ผ์ชฝ ๋
ธ๋์ ๊ฐ์ด ์์ ๋ณด๋ค ํฌ๋ค๋ฉด ํด๋น ์ธ๋ฑ์ค๋ฅผ ๋ฃ์ด์ค๋๋ค.
if left <= heap.count - 1 && heap[left] > heap[max] {
max = left
}
// ์ค๋ฅธ์ชฝ ๋
ธ๋์ ๊ฐ์ด ์์ ๋ณด๋ค ํฌ๋ค๋ฉด ํด๋น ์ธ๋ฑ์ค๋ฅผ ๋ฃ์ด์ค๋๋ค.
if right <= heap.count - 1 && heap[right] > heap[max] {
max = right
}
// ๊ธฐ์กด์ ์์ ์ ์ธ๋ฑ์ค์ ๋ค๋ฅธ ์ธ๋ฑ์ค๋ฅผ ๊ฐ์ง๊ฒ ๋์๋ค๋ฉด
if max != index {
heap.swapAt(index, max)
heapifyDown(index: max)
// ๋ณ๊ฒฝ๋ ์ธ๋ฑ์ค๋ถํฐ ๋ค์ heapify
}
}
๋ ์ข์ ๊ธ๋ก ์ฐพ์๋ต๊ฒ ์ต๋๋ค ~
๊ทธ๋ผ ์๋ ~ ๐๐ป๐๐ป๐๐ป
'์๋ฃ๊ตฌ์กฐ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Swift] ์๋ฃ๊ตฌ์กฐ - ์ด์ง ํ์ํธ๋ฆฌ ( Binary Search Tree ) (0) | 2022.05.14 |
---|---|
[Swift] ์๋ฃ๊ตฌ์กฐ - ํด์ ํ ์ด๋ธ(Hash Table) (0) | 2022.04.21 |
[Swift] ์๋ฃ๊ตฌ์กฐ - ๋จ๋ฐฉํฅ / ์๋ฐฉํฅ ์ฐ๊ฒฐ ๋ฆฌ์คํธ(Linked List) (2) | 2022.04.20 |
[Swift] ์๋ฃ๊ตฌ์กฐ - ํ(Queue) (0) | 2022.04.19 |
[Swift] ์๋ฃ๊ตฌ์กฐ - ์คํ(Stack) (0) | 2022.04.18 |