Swift 队列、栈、最大堆结构简单实现

//
//  BaseData.swift
//  BaseData
//
//  Created by 周一见 on 2022/10/25.
//

import Foundation

protocol Stack {
    associatedtype ItemType
    
    func getSize() -> Int
    func isEmpty() -> Bool
    func push(element: ItemType)
    func pop() -> ItemType
    func top() -> ItemType
}

protocol Queue {
    associatedtype ItemType
    
    func getSize() -> Int
    func isEmpty() -> Bool
    func enqueue(element: ItemType)
    func dequeue( ) -> ItemType
    func getFront() -> ItemType
}

class ArrayStack: CustomStringConvertible, Stack {
    private var array: Array
    
    var description: String {
        var des = "["
        for i in 0 ..< array.count {
            des += "\(array[i])"
            if i != (array.count - 1) {
                des += ", "
            }
        }
        des += "] top"
        return des
    }
    
    init(capacity: Int) {
        array = Array.init()
        array.reserveCapacity(capacity)
    }
    
    convenience init() {
        self.init(capacity: 10)
    }
    
    //MARK: - Stack
    func getSize() -> Int {
        return array.count
    }
    
    func isEmpty() -> Bool {
        return array.isEmpty
    }
    
    func push(element: T) {
        array.append(element)
    }
    
    func pop() -> T {
        return array.removeLast()
    }
    
    func top() -> T {
        return array.last!
    }
}

class LoopQueue: CustomStringConvertible, Queue {
    private var array: Array
    private var front = 0
    private var tail = 0
    private var size = 0
    
    var description: String {
        var des = "front ["
        var i = front
        while i != tail {
            des += String(describing: array[i])
            if i != (tail - 1) {
                des += ", "
            }
            i = (i + 1) % array.count
        }
        des += "] tail"
        return des
    }
    
    init(capacity: Int) {
        array = Array.init(repeating: nil, count: capacity)
    }
    
    convenience init() {
        self.init(capacity: 10)
    }
    
    //MARK: - Stack
    func getSize() -> Int {
        return size
    }
    
    func getCapacity() -> Int {
        return array.count - 1
    }
    
    func isEmpty() -> Bool {
        return front == tail
    }
    
    func enqueue(element: T) {
        if size == getCapacity() {
            resize(capacity: getCapacity() * 2)
        }
        array[tail] = element
        tail = (tail + 1) % array.count
        size += 1
    }
    
    func dequeue() -> T {
        if isEmpty() {
            fatalError("Queue is Empty")
        } else {
            if size == (getCapacity() / 4) {
                resize(capacity: getCapacity() / 2)
            }
            let t = array[front]!
            array[front] = nil
            front = (front + 1) % array.count
            size -= 1
            return t
        }
    }
    
    func getFront() -> T {
        if isEmpty() {
            fatalError("Queue is Empty")
        } else {
            return array[front]!
        }
    }
    
    private func resize(capacity: Int) {
        var newArray = Array.init(repeating: nil, count: capacity + 1)
        for i in 0 ..< size {
            newArray[i] = array[(front + i) % array.count]
        }
        front = 0
        tail = size
        array = newArray
    }
}

class MaxHeap {
    private var array: Array
    
    //MARK: - Init funtion
    init(capacity: Int) {
        self.array = Array.init()
        self.array.reserveCapacity(capacity)
    }
    
    convenience init() {
        self.init(capacity: 10)
    }
    
    convenience init(array: Array) {
        self.init(capacity: array.count)
        for i in (0...parent(index: array.count - 1)).reversed() {
            var k = i
            siftDown(k: &k)
        }
    }
    
    //MARK: - Public API
    func getSize() -> Int {
        return array.count
    }
    
    func isEmpty() -> Bool {
        return array.isEmpty
    }

    func add(element: T) {
        array.append(element)
        var k = getSize() - 1
        siftUp(k: &k)
    }
    
    func findMax() -> T {
        if array.isEmpty {
            fatalError("heap is empty!")
        }
        return array[0]
    }
    
    func extractMax() -> T {
        let max = findMax()
        array[0] = array[getSize() - 1]
        array.removeLast()
        var k = 0
        siftDown(k: &k)
        return max
    }
    
    func replace(element: T) -> T {
        let max = findMax()
        array[0] = element
        var k = 0
        siftDown(k: &k)
        return max
    }
    
    //MARK: -  Private function
    private func parent(index: Int) -> Int {
        if index == 0 {
            fatalError("0 no parent!")
        }
        return (index - 1) / 2
    }
    
    private func leftChild(index: Int) -> Int {
        return index * 2 + 1
    }
    
    private func rightChild(index: Int) -> Int {
        return index * 2 + 2
    }
    
    private func siftUp(k: inout Int) {
        while k > 0 && array[k] > array[parent(index: k)] {
            array.swapAt(k, parent(index: k))
            k = parent(index: k)
        }
    }
    
    private func siftDown(k: inout Int) {
        var j = 0
        while leftChild(index: k) < getSize() {
            j = leftChild(index: k)
            if rightChild(index: k) < getSize() && array[j] < array[j + 1] {
                j = rightChild(index: k)
            }
            if array[k] < array[j] {
                array.swapAt(k, j)
            }
            k = j
        }
    }
}

你可能感兴趣的:(Swift 队列、栈、最大堆结构简单实现)