[Swift] ν(Heap) ꡬννκΈ°
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
μ΅μ νμ μ€λ¦μ°¨μμΌλ‘ μμλ₯Ό λ°ννκ³ , μ΅λ νμ λ΄λ¦Όμ°¨μμΌλ‘ μμλ₯Ό λ°νν©λλ€.
μ΄ κ΅¬μ‘°λ μ λ ¬ μκ³ λ¦¬μ¦μ΄λ μ°μ μμ ν κ°μ λ€μν μμ© νλ‘κ·Έλ¨μμ λ§€μ° μ μ©νκ² μ¬μ©λ μ μμ΅λλ€.