Skip to content

Instantly share code, notes, and snippets.

@joanromano
Created September 8, 2019 10:17
Show Gist options
  • Save joanromano/7fa37e0f45384157680293a3299b9643 to your computer and use it in GitHub Desktop.
Save joanromano/7fa37e0f45384157680293a3299b9643 to your computer and use it in GitHub Desktop.
An array based implementation of a PriorityQueue
struct PriorityQueue<T> {
private var array: [T] = []
private let priority: (T, T) -> Bool
var count: Int { return array.count }
var isEmpty: Bool { return array.isEmpty }
var top: T? { return array.first }
init(_ values: [T], priority: @escaping (T, T) -> Bool) {
self.priority = priority
for value in values { insert(value) }
}
mutating func insert(_ value: T) {
array.append(value)
swim(at: count - 1)
}
mutating func removeTop() -> T? {
guard !array.isEmpty else { return nil }
guard array.count != 1 else { return array.removeFirst() }
array.swapAt(0, array.count - 1)
let result = array.removeLast()
sink(at: 0)
return result
}
private mutating func sink(at index: Int) {
var current = index
while 2 * current + 1 < array.count {
var j = 2 * current + 1
if j < array.count - 1, priority(array[j+1], array[j]) { j += 1 }
if priority(array[current], array[j]) { break }
array.swapAt(current, j)
current = j
}
}
private mutating func swim(at index: Int) {
var current = index
while current > 0, priority(array[current], array[(current-1)/2]) {
array.swapAt(current, (current-1)/2)
current = (current-1)/2
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment