Swift堆数据结构
时间:2020-02-23 14:44:01 来源:igfitidea点击:
在本教程中,我们将讨论并在Swift中实现Heap数据结构。
Swift堆
堆可以是最大堆,也可以是最小堆。
在最大堆中,根节点是最大的元素,所有子节点必须小于父节点。
最小堆的工作方式恰恰相反。
堆是一种特殊的基于树的数据结构。
堆数据结构可用于有效地找到数组中第k个最小(或者最大)的元素。
堆属性:如果P是C的父节点,则P的键(值)大于或者等于(在最大堆中)或者小于或者等于(在最小堆中)C的键。
顶部的节点是最高优先级的节点。
堆化
删除元素需要重新排列堆数据结构。
这称为堆化。
例如,如果删除堆的根节点。
为此,我们需要将其与根节点之间的最低节点交换,然后在整个过程中递归检查堆属性。
heapifyUp()从底部开始,并一直检查堆属性。
heapifyDown()恰好相反
N处的节点的子代将在最大堆中定位为" 2n + 1"和" 2n + 2"。
让我们启动XCode运动场,并使用Swift创建我们的堆。
我们将使用数组构建堆结构。
建立一个堆
struct Heap<T> {
var elements = [T]()
var isEmpty: Bool { return elements.isEmpty }
var count: Int { return elements.count }
var isOrdered: (T, T) -> Bool
public init(sort: @escaping (T, T) -> Bool) {
self.isOrdered = sort
}
}
传递了转义的闭包,用于保存函数值。
它比较传递的两个值。
在结构中添加以下函数以获取父节点,左节点和右节点的索引:
func parentOf(_ index: Int) -> Int {
return (index - 1)/2
}
func leftOf(_ index: Int) -> Int {
return (2 * index) + 1
}
func rightOf(_ index: Int) -> Int {
return (2 * index) + 2
}
heapifyDown():
mutating func heapifyDown(index: Int, heapSize: Int) {
var parentIndex = index
while true {
let leftIndex = self.leftOf(parentIndex)
let rightIndex = leftIndex + 1
var first = parentIndex
if leftIndex < heapSize && isOrdered(elements[leftIndex], elements[first]) {
first = leftIndex
}
if rightIndex < heapSize && isOrdered(elements[rightIndex], elements[first]) {
first = rightIndex
}
if first == parentIndex { return }
elements.swapAt(parentIndex, first)
parentIndex = first
}
}
mutating func shiftDown() {
heapifyDown(index: 0, heapSize: elements.count)
}
在删除元素时使用heapifyDown()。
插入时使用heapifyUp()。
以下函数用于从数组构建堆:
mutating func buildHeap(fromArray array: [T]) {
elements = array
for i in stride(from: (elements.count/2 - 1), through: 0, by: -1) {
heapifyDown(index: i, heapSize: elements.count)
}
}
heapifyUp():
mutating func heapifyUp(index: Int) {
var nodeIndex = index
while true {
let parentIndex = self.parentOf(nodeIndex)
var first = parentIndex
if parentIndex >= 0 && isOrdered(elements[nodeIndex], elements[first]) {
first = nodeIndex
}
if first == parentIndex { return }
elements.swapAt(parentIndex, first)
nodeIndex = first
}
}
以下函数用于从堆中插入和删除元素:
插入:
mutating func insert(value: T) {
self.elements.append(value)
heapifyUp(index: self.elements.count - 1)
}
删除:
public mutating func remove(at index: Int) -> T? {
let temp: T
if index < 0 && count - 1 <= index {
return nil
}
temp = elements[index]
elements[index] = elements[count - 1]
elements.removeLast()
shiftDown()
return temp
}
让我们使用示例输入来测试我们创建的上述结构:
let array: [Int] = [12,3,6,15,45,1,2] var heap = Heap<Int>(sort: >) heap.buildHeap(fromArray: array) heap.insert(value: 23) print(heap.elements) print(heap.remove(at: 0)) print(heap.elements)

