์๋ ํ์ธ์ Foma ๐ป ์ ๋๋ค!
์์ฆ ์๊ณ ๋ฆฌ์ฆ์ ๊ณต๋ถํ๊ณ ์๋๋ฐ ๊ทธ ์ค ํ์ํธ์ ๋ํด ์๊ฒ ๋์์ต๋๋ค.
ํ์ํธ๋ฅผ ํ๋ ค๋ฉด ํ์ด๋ผ๋ ์๋ฃ๊ตฌ์กฐ๊ฐ ํ์ํ๋๋ผ๊ตฌ์.
๊ทธ๋์ ํ์ด ๋ฌด์์ด๊ณ ์ด๋ป๊ฒ ๊ตฌํํ๋์ง์ ๋ํด ์ ๋ฆฌํ๋ ค๊ณ ํฉ๋๋ค!
๋ฐ๋ก ์์ํ ๊ฒ์~
์์ ์ด์งํธ๋ฆฌ(Complete Binary Tree)๋? โ
๋จผ์ ํ์ ๋ํด ์์๋ณด๊ธฐ ์ ์ ์์ ์ด์งํธ๋ฆฌ์ ๋ํด์ ์์๋ณด๊ฒ ์ต๋๋ค.
์ด์ ๋ ํ์ด ์์ ์ด์งํธ๋ฆฌ๋ก ๋์ด์๊ธฐ ๋๋ฌธ์ ๋๋ค.
์์ ์ด์ง ํธ๋ฆฌ์์, ๋ง์ง๋ง ๋ ๋ฒจ์ ์ ์ธํ๊ณ ๋ชจ๋ ๋ ๋ฒจ์ด ์์ ํ ์ฑ์์ ธ ์์ผ๋ฉฐ, ๋ง์ง๋ง ๋ ๋ฒจ์ ๋ชจ๋ ๋ ธ๋๋ ๊ฐ๋ฅํ ํ ๊ฐ์ฅ ์ผ์ชฝ์ ์๋ค. ๋ง์ง๋ง ๋ ๋ฒจ h ์์ 1๋ถํฐ 2h-1 ๊ฐ์ ๋ ธ๋๋ฅผ ๊ฐ์ง ์ ์๋ค. ์์ ์ด์ง ํธ๋ฆฌ๋ ๋ฐฐ์ด์ ์ฌ์ฉํด ํจ์จ์ ์ผ๋ก ํํ ๊ฐ๋ฅํ๋ค. - ์ํค ๋ฐฑ๊ณผ -
์ฆ, ๋งจ ๋ง์ง๋ง ๋ ธ๋์ ์์ ๋นผ๊ณ ๋ชจ๋ ๋ ธ๋๊ฐ ๋๊ฐ์ฉ ์์์ ๊ฐ์ง๊ณ ์์ด์ผ ํ๋ ๊ตฌ์กฐ์ ๋๋ค.
์๋ ๊ทธ๋ฆผ์ ๋ณด์๋ฉด ์ดํดํ๊ธฐ๊ฐ ์์ํ์ค๊ฑฐ์์!
ํ(Heap)์ด๋? ๐
ํ์ ์ต๋๊ฐ ๋ฐ ์ต์๊ฐ์ ์ฐพ์๋ด๋ ์ฐ์ฐ์ ๋น ๋ฅด๊ฒ ํ๊ธฐ ์ํด ๊ณ ์๋ ์์ ์ด์งํธ๋ฆฌ๋ฅผ ๊ธฐ๋ณธ์ผ๋ก ํ ์๋ฃ๊ตฌ์กฐ์ด๋ค. - ์ํค ๋ฐฑ๊ณผ -
์ฆ, ์ต๋๊ฐ๊ณผ ์ต์๊ฐ์ ๋น ๋ฅด๊ฒ ์ฐพ์๋ด๊ธฐ ์ํ ์๋ฃ๊ตฌ์กฐ ์ ๋๋ค.
์ต๋ํ(MaxHeap) ๐๐ป
์ต๋ํ์ ์ต๋๊ฐ์ ๋น ๋ฅด๊ฒ ์ฐพ์๋ด๊ธฐ ์ํ ์๋ฃ๊ตฌ์กฐ๋ก,
๋ถ๋ชจ๋ ธ๋์ ํค๊ฐ์ด ์์๋ ธ๋์ ํค๊ฐ๋ณด๋ค ํญ์ ํฐ ํ์ ์๋ฏธํฉ๋๋ค.
์ต์ํ(MinHeap) ๐๐ป
์ต์ํ์ ์ต๋ํ๊ณผ ๋ฐ๋๋ก ์ต์๊ฐ์ ๋น ๋ฅด๊ฒ ์ฐพ์๋ด๊ธฐ ์ํ ์๋ฃ๊ตฌ์กฐ๋ก,
๋ถ๋ชจ๋ ธ๋์ ํค๊ฐ์ด ์์๋ ธ๋์ ํค๊ฐ๋ณด๋ค ํญ์ ๋ ์์ ํ์ ์๋ฏธํฉ๋๋ค.
ํน์ง
๋ฐฐ์ด ํํ๋ก ๊ตฌํํ ์ ์๋ค.
์๊ฐ๋ณต์ก๋
ํ์ ์ ์ฒด ๋์ด๊ฐ logN์ ๋๋ค.
๊ณ ๋ก, ์ฝ์ ์ด๋ ์ญ์ ์์ ๋ ธ๋๋ค์ ์ฌ์ ๋ ฌ ํ ๋ ์ต๋ logN์ ์๊ฐ์ด ๊ฑธ๋ฆฐ๋ค.
๋ชจ๋ N๊ฐ์ ๋ ธ๋๋ค์ด ์ต๋ logN์ ์๊ฐ์ด ๊ฑธ๋ฆฐ๋ค๋ฉด NlogN์ ์๊ฐ์ด ๊ฑธ๋ฆฌ๋ฏ๋ก ์๊ฐ๋ณต์ก๋๋ O(nlogn) ์ ๋๋ค.
Heapify๋?
Heapify๋ ๋ง ๊ทธ๋๋ก ํ์ ์ฑ์ง๋ก ๋ฐ๊ฟ์ฃผ๋ ๊ณผ์ ์ ๋๋ค.
์ฝ์
์๋์ ๊ฐ์ด ํน์ ํ ๊ฐ์ ๊ฐ์ง ๋ ธ๋๊ฐ ์๋กญ๊ฒ ๋ค์ด์์ ๋ ํ์ ์ฑ์ง์ ๋ง๊ฒ ๊ตฌํํ๋ ๊ณผ์ ์ ๋๋ค.
๊ฐ๋จํ ๋งํ๋ฉด ๊ฐ์ฅ ๋ง์ง๋ง์ ์๋กญ๊ฒ ๋ค์ด์จ ๋ ธ๋๋ฅผ ์ฝ์ ํ๊ณ ๋ถ๋ชจ ๋ ธ๋์ ๋น๊ตํ๋ฉด์ ๋ฐ๊ฟ๊ฐ์ฃผ๋ ๊ณผ์ ์ ๋๋ค.
์ญ์
์ญ์ ๋ ๊ฐ์ฅ ์ต๋๊ฐ์ ๊ฐ์ง๊ณ ์๋ ๋ฃจํธ๋ ธ๋๋ฅผ ์ญ์ ํด์ค๋๋ค.
๊ทธ๋ฆฌ๊ณ ๋ฃจํธ ๋ ธ๋ ์์น์ ๊ฐ์ฅ ๋ง์ง๋ง์ ์๋ ๋ ธ๋๋ฅผ ๋์ ํด์ฃผ๊ณ ์์๋ ธ๋๋ค์ ๋น๊ตํด๊ฐ๋ฉด์ ๋ฐ๊ฟ๊ฐ๋ ๊ณผ์ ์ ๋๋ค.
์ฝ๋ ๊ตฌํ
๋ณดํต ํ์ผ๋ก ๋ง์ด ์ฐ์ด๋ MaxHeap์ ๊ตฌํํด๋ณด๊ฒ ์ต๋๋ค.
์ด๊ธฐ์ ๋ฐฐ์ด์ด ์ฃผ์ด์ง๋ค๋ฉด insert๋ฅผ ํตํด ํ์ ๋ง๋๋ ์ด๊ธฐํ ๊ณผ์ ์ ๋ฏธ๋ฆฌ ๋ง๋ค์ด๋๊ณ
๊ธฐ๋ณธ์ ์ผ๋ก ์ฌ์ฉ๋ ๋ถ๋ชจ,์์์ ์ธ๋ฑ์ค๋ฅผ ์์๋ด๋ ํจ์์ ๋ถ๋ชจ๋
์์์ ์ ๋ฌด๋ฅผ ํ์ธํ ํจ์๋ฅผ ๋ฏธ๋ฆฌ ๋ง๋ค์ด๋๊ฒ ์ต๋๋ค.
struct MaxHeap {
var nodes:[Int] = []
init(nodes:[Int]) {
nodes.forEach {
insert($0)
}
}
private func getLeftChildIndex(_ parentIndex: Int) -> Int {
return 2 * parentIndex + 1
}
private func getRightChildIndex(_ parentIndex: Int) -> Int {
return 2 * parentIndex + 2
}
private func getParentIndex(_ childIndex: Int) -> Int {
return (childIndex - 1) / 2
}
private func hasLeftChild(_ index: Int) -> Bool {
return getLeftChildIndex(index) < nodes.count
}
private func hasRightChild(_ index: Int) -> Bool {
return getRightChildIndex(index) < nodes.count
}
private func hasParent(_ index: Int) -> Bool {
return getParentIndex(index) >= 0
}
...
์ฝ์
๋จผ์ ์๋ก์ด ๋ ธ๋๋ฅผ ๊ธฐ์กด์ nodes์ ๋ฃ์ด์ค๋๋ค.
๋งจ ๋ง์ง๋ง ๋ ธ๋๋ถํฐ ์ฐจ๋ก๋ก ์์ ๋ถ๋ชจ์ ํ์ฌ node๋ฅผ ๋น๊ตํด์ค๋๋ค.
๋ง์ฝ ํ์ฌ ๋ ธ๋๊ฐ ๋ ํฌ๋ค๋ฉด ๋ถ๋ชจ์ ์์ ์ swapํด์ค๋๋ค.
์ด๊ฒ์ root๋ ธ๋๊ฐ ๋๊ฑฐ๋ ๋ถ๋ชจ๊ฐ ๋ ํด ๋๊น์ง heapify ๊ณผ์ ์ ์๋ก ๋ฐ๋ณตํฉ๋๋ค.
mutating private func heapifyUp() {
var index = nodes.count - 1
while hasParent(index) && nodes[getParentIndex(index)] < nodes[index] {
nodes.swapAt(getParentIndex(index),index)
index = getParentIndex(index)
}
}
mutating func insert(_ node:Int) {
nodes.append(node)
heapifyUp()
}
์ญ์
nodes๊ฐ ์๋ฌด๊ฒ๋ ์๋ค๋ฉด ์คํํ์ง ์์ต๋๋ค.
๋ง์ฝ ์กด์ฌํ๋ค๋ฉด ๊ฐ์ฅ ์ฒซ๋ฒ์งธ์ ๊ฐ์ฅ ๋ง์ง๋ง ๋ฒ์งธ ๋ ธ๋๋ฅผ ์๋ก ๋ฐ๊ฟ์ฃผ๊ณ
๊ฐ์ฅ ๋ง์ง๋ง ๋ ธ๋๋ฅผ ์ญ์ ํด์ค๋๋ค. (์ด๋ ๊ฒ ํ๋ฉด ๊ฐ์ฅ ํฐ ๊ฐ์ ์ญ์ ํ ๊ฒ๊ณผ ๋๊ฐ๊ฒ ์ฃ ?)
๊ทธ๋ฆฌ๊ณค ๊ฐ์ฅ ์(0)๋ถํฐ ์ฐจ๋ก๋ก ์์๋ค์ด ๋ ์์ ๋๊น์ง heapify๋ฅผ ์๋๋ก ๋ฐ๋ณตํด์ค๋๋ค.
mutating private func heapifyDown() {
var index = 0
while hasLeftChild(index) {
let leftIndex:Int = getLeftChildIndex(index)
let rightIndex:Int = getRightChildIndex(index)
var biggerChildIndex = leftIndex
if hasRightChild(index) && nodes[leftIndex] < nodes[rightIndex] {
biggerChildIndex = rightIndex
}
if nodes[index] > nodes[biggerChildIndex] {
break
} else {
nodes.swapAt(index, biggerChildIndex)
}
index = biggerChildIndex
}
}
mutating func remove() {
if nodes.isEmpty {
return
}
nodes.swapAt(0, nodes.count - 1)
nodes.removeLast()
heapifyDown()
}
์ฝ์ ํ๊ณ ์ญ์ ๋ฅผ ํ๋ ๊ณผ์ ์ ์ถ๋ ฅํด๋ณด๋ฉด ์๋์ ๊ฐ์ต๋๋ค.
var heap = MaxHeap(nodes: [1,5,3]) //[5,1,3]
heap.insert(4) //[5,4,3,1]
heap.insert(2) //[5,4,3,1,2]
heap.insert(1) //[5,4,3,1,2,1]
heap.insert(2) //[5,4,3,1,2,1,2]
heap.remove() //[4,2,3,1,2,1]
heap.remove() //[3,2,1,1,2]
heap.remove() //[2,2,1,1]
heap.insert(7) //[7, 2, 1, 1, 2]
heap.insert(5) //[7, 2, 5, 1, 2, 1]
์ ์ฒด ์ฝ๋
Reference
์๋ ๋ธ๋ก๊ทธ๋ฅผ ์ฐธ๊ณ ํ์ต๋๋ค.
๋๊ธ