roovent

Heap

Jul 25th, 2018
138
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Swift 2.21 KB | None | 0 0
  1. struct Heap<E: Comparable> {
  2.     enum HeapType { case max, min }
  3.  
  4.     // an array representing the binary tree
  5.     var tree = [E]()
  6.  
  7.     // indicating if this heap is a max heap or min heap
  8.     let type: HeapType
  9.  
  10.     var count: Int {
  11.         return tree.count
  12.     }
  13.  
  14.     init(type: HeapType) {
  15.         self.type = type
  16.     }
  17.  
  18.     mutating func add(_ element: E) {
  19.         tree.append(element)
  20.         var child = tree.count - 1
  21.         var parent = (child - 1) / 2
  22.         while child > 0 && !satify(tree[parent], tree[child]) {
  23.             tree.swapAt(parent, child)
  24.             child = parent
  25.             parent = (child - 1) / 2
  26.         }
  27.         assert(isHeap(0), "borken heap: \(tree)")
  28.     }
  29.  
  30.     mutating func remove() -> E? {
  31.         let rev = tree.first
  32.         if tree.count > 0 {
  33.             tree.swapAt(0, tree.count - 1)
  34.             tree.removeLast()
  35.             heapify(0)
  36.         }
  37.         assert(isHeap(0), "borken heap: \(tree)")
  38.         return rev
  39.     }
  40.  
  41.     func peek() -> E? {
  42.         return tree.first
  43.     }
  44.  
  45.     mutating private func heapify(_ rootIndex: Int) {
  46.         let count = tree.count
  47.         let leftChild = 2 * rootIndex + 1
  48.         let rightChild = 2 * rootIndex + 2
  49.  
  50.         // no children
  51.         if leftChild >= count { return }
  52.  
  53.         let targetChild = (rightChild >= count || satify(tree[leftChild], tree[rightChild])) ? leftChild : rightChild
  54.         if (!satify(tree[rootIndex], tree[targetChild])) {
  55.             tree.swapAt(rootIndex, targetChild)
  56.             heapify(targetChild)
  57.         }
  58.     }
  59.  
  60.     private func satify(_ lhs: E, _ rhs: E) -> Bool {
  61.         return (self.type == .min) ? (lhs <= rhs) : (lhs >= rhs)
  62.     }
  63.  
  64.     // debugging helper methods
  65.     private func isHeap(_ rootIndex: Int) -> Bool {
  66.         let leftChild = 2 * rootIndex + 1
  67.         let rightChild = 2 * rootIndex + 2
  68.         var valid = true
  69.         if leftChild < tree.count {
  70.             valid = satify(tree[rootIndex], tree[leftChild]) && isHeap(leftChild)
  71.         }
  72.  
  73.         if !valid { return false }
  74.  
  75.         if rightChild < tree.count {
  76.             valid = satify(tree[rootIndex], tree[rightChild]) && isHeap(rightChild)
  77.         }
  78.         return valid
  79.     }
  80. }
Advertisement
Add Comment
Please, Sign In to add comment