hello-algo/codes/swift/chapter_heap/my_heap.swift
2023-02-07 19:05:19 +08:00

163 lines
3.9 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* File: my_heap.swift
* Created Time: 2023-01-28
* Author: nuomi1 (nuomi1@qq.com)
*/
import utils
/* */
class MaxHeap {
private var maxHeap: [Int]
/* */
init(nums: [Int]) {
//
maxHeap = nums
//
for i in stride(from: parent(i: size() - 1), through: 0, by: -1) {
siftDown(i: i)
}
}
/* */
private func left(i: Int) -> Int {
2 * i + 1
}
/* */
private func right(i: Int) -> Int {
2 * i + 2
}
/* */
private func parent(i: Int) -> Int {
(i - 1) / 2 //
}
/* */
private func swap(i: Int, j: Int) {
maxHeap.swapAt(i, j)
}
/* */
func size() -> Int {
maxHeap.count
}
/* */
func isEmpty() -> Bool {
size() == 0
}
/* 访 */
func peek() -> Int {
maxHeap[0]
}
/* */
func push(val: Int) {
//
maxHeap.append(val)
//
siftUp(i: size() - 1)
}
/* i */
private func siftUp(i: Int) {
var i = i
while true {
// i
let p = parent(i: i)
//
if p < 0 || maxHeap[i] <= maxHeap[p] {
break
}
//
swap(i: i, j: p)
//
i = p
}
}
/* */
func poll() -> Int {
//
if isEmpty() {
fatalError("堆为空")
}
//
swap(i: 0, j: size() - 1)
//
let val = maxHeap.remove(at: size() - 1)
//
siftDown(i: 0)
//
return val
}
/* i */
private func siftDown(i: Int) {
var i = i
while true {
// i, l, r ma
let l = left(i: i)
let r = right(i: i)
var ma = i
if l < size(), maxHeap[l] > maxHeap[ma] {
ma = l
}
if r < size(), maxHeap[r] > maxHeap[ma] {
ma = r
}
// i l, r
if ma == i {
break
}
//
swap(i: i, j: ma)
//
i = ma
}
}
/* */
func print() {
let queue = maxHeap
PrintUtil.printHeap(queue: queue)
}
}
@main
enum MyHeap {
/* Driver Code */
static func main() {
/* */
let maxHeap = MaxHeap(nums: [9, 8, 6, 6, 7, 5, 2, 1, 4, 3, 6, 2])
print("\n输入列表并建堆后")
maxHeap.print()
/* */
var peek = maxHeap.peek()
print("\n堆顶元素为 \(peek)")
/* */
let val = 7
maxHeap.push(val: val)
print("\n元素 \(val) 入堆后")
maxHeap.print()
/* */
peek = maxHeap.poll()
print("\n堆顶元素 \(peek) 出堆后")
maxHeap.print()
/* */
let size = maxHeap.size()
print("\n堆元素数量为 \(size)")
/* */
let isEmpty = maxHeap.isEmpty()
print("\n堆是否为空 \(isEmpty)")
}
}