Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- struct Heap<E: Comparable> {
- enum HeapType { case max, min }
- // an array representing the binary tree
- var tree = [E]()
- // indicating if this heap is a max heap or min heap
- let type: HeapType
- var count: Int {
- return tree.count
- }
- init(type: HeapType) {
- self.type = type
- }
- mutating func add(_ element: E) {
- tree.append(element)
- var child = tree.count - 1
- var parent = (child - 1) / 2
- while child > 0 && !satify(tree[parent], tree[child]) {
- tree.swapAt(parent, child)
- child = parent
- parent = (child - 1) / 2
- }
- assert(isHeap(0), "borken heap: \(tree)")
- }
- mutating func remove() -> E? {
- let rev = tree.first
- if tree.count > 0 {
- tree.swapAt(0, tree.count - 1)
- tree.removeLast()
- heapify(0)
- }
- assert(isHeap(0), "borken heap: \(tree)")
- return rev
- }
- func peek() -> E? {
- return tree.first
- }
- mutating private func heapify(_ rootIndex: Int) {
- let count = tree.count
- let leftChild = 2 * rootIndex + 1
- let rightChild = 2 * rootIndex + 2
- // no children
- if leftChild >= count { return }
- let targetChild = (rightChild >= count || satify(tree[leftChild], tree[rightChild])) ? leftChild : rightChild
- if (!satify(tree[rootIndex], tree[targetChild])) {
- tree.swapAt(rootIndex, targetChild)
- heapify(targetChild)
- }
- }
- private func satify(_ lhs: E, _ rhs: E) -> Bool {
- return (self.type == .min) ? (lhs <= rhs) : (lhs >= rhs)
- }
- // debugging helper methods
- private func isHeap(_ rootIndex: Int) -> Bool {
- let leftChild = 2 * rootIndex + 1
- let rightChild = 2 * rootIndex + 2
- var valid = true
- if leftChild < tree.count {
- valid = satify(tree[rootIndex], tree[leftChild]) && isHeap(leftChild)
- }
- if !valid { return false }
- if rightChild < tree.count {
- valid = satify(tree[rootIndex], tree[rightChild]) && isHeap(rightChild)
- }
- return valid
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment