์ค์ํํธ๋ก ๊ตฌํํ๋ ์๋ฃ๊ตฌ์กฐ 5: ํ(Heap)
ํ (Heap)
ํ์ ์ด์งํธ๋ฆฌ๋ฅผ ์ฌ์ฉํด์ ๋ฐ์ดํฐ๋ค์ ๋ฐ์ ๋ ฌ ์ํ๋ก ์ ์งํ๋ ์๋ฃ๊ตฌ์กฐ์ ๋๋ค. ํ์ ํธ๋ฆฌ์ ๋ฃจํธ ๋ ธ๋์ ๋ฐ์ดํฐ๋ค์ ์ต์๊ฐ ํน์ ์ต๋๊ฐ์ ์ ์ฅํ๋๋ฐ์, ์ต์๊ฐ์ ๋ฃจํธ์ ๋ ๋๋ ์ต์ํ, ์ต๋๊ฐ์ ๋ฃจํธ์ ๋๋ฉด ์ต๋ํ์ด๋ผ๊ณ ํฉ๋๋ค.
์์ ์ด์ง ํธ๋ฆฌ
์ด์ง ํธ๋ฆฌ๋ ํธ๋ฆฌ๋ฅผ ๊ตฌ์ฑํ๋ ๋ชจ๋ ๋ ธ๋๊ฐ ์ต๋ ๋ ๊ฐ์ ์์ ๋ ธ๋๋ฅผ ๊ฐ์ง๋ ์๋ฃ๊ตฌ์กฐ์ ๋๋ค. ๊ทธ๋ฆฌ๊ณ ์์ ์ด์ง ํธ๋ฆฌ๋ ๊ฐ ๋์ด์ ์๋ ๋ชจ๋ ๋ ธ๋๊ฐ ์์ ๋ ธ๋๋ฅผ ๊ฐ์ ธ์ผ ๋ค์ ๋์ด์ ์ ๋ ธ๋๋ฅผ ์ถ๊ฐํ ์ ์๊ณ , ๊ฐ์ฅ ์ผ์ชฝ๋ถํฐ ์ฐจ๋ก๋๋ก ๋ ธ๋๋ฅผ ์ฑ์์ผํฉ๋๋ค.

์ด๋ฐ ์ด์ง ํธ๋ฆฌ๋ ๋ฐฐ์ด๋ก๋ ๊ตฌํ์ด ๊ฐ๋ฅํ๋ฐ์, ๋ฃจํธ ๋ ธ๋๋ฅผ ์ธ๋ฑ์ค 1๋ก ์ผ์ผ๋ฉด ์ด๋ค index ๋ฒ์งธ ๋ ธ๋์ ์ผ์ชฝ ์์ ๋ ธ๋๋ index * 2, ์ค๋ฅธ์ชฝ ์์ ๋ ธ๋๋ (index * 2) + 1 ๋ก ๊ตฌํ ์ ์์ต๋๋ค.

์ฐ๋ฆฌ๋ ํ์ ์ด ๋ฐฐ์ด ๊ธฐ๋ฐ์ ์ด์ง ํธ๋ฆฌ๋ฅผ ํตํด์ ๊ตฌํํ ๊ฑฐ์์!

๊ทธ๋ฆฌ๊ณ ํ์ ์ด์ง ํธ๋ฆฌ๋ ํธ๋ฆฌ๋ฅผ ๊ตฌ์ฑํ๋ ๊ฐ ์๋ธ ํธ๋ฆฌ๋ค๋ ๋ชจ๋ ํ์ ๋ง์กฑํด์ผํฉ๋๋ค.
๋ผ๋ ๋ง๋ค๊ธฐ
import Foundation struct Heap<T: Comparable> { private var elements: [T] = [] private let sortFunction: (T, T) -> Bool var isEmpty: Bool { return self.elements.count == 1 } var peek: T? { if self.isEmpty { return nil } return self.elements[1] } var count: Int { return self.elements.count - 1 } init(elements: [T] = [], sortFunction: @escaping (T, T) -> Bool) { if !elements.isEmpty { self.elements = [elements.first!] + elements } else { self.elements = elements } self.sortFunction = sortFunction if elements.count > 1 { self.buildHeap() } } func leftChild(of index: Int) -> Int { return index * 2 } func rightChild(of index: Int) -> Int { return index * 2 + 1 } func parent(of index: Int) -> Int { return (index) / 2 } }
๋จผ์ ๊ธฐ๋ณธ์ ์ธ ํ๋กํผํฐ๋ค๊ณผ ์์ฑ์, ๋ฉ์๋๋ฅผ ๊ตฌํํด์ฃผ์์ต๋๋ค.
elements ๋ ์ค์ ๋ก ๋ฐ์ดํฐ๋ค์ ์ ์ฅํ ์ด์งํธ๋ฆฌ๋ก ํํ๋ ๋ฐฐ์ด์ด๊ณ , sortFunction์ ์ต์ํ, ์ต๋ํ์ ๊ธฐ์ค์ ์ผ๋ก ์ผ์ ์ ๋ ฌ ๋ก์ง์ ๊ฐ์ง ํด๋ก์ ์ ๋๋ค. ๋ง์ฝ ์ ์ฅ๋๋ ๋ฐ์ดํฐ๊ฐ ์ ์์ด๊ณ , sortFunction์ด ์ค๋ฆ์ฐจ์ ์ ๋ ฌ์ด๋ฉด ์ต์ํ์ด ๋๊ณ , ๋ด๋ฆผ์ฐจ์ ์ ๋ ฌ์ด๋ฉด ์ต๋ํ์ด ๋๊ฒ ์ฃ ?
isEmpty ํ๋กํผํฐ๋ ํ์ฌ ์ด์งํธ๋ฆฌ์ ์์๋ค์ด 1๊ฐ์ธ์ง ํ์ธํ๋ ๊ฒ์ผ๋ก ํ๋ณํฉ๋๋ค. ๋ฐฐ์ด์ 0๋ฒ์งธ ์ธ๋ฑ์ค๋ ์ฌ์ฉํ์ง ์๋ ๊ฐ์ด๋ ๋ฐฐ์ด์ ๊ฐ์ด ํ๋๋ง ์์ ๋ ํธ๋ฆฌ๊ฐ ๋น์์ ธ ์๋ ๊ฒ์ ๋๋ค.
leftChild, rightChild, parent๋ ์์์ ์ค๋ช ํ๋๋๋ก ๋ถ๋ชจ์ ์์๋ ธ๋์ ์ธ๋ฑ์ค๋ฅผ ๊ตฌํ๋ ๋ฉ์๋์ด๊ตฌ์, ์์ฑ์์ buildHeap๋ ์ ์ ๋ค์ ์ค๋ช ํ๊ฒ ์ต๋๋ค!
์ฝ์ (insert) - O(log N)
ํ์ ์ฝ์ ์ ๋ค์๊ณผ ๊ฐ์ ๊ณผ์ ์ผ๋ก ์งํ๋ฉ๋๋ค.

์ด๋ ๊ฒ ์ต๋ํ์ด ์์ ๋ ์๋ก์ด ๋ฃจํธ๋ ธ๋๊ฐ ๋ ๋ ธ๋๋ฅผ ํ๋ ์ฝ์ ํ๋ค๊ณ ํด๋ณด๊ฒ ์ต๋๋ค.

๋จผ์ ๊ฐ์ฅ ์ผ์ชฝ ๋ฆฌํ๋ ธ๋์ ์๋ก ์ถ๊ฐํ ๋ ธ๋๋ฅผ ๋ถ์ฌ์ค๋๋ค.
์ด์ ์ต๋ ํ์ ์ ์งํ๊ธฐ ์ํด ํธ๋ฆฌ๋ฅผ ์ฌ์กฐ์ ํด์ฃผ์ด์ผ ํ๋๋ฐ์, ๊ฐ์ฅ ๋์ ๋ ธ๋๋ฅผ ๋ถ์์ผ๋ ์ด ๋ ธ๋๋ฅผ ์ฌ๋ผ๊ฐ ์ ์๋ ์ต๋ํ ์ฌ๋ ค์ฃผ์ด์ผ ํฉ๋๋ค. ๊ทธ๋์ผ ํธ๋ฆฌ์ ๊ฐ ์๋ธ ํธ๋ฆฌ๋ค๋ ์ต๋ ํ์ ๋ง์กฑํ๋๊น์.

๋จผ์ 9๋ ๋ถ๋ชจ ๋ ธ๋์ธ 1๋ณด๋ค ํฌ๊ธฐ ๋๋ฌธ์ ๋ ๋ ธ๋๋ฅผ ๊ตํํด์ค๋๋ค.

9์ ์๋ก์ด ๋ถ๋ชจ ๋ ธ๋ 4๋ 9๋ณด๋ค ์๋ค์. ๋ค์ ๊ตํํฉ์๋ค.

๊ทธ๋ฆฌ๊ณ ๋ค์ ์๋ก์ด ๋ถ๋ชจ๋ ธ๋์ธ 7๋ณด๋ค๋ ํฌ๊ธฐ ๋๋ฌธ์ ์๋ก์ด ๋ฃจํธ๋ ธ๋๋ 9๊ฐ ๋ฉ๋๋ค.

์ ์ฒด ํธ๋ฆฌ์ ๋ชจ๋ ์๋ธํธ๋ฆฌ๊ฐ ์ต๋ํ์ ๋ง์กฑํ๋ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค!
์ฝ์ ๊ตฌํ - swimUp
๊ฒฐ๊ตญ ์ฝ์ ์ฐ์ฐ์
1) ํธ๋ฆฌ ์ ์ผ ๋์ ์ ๋ ธ๋ ๋ถ์ด๊ธฐ
2) ์ ๋ ธ๋๋ฅผ ์ฌ๋ฆด ์ ์๋๋ฐ๊น์ง ์ฌ๋ฆฌ๊ธฐ
๋ ๋จ๊ณ๋ก ์งํ๋ฉ๋๋ค.
์ด๋ 2๋ฒ ๊ณผ์ ์ ์ ์๊ฒ ์๋ฃ๊ตฌ์กฐ๋ฅผ ๊ฐ๋ฅด์ณ์ฃผ์ ๊ต์๋์ swimUp ์ด๋ผ๊ณ ํํํ์ จ๋๋ฐ์, ๋ง์น ์์ํด์ ์ฌ๋ผ๊ฐ๋ ๊ฒ ๊ฐ๋ค๊ณ ...
swimUp์ ๊ตฌํํด๋ด ์๋ค.
mutating func swimUp(from index: Int) { var index = index while index != 1 && self.sortFunction(self.elements[index], self.elements[self.parent(of: index)]) { self.elements.swapAt(index, self.parent(of: index)) index = self.parent(of: index) } }
๋๋ฌ์ต๋๋ค..ใ ใ ใ ใ
๋ฃจํธ๋ ธ๋์ ๋ค๋ค๋ฅด๊ฑฐ๋, ํ์ฌ ๋ ธ๋๊ฐ ๋ถ๋ชจ ๋ ธ๋๋ณด๋ค ์ฐ์ ์์๊ฐ ๋ฎ์์ง๊ธฐ ์ ๊น์ง ๋ ธ๋์ ๋ถ๋ชจ๋ ธ๋๋ฅผ ๊ณ์ ๊ตํํด์ค๋๋ค. ์ ๊ทธ๋ฆผ์ ์์์ ๋ํ ์๊ณ ๋ฆฌ์ฆ ๋์ ๊ณผ์ ์ ์จ๋ณด๋ฉด
1. ํ์ฌ ์ธ๋ฑ์ค 8๋ถํฐ swimUp ์์!
2. ํ์ฌ ์ธ๋ฑ์ค์ ๊ฐ 9๋ ๋ถ๋ชจ ์ธ๋ฑ์ค 4์ ๊ฐ 1๋ณด๋ค ํฌ๊ธฐ ๋๋ฌธ์ ๋ ๋ ธ๋์ ๊ฐ์ ๊ตํํ๊ณ ํ์ฌ ์ธ๋ฑ์ค๋ฅผ ๋ถ๋ชจ ์ธ๋ฑ์ค์ธ 4๋ก ๋ณ๊ฒฝํฉ๋๋ค.
3. ํ์ฌ ์ธ๋ฑ์ค 4์ ๊ฐ 9๋ ๋ถ๋ชจ ์ธ๋ฑ์ค 2์ ๊ฐ 4๋ณด๋ค ํฌ๊ธฐ ๋๋ฌธ์ ๋ ๋ ธ๋์ ๊ฐ์ ๊ตํํ๊ณ ํ์ฌ ์ธ๋ฑ์ค๋ฅผ ๋ถ๋ชจ ์ธ๋ฑ์ค์ธ 2๋ก ๋ณ๊ฒฝํฉ๋๋ค.
4. ํ์ฌ ์ธ๋ฑ์ค 2์ ๊ฐ 9๋ ๋ถ๋ชจ ์ธ๋ฑ์ค 1์ ๊ฐ 7๋ณด๋ค ํฌ๊ธฐ ๋๋ฌธ์ ๋ ๋ ธ๋์ ๊ฐ์ ๊ตํํ๊ณ ํ์ฌ ์ธ๋ฑ์ค๋ฅผ ๋ถ๋ชจ ์ธ๋ฑ์ค์ธ 1๋ก ๋ณ๊ฒฝํฉ๋๋ค.
5. ํ์ฌ ์ธ๋ฑ์ค๋ 1์ด๊ธฐ ๋๋ฌธ์ while๋ฌธ์ ๋น ์ ธ๋์์ ํจ์๋ ์ข ๋ฃ๋ฉ๋๋ค.
์ด ์๊ณ ๋ฆฌ์ฆ์ ์ต์ ์ ๊ฒฝ์ฐ์๋ ์ง๊ธ์ฒ๋ผ ๋ฆฌํ๋ ธ๋๋ถํฐ ๋ฃจํธ๋ ธ๋๊น์ง ๊ฑฐ์ฌ๋ฌ ์ฌ๋ผ๊ฐ๋ฉฐ ๊ตํ์ ์งํํ๊ธฐ ๋๋ฌธ์ ์๊ฐ๋ณต์ก๋๋ ํธ๋ฆฌ์ ๋์ด์ ๋ํ ๋ ธ๋ ๊ฐ์์ธ O(log N)๊ฐ ๋ฉ๋๋ค.
๋ฐ๋ผ์ ์ ์ฒด ์ฝ์ ๊ณผ์ ์ ํธ๋ฆฌ ๋์ ๋ฐ์ดํฐ๋ฅผ ํ๋ ์ฝ์ ํ๊ณ swimUp์ ์ํํ๋ O(1) + O(log N) = O(log N)๊ฐ ๋ฉ๋๋ค.
mutating func insert(node: T) { if self.elements.isEmpty { self.elements.append(node) return } self.elements.append(node) self.swimUp(from: self.elements.endIndex - 1) }
์ญ์ (delete) - O(log N)
์ญ์ ๋ ๋ฃจํธ๋ ธ๋์ ์๋ ๊ฐ์ฅ ์ฐ์ ์์๊ฐ ๋์ ๋ ธ๋๋ฅผ ๊บผ๋ด๊ณ ํธ๋ฆฌ๋ฅผ ์ฌ์กฐ์ ํ๋ ์์ ์ด ํ์ํฉ๋๋ค.

์ฌ๊ธฐ์ ์ญ์ ๋ฅผ ํ๋ฉด ๋ฃจํธ๋ ธ๋๊ฐ ๋์ค๊ฒ ์ฃ ? ํ์์์ ์ญ์ ๋ ๋ฃจํธ๋ ธ๋์ ๋ง์ง๋ง ๋ฆฌํ ๋ ธ๋๋ฅผ ๊ตํํด์ฃผ๋ ๊ฒ์ผ๋ก ์์๋ฉ๋๋ค.

์ด๋ ๊ฒ ๊ตํ๋๋ฉด ๋ฃจํธ๋ ธ๋ ์๋ ๋ ธ๋๋ฅผ ์ ๊ฑฐํด์ฃผ๋ ๊ฒ์ ๊ฐ๋จํ๊ฒ ์ฃ ? ํธ๋ฆฌ์์ ์ฐ๊ฒฐ์ ๋์ด์ค๋๋ค.

์ฐ๋ฆฌ๋ ์ด์ง ํธ๋ฆฌ๊ฐ ๋ฐฐ์ด๋ก ๊ตฌํ๋์ด ์๊ธฐ ๋๋ฌธ์ ๋ ธ๋์ ์ญ์ ๊ฐ ์ด๋ ต์ง ์์ต๋๋ค. ๊ทธ๋ฅ ๋ฐฐ์ด์์ ๋ง์ง๋ง ๊ฐ์ ๋นผ์ฃผ๋ฉด ๋๋๊น์!
๋์ ์ต๋ํ์ด ๊นจ์ก๊ธฐ ๋๋ฌธ์ ๋ค์ ํธ๋ฆฌ๋ฅผ ์ฌ์กฐ์ ํด์ผ ํฉ๋๋ค.

๋ฃจํธ ๋ ธ๋์ ์์ ๋ ธ๋๋ค ์ค์ ์ฐ์ ์์๊ฐ ๋ ๋์ ๋ ธ๋๋ฅผ ๊ณจ๋ผ ํ์ฌ ๋ฃจํธ ๋ ธ๋์ ๋ณ๊ฒฝํด์ค์๋ค.
์ด์ ์๋ ๋ฃจํธ๋ ธ๋์ ์๋ ๋ ธ๋๊ฐ ์ด๋ํ๋ฉด์ ์๋ธํธ๋ฆฌ์ ์๋ก์ด ๋ฃจํธ ๋ ธ๋๊ฐ ๋ฉ๋๋ค. ๋ฐ๋ผ์ ์๋ธํธ๋ฆฌ๊ฐ ์ต๋ ํ์ ๋ง์กฑํ๋์ง ํ์ธํด๋ด์ผ๊ฒ ์ฃ ? ์ด๋ฒ์๋ ์์ ๋ ธ๋๋ค ์ค์ ์ฐ์ ์์๊ฐ ๊ฐ์ฅ ๋์ ๋ ธ๋์ ์๋ธํธ๋ฆฌ์ ๋ฃจํธ๋ ธ๋๋ฅผ ๋น๊ตํด๋ด ๋๋ค.
๋ฃจํธ๋ ธ๋๋ 5์ด๊ณ , ์์๋ ธ๋๋ ํ๋ ๋ฟ์ธ 2์ด๊ธฐ ๋๋ฌธ์ ํ์ฌ ํธ๋ฆฌ์ ์ํ๊ฐ ์ ์ง๋ฉ๋๋ค.

์ด๋ ๊ฒ ํ๋ฉด ๋ชจ๋ ์๋ธ ํธ๋ฆฌ์ ์ต๋ ํ์ ์ ์งํ๋ฉด์ ๋ฃจํธ๋ ธ๋๋ฅผ ์ ๊ฑฐํ ์ ์๊ฒ๋ฉ๋๋ค.
์ญ์ ๊ตฌํ - diveDown
์์ ์ค๋ช ํ๋๋ก ์ญ์ ์ฐ์ฐ์ ๋ฃจํธ ๋ ธ๋์ ๋ฆฌํ ๋ ธ๋์ ๊ตํ, ๊ทธ๋ฆฌ๊ณ ํธ๋ฆฌ์ ์ฌ์กฐ์ ์ ์์๋ก ์งํ๋ฉ๋๋ค.
swimUp์ ๋ช ๋ช ํ์ ๊ต์๋๊ป์๋ ๋ฃจํธ๋ ธ๋์์๋ถํฐ ํ์ ๋ ธ๋๋ค์ ๊ฐฑ์ ํ๋ฉด์ ์ ์ง์ ์ผ๋ก ๋ด๋ ค๊ฐ๋ ํจ์๋ฅผ diveDown์ผ๋ก ๋ช ๋ช ํ์ จ๋๋ฐ์. ์ด๊ฒ๋ ์์์๋ถํฐ ๋ค์ด๋นํด์ ๋ด๋ ค์ค๋ ๊ฒ ๊ฐ๋ค๊ณ ...
mutating func diveDown(from index: Int) { var higherPriority = index let leftIndex = self.leftChild(of: index) let rightIndex = self.rightChild(of: index) // ์ผ์ชฝ ์์ ๋
ธ๋๊ฐ ๋ ์ฐ์ ์์๊ฐ ๋์ ๋ if leftIndex < self.elements.endIndex && self.sortFunction(self.elements[leftIndex], self.elements[higherPriority]) { higherPriority = leftIndex } // ์ค๋ฅธ์ชฝ ์์ ๋
ธ๋๊ฐ ๋ ์ฐ์ ์์๊ฐ ๋์ ๋ if rightIndex < self.elements.endIndex && self.sortFunction(self.elements[rightIndex], self.elements[higherPriority]) { higherPriority = rightIndex } // ๊ตํ์ด ํ์ํ ๊ฒฝ์ฐ๋ ๊ตํ ํ ์๋ธํธ๋ฆฌ๋ก ์ด๋ if higherPriority != index { self.elements.swapAt(higherPriority, index) self.diveDown(from: higherPriority) } }
diveDown์ ๊ตฌํ์ ์ด๋ ๊ฒ ๋ฉ๋๋ค.
๋ ์ด์ ๊ตํ์ด ํ์์์ ๋๊น์ง ์ผ์ชฝ ์์๋ ธ๋์ ์ค๋ฅธ์ชฝ ์์ ๋ ธ๋๋ฅผ ํ์ฌ ๋ฃจํธ ๋ ธ๋์ ๋น๊ตํ๋ฉด์ ์ฐ์ ์์๊ฐ ๋ ๋์ ๋ ธ๋์ ๊ตํ์ ์งํํด์ฃผ๊ณ , ๊ตํ์ด ๋๋ฉด ์๋ก์ด ๋ ธ๋๋ฅผ ๋ฃจํธ ๋ ธ๋๋ก ์ผ์์ diveDown์ ์ฌ๊ท์ ์ผ๋ก ์งํํฉ๋๋ค.
์ด๋ฒ์๋ ๋ฃจํธ์ ๋ฆฌํ๋ฅผ ๊ตํํ๋ ์๊ฐ๋ณต์ก๋ O(1), ์ต์ ์ ๊ฒฝ์ฐ ๋ฃจํธ๋ ธ๋๋ถํฐ ๋ฆฌํ๋ ธ๋๊น์ง ๊ตํ์ ์งํํ๋ ์๊ฐ๋ณต์ก๋ O(log N)๋ก ์ญ์ ์ฐ์ฐ์ O(log N)์ ์๊ฐ๋ณต์ก๋๊ฐ ์๊ตฌ๋ฉ๋๋ค.
๋ฐฐ์ด์ ํ์ผ๋ก - Build Heap
init(elements: [T] = [], sortFunction: @escaping (T, T) -> Bool) { if !elements.isEmpty { self.elements = [elements.first!] + elements } else { self.elements = elements } self.sortFunction = sortFunction if elements.count > 1 { self.buildHeap() } }
์๊น ์์ฑ์๋ฅผ ์ด๋ ๊ฒ ๊ตฌํํ์๋๋ฐ์, ๋ง์ฝ ์์ฑ์๋ก ๋ฐ์ ๋ฐฐ์ด์ ๊ฐ์ด ๋ค์ด ์๋ค๋ฉด ๋ฐฐ์ด ์ ์ฒด๋ฅผ ํ์ผ๋ก ๋ค์ ์ฌ๊ตฌ์ฑ ํด์ฃผ์ด์ผํ๊ธฐ ๋๋ฌธ์ ์ด๋ฅผ ์ํด์ buildHeap์ด๋ผ๋ ๋ฉ์๋๋ฅผ ํธ์ถํ๊ณ ์์ต๋๋ค.
mutating func buildHeap() { for index in (1...(self.elements.count / 2)).reversed() { self.diveDown(from: index) } }
buildHeap์ ์ด๋ ๊ฒ ๊ตฌํ๋์ด ์์ต๋๋ค. ๋ฐฐ์ด์ ๋ค์ด์๋ ์์์ ๊ฐ์๋ฅผ 2๋ก ๋๋๋ฉด ๋ง์ง๋ง ๋ฆฌํ๋ ธ๋์ ๋ถ๋ชจ ๋ ธ๋๊ฐ ๋์ค๊ธฐ ๋๋ฌธ์ ์ด ๋ ธ๋๊ฐ ๋ฆฌํ๋ ธ๋๋ฅผ ์ ์ธํ๊ณ ๋ ๊ฐ์ฅ ๋ง์ง๋ง ๋ ธ๋๊ฐ ๋ฉ๋๋ค.

์ด ๋ ธ๋๋ถํฐ ๋ฃจํธ๋ ธ๋๊น์ง ์ญ์์ผ๋ก ๊ฐ ์๋ธํธ๋ฆฌ์ ๋ฃจํธ๋ ธ๋๋ค์ ์ํํ๋ฉด์ diveDown์ ํธ์ถํ๋ฉด ๊ฐ์ฅ ๋ง์ง๋ง ์๋ธํธ๋ฆฌ๋ถํฐ ์์๋๋ก ํ์ ์ฌ๊ตฌ์ฑํ๊ฒ ๋ฉ๋๋ค.
์ ์ฒด ์ฝ๋
// | |
// Heap.swift | |
// Heap | |
// | |
// Created by ์ ์ฌํ on 2021/12/12. | |
// | |
import Foundation | |
struct Heap<T: Comparable> { | |
private var elements: [T] = [] | |
private let sortFunction: (T, T) -> Bool | |
var isEmpty: Bool { | |
return self.elements.count == 1 | |
} | |
var peek: T? { | |
if self.isEmpty { return nil } | |
return self.elements.last! | |
} | |
var count: Int { | |
return self.elements.count - 1 | |
} | |
init(elements: [T] = [], sortFunction: @escaping (T, T) -> Bool) { | |
if !elements.isEmpty { | |
self.elements = [elements.first!] + elements | |
} else { | |
self.elements = elements | |
} | |
self.sortFunction = sortFunction | |
if elements.count > 1 { | |
self.buildHeap() | |
} | |
} | |
func leftChild(of index: Int) -> Int { | |
return index * 2 | |
} | |
func rightChild(of index: Int) -> Int { | |
return index * 2 + 1 | |
} | |
func parent(of index: Int) -> Int { | |
return (index) / 2 | |
} | |
mutating func add(element: T) { | |
self.elements.append(element) | |
} | |
mutating func diveDown(from index: Int) { | |
var higherPriority = index | |
let leftIndex = self.leftChild(of: index) | |
let rightIndex = self.rightChild(of: index) | |
if leftIndex < self.elements.endIndex && self.sortFunction(self.elements[leftIndex], self.elements[higherPriority]) { | |
higherPriority = leftIndex | |
} | |
if rightIndex < self.elements.endIndex && self.sortFunction(self.elements[rightIndex], self.elements[higherPriority]) { | |
higherPriority = rightIndex | |
} | |
if higherPriority != index { | |
self.elements.swapAt(higherPriority, index) | |
self.diveDown(from: higherPriority) | |
} | |
} | |
mutating func swimUp(from index: Int) { | |
var index = index | |
while index != 1 && self.sortFunction(self.elements[index], self.elements[self.parent(of: index)]) { | |
self.elements.swapAt(index, self.parent(of: index)) | |
index = self.parent(of: index) | |
} | |
} | |
mutating func buildHeap() { | |
for index in (1...(self.elements.count / 2)).reversed() { | |
self.diveDown(from: index) | |
} | |
} | |
mutating func insert(node: T) { | |
if self.elements.isEmpty { | |
self.elements.append(node) | |
} | |
self.elements.append(node) | |
self.swimUp(from: self.elements.endIndex - 1) | |
} | |
mutating func remove() -> T? { | |
if self.isEmpty { return nil } | |
self.elements.swapAt(1, elements.endIndex - 1) | |
let deleted = elements.removeLast() | |
self.diveDown(from: 1) | |
return deleted | |
} | |
} |
GitHub - jeonyeohun/Data-Structures-In-Swift: ๐ท๐ปโโ๏ธ STL ์ ์์ด.. ์ค์ํํธ๋ก ๊ตฌํํ๋ ์๋ฃ๊ตฌ์กฐ
๐ท๐ปโโ๏ธ STL ์ ์์ด.. ์ค์ํํธ๋ก ๊ตฌํํ๋ ์๋ฃ๊ตฌ์กฐ. Contribute to jeonyeohun/Data-Structures-In-Swift development by creating an account on GitHub.
github.com
์๋ฃ๊ตฌ์กฐ ์๋ฆฌ์ฆ์ ์ฝ๋๋ค์ ์ด ๋ ํฌ์์ ๋ชจ๋ ํ์ธํ ์ ์์ด์!
'๐ฎ ์จ-์์ค > ๐ฆด ์๋ฃ๊ตฌ์กฐ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
๋๊ธ
์ด ๊ธ ๊ณต์ ํ๊ธฐ
-
๊ตฌ๋
ํ๊ธฐ
๊ตฌ๋ ํ๊ธฐ
-
์นด์นด์คํก
์นด์นด์คํก
-
๋ผ์ธ
๋ผ์ธ
-
ํธ์ํฐ
ํธ์ํฐ
-
Facebook
Facebook
-
์นด์นด์ค์คํ ๋ฆฌ
์นด์นด์ค์คํ ๋ฆฌ
-
๋ฐด๋
๋ฐด๋
-
๋ค์ด๋ฒ ๋ธ๋ก๊ทธ
๋ค์ด๋ฒ ๋ธ๋ก๊ทธ
-
Pocket
Pocket
-
Evernote
Evernote
๋๊ธ์ ์ฌ์ฉํ ์ ์์ต๋๋ค.