Heap์ ํธ๋ฆฌ ๊ธฐ๋ฐ์ ์๋ฃ๊ตฌ์กฐ๋ก, ํน์ ์ฐ์ ์์์ ๋ฐ๋ผ ์์๋ค์ ์ ๋ ฌํ๋ ๊ธฐ๋ฅ์ ์ ๊ณตํฉ๋๋ค.
Heap์ ํฌ๊ฒ ๋ ๊ฐ์ง ์ ํ์ด ์์ต๋๋ค.
์ต์ ํ์ ์์ ๊ฐ์ด ๋จผ์ ๋์ค๋๋ก ์ ๋ ฌํ๊ณ , ์ต๋ ํ์ ํฐ ๊ฐ์ด ๋จผ์ ๋์ค๋๋ก ์ ๋ ฌํฉ๋๋ค.
์ ๋ค๋ฆญ์ ์ด์ฉํด Heap ๊ตฌ์กฐ์ฒด๋ฅผ ์ ์ํ๊ณ ์ฃผ์ ๊ธฐ๋ฅ์ ๊ตฌํํด๋ณด๊ฒ ์ต๋๋ค.
struct Heap<T> {
private var elements: [T] = []
private let priorityFunction: (T, T) -> Bool
var isEmpty: Bool {
return elements.isEmpty
}
var count: Int {
return elements.count
}
var peek: T? {
return elements.first
}
init(priorityFunction: @escaping (T, T) -> Bool) {
self.priorityFunction = priorityFunction
}
mutating func push(_ element: T) {
elements.append(element)
siftUp(from: elements.count - 1)
}
mutating func pop() -> T? {
guard !isEmpty else { return nil }
elements.swapAt(0, count - 1)
let element = elements.removeLast()
if !isEmpty {
siftDown(from: 0)
}
return element
}
private mutating func siftUp(from index: Int) {
var childIndex = index
let child = elements[childIndex]
var parentIndex = self.parentIndex(of: childIndex)
while childIndex > 0 && priorityFunction(child, elements[parentIndex]) {
elements[childIndex] = elements[parentIndex]
childIndex = parentIndex
parentIndex = self.parentIndex(of: childIndex)
}
elements[childIndex] = child
}
private mutating func siftDown(from index: Int) {
let parent = elements[index]
var parentIndex = index
while true {
let leftChildIndex = self.leftChildIndex(of: parentIndex)
let rightChildIndex = leftChildIndex + 1
var candidateIndex = parentIndex
if leftChildIndex < count && priorityFunction(elements[leftChildIndex], elements[candidateIndex]) {
candidateIndex = leftChildIndex
}
if rightChildIndex < count && priorityFunction(elements[rightChildIndex], elements[candidateIndex]) {
candidateIndex = rightChildIndex
}
if candidateIndex == parentIndex {
return
}
elements.swapAt(parentIndex, candidateIndex)
parentIndex = candidateIndex
}
elements[parentIndex] = parent
}
private func parentIndex(of index: Int) -> Int {
return (index - 1) / 2
}
private func leftChildIndex(of index: Int) -> Int {
return 2 * index + 1
}
private func rightChildIndex(of index: Int) -> Int {
return 2 * index + 2
}
}
์ ์ฝ๋์์๋ Heap์ ๊ธฐ๋ณธ ๋์์ ๊ตฌํํ์ต๋๋ค.
- push(_:): ์๋ก์ด ์์๋ฅผ ํ์ ์ถ๊ฐํ๊ณ ํ์ ์์ฑ์ ์ ์งํฉ๋๋ค. ์๊ฐ ๋ณต์ก๋๋ O(log n)์ ๋๋ค.
- pop(): ํ์ ์ต์์ ์์๋ฅผ ์ ๊ฑฐํ๊ณ ๋ฐํํ๋ฉฐ, ์ ๊ฑฐ ํ ํ์ ์์ฑ์ ์ ์งํฉ๋๋ค. ์๊ฐ ๋ณต์ก๋๋ O(log n)์ ๋๋ค.
- peek: ์ต์์ ์์๋ฅผ ์ ๊ฑฐํ์ง ์๊ณ ๋ฐํํฉ๋๋ค. ์๊ฐ ๋ณต์ก๋๋ O(1)์ ๋๋ค.
- siftUp(from:): ์๋ก์ด ์์๋ฅผ ์ฝ์ ํ ์ฌ๋ฐ๋ฅธ ์์น๋ก ์ด๋์ํต๋๋ค.
- siftDown(from:): ์ต์์ ์์๋ฅผ ์ ๊ฑฐํ ํ ํ ์์ฑ์ ์ ์งํ๋๋ก ์ฌ๋ฐฐ์นํฉ๋๋ค.
๊ตฌํํ Heap์ ๋ค์๊ณผ ๊ฐ์ด ์ฌ์ฉํ ์ ์์ต๋๋ค.
// ์ต์ ํ ํ
์คํธ
var minHeap = Heap<Int> { $0 < $1 }
minHeap.push(3)
minHeap.push(1)
minHeap.push(4)
minHeap.push(1)
minHeap.push(5)
print("Min Heap Test:")
while let element = minHeap.pop() {
print(element)
}
์ถ๋ ฅ
Min Heap Test:
1
1
3
4
5
// ์ต๋ ํ ํ
์คํธ
var maxHeap = Heap<Int> { $0 > $1 }
maxHeap.push(3)
maxHeap.push(1)
maxHeap.push(4)
maxHeap.push(1)
maxHeap.push(5)
print("\nMax Heap Test:")
while let element = maxHeap.pop() {
print(element)
}
์ถ๋ ฅ
Max Heap Test:
5
4
3
1
1
์ต์ ํ์ ์ค๋ฆ์ฐจ์์ผ๋ก ์์๋ฅผ ๋ฐํํ๊ณ , ์ต๋ ํ์ ๋ด๋ฆผ์ฐจ์์ผ๋ก ์์๋ฅผ ๋ฐํํฉ๋๋ค.
์ด ๊ตฌ์กฐ๋ ์ ๋ ฌ ์๊ณ ๋ฆฌ์ฆ์ด๋ ์ฐ์ ์์ ํ ๊ฐ์ ๋ค์ํ ์์ฉ ํ๋ก๊ทธ๋จ์์ ๋งค์ฐ ์ ์ฉํ๊ฒ ์ฌ์ฉ๋ ์ ์์ต๋๋ค.
'โจ๏ธ Language > swift' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Swift] ์ฐ์ ์์ ํ(Priority Queue) ๊ตฌํํ๊ธฐ (0) | 2024.09.27 |
---|---|
[Swift] Dequeue ๊ตฌํํ๊ธฐ (0) | 2024.09.27 |
[Swfit] ํ(Queue) ๊ตฌํํ๊ธฐ (1) | 2024.09.27 |
[Swift] ์คํ(Stack) ๊ตฌํํ๊ธฐ (0) | 2024.09.27 |
[Swift] ์๋ ์ฐธ์กฐ ์นด์ดํธ (0) | 2024.04.02 |