public protocol Queue {
associatedType Element
mutating func enqueue(_ element: Element) -> Bool
mutating func dequeue() -> Element?
var isEmpty: Bool { get }
var peek: Element? { get }
}
struct Heap<Element: Equtable> {
var elements: [Element] = []
let sort: (Element, Element) -> Bool
init(sort: @escaping (Element, Element) -> Bool, elements: [Element] = [] ) {
self.sort = sort
self.elements = elements
if !elements.isEmpty {
for i in stride(from: count / 2 - 1, through: 0, by: - 1) {
siftDown(from: i)
}
}
}
var isEmpty: Bool {
elements.isEmpty
}
var count: Int {
elements.count
}
func peek() -> Element? {
element.first
}
func leftChildIndex(ofParentAt index: Int) -> Int {
(index * 2) + 1
}
func rightChildIndex(ofParentAt index: Int) -> Int {
(index * 2) + 2
}
func parentIndex(ofChildAt index: Int) -> Int {
(index - 1) / 2
}
private mutating func siftDown(from index: Int) {
var parent = index
while true {
let left = leftChildIndex(ofParentAt: parent)
let right = rightChildIndex(ofParentAt: parent)
var candidate = parent
if left < count && sort(elements[left], elements[candidate]) {
candidate = left
}
if right < count && sort(elements[right], elements[candidate]) {
candidate = right
}
if candidate == parent {
return
}
elements.swapAt(parent, candidate)
parent = candidate
}
}
private mutating func siftUp(from index: Int) {
var child = index
var parent = parentIndex(ofChild: child)
while child > 0 && sort(elements[child], elements[parent]) {
elements.swapAt(child, parent)
child = parent
parent = parentIndex(ofChildAt: child)
}
}
mutating func remove() -> Element? {
guard !isEmpty else {
return nil
}
elements.swapAt(0, count - 1)
defer {
siftDown(from: 0)
}
return elements.removeLast()
}
mutating func insert(_ element: Element) {
elements.append(element)
siftUp(from: elements.count - 1)
}
}
struct PriortyQueue<Element: Equtable>: Queue {
private var heap: Heap<Element>
init(sort: @escaping (Element, Element) -> Bool, elements: [Element] = []) {
heap = Heap(sort: sort, elements: elements)
}
var isEmpty: Bool {
heap.isEmpty
}
var peek: Element? {
heap.peek()
}
mutating func enqueue(_ element: Element) -> Bool {
heap.insert(element)
return ture
}
mutating func dequeue() -> Element? {
heap.remove()
}
}
public struct PriorityQueueArray<T: Equatable>: Queue {
private var elements:[T] = []
let sort: (Element, Element) -> Bool
public init(sort: @escaping (Element,Element) -> Bool, elements: [Element] = []) {
self.sort = sort
self.elements = elements
self.elements.sort(by: sort)
}
public var isEmpty: Bool {
elements.isEmpty
}
public var peek: T? {
elements.first
}
public mutating func enqueue(_ element: T) -> Bool {
for (index, otherElement) in elements.enumerated() {
if sort(element, otherElement) {
elements.insert(element, at: index)
return true
}
}
elements.append(element)
return true
}
public mutating func dequeue() -> T? {
isEmpty ? nil : elements.removeFirst()
}
}
extension PriorityQueueArray: CustomStringConvertible {
public var description: String {
String(describing: elements)
}
}
var priorityQueue = PriorityQueue(sort: >, elements: [1,12,3,4,1,6,8,7])
while !priorityQueue.isEmpty {
print(priorityQueue.dequeue()!)
}
12
8
7
6
4
3
1 1
제가 학습한 내용을 요약하여 정리한 것입니다. 내용에 오류가 있을 수 있으며, 어떠한 피드백도 감사히 받겠습니다.
감사합니다.