swift实现队列

53 阅读4分钟

队列Queue

特点: 先进先出(FIFO:First In First Out),只能在队尾添加元素,队头移除元素。

可以运用双向链表来实现

class Queue<E> {
    let list = LinkedList<E>()
    
    // MARK: 元素数量
    func size() -> Int {
        return list.size
    }
    
    // MARK: 是否为空
    func isEmpty() -> Bool {
        return list.isEmpty()
    }
    
    // MARK: 清空
    func clear() {
        list.clear()
    }
    
    // MARK: 入队
    func enQueue(_ element: E) {
        list.add(element)
    }
    
    // MARK: 出队
    func deQueue() -> E? {
        return list.remove(0)
    }
    
    // MARK: 获取队列的头元素
    func front() -> E? {
        return list.get(0)
    }
}

测试代码:

let queue = Queue<Any>()
queue.enQueue(11)
queue.enQueue(22)
queue.enQueue(33)
queue.enQueue(44)
queue.enQueue(true)
queue.enQueue(0.1)
while !queue.isEmpty() {
    print(queue.deQueue() as Any)
}

双端队列Deque

特点:可以在头尾两端添加、删除元素

class Deque<E> {
    let list = LinkedList<E>()
    
    // MARK: 元素数量
    func size() -> Int {
        return list.size
    }
    
    // MARK: 是否为空
    func isEmpty() -> Bool {
        return list.isEmpty()
    }
    
    // MARK: 清空
    func clear() {
        list.clear()
    }
    
    // MARK: 从队尾入队
    func enQueueRear(_ element: E) {
        list.add(element)
    }
    
    // MARK: 从队头出队
    func deQueueFront() -> E? {
        return list.remove(0)
    }
    
    // MARK: 从队头入队
    func enQueueFront(_ element: E) {
        list.add(0, element)
    }
    
    // MARK: 从队尾出队
    func deQueueRear() -> E? {
        return list.remove(size() - 1)
    }
    
    // MARK: 获取队列的头元素
    func front() -> E? {
        return list.get(0)
    }
    
    // MARK: 获取队列的尾元素
    func rear() -> E? {
        return list.get(size() - 1)
    }
}

测试代码:

let deque = Deque<Any>()
deque.enQueueFront(11)
deque.enQueueFront(22)
deque.enQueueRear(33)
deque.enQueueRear(44)

// 头 22 11 33 44尾
while !deque.isEmpty() {
//    print(deque.deQueueFront())
    print(deque.deQueueRear())
}

循环队列

class CircleQueue<E> {
    struct CommonInteger {
        let Capacity: Int = 10
    }
    var elements: [E?] = []
    var frontIndex: Int = 0
    var size: Int = 0
    
    init() {
        elements = Array(repeating: nil, count: 10)
    }
    
    // MARK: 是否为空
    func isEmpty() -> Bool {
        return size == 0
    }
    
    // MARK: 清空
    func clear() {
        for index in 0..<elements.count {
            elements[getIndex(index)] = nil
        }
        frontIndex = 0
        size = 0
    }
    
    // MARK: 入队
    func enQueue(_ element: E) {
        ensureCapacity(size + 1)
        elements[getIndex(size)] = element
        size += 1
    }
    
    // MARK: 出队
    @discardableResult
    func deQueue() -> E? {
       let frontElement = elements[frontIndex]
       elements[frontIndex] = nil
       frontIndex = getIndex(1)
       size -= 1
       return frontElement
    }
    
    // MARK: 获取队列的头元素
    @discardableResult
    func front() -> E? {
       return elements[frontIndex]
    }
    
    // MARK: 获取队列中真实的index
    private func getIndex(_ index: Int) -> Int {
        // 尽量避免使用乘、除、模、浮点运算,效率低下
        // return (frontIndex + index) % elements.count
        // n % m 等价于 n - (n >= m ? m : 0) 且 n < 2m
        let i = index + frontIndex
        return i - (i >= elements.count ? elements.count : 0)
    }
    
    // MARK: 保证要有capacity的容量
    private func ensureCapacity(_ capacity: Int) {
        let oldCapacity = elements.count
        if oldCapacity >= capacity { return }
        let newCapacity = oldCapacity + (oldCapacity >> 1)
        var newElements = Array<E?>(repeating: nil, count: newCapacity)
        for index in 0..<size {
            newElements[index] = elements[getIndex(index)]
        }
        elements = newElements
        frontIndex = 0
    }
}

测试代码:

let circleQueue = CircleQueue<Any>()
// 0 1 2 3 4 5 6 7 8 9
for i in 0..<10 {
    circleQueue.enQueue(i)
}
// nil nil nil nil nil 5 6 7 8 9
for _ in 0..<5 {
    circleQueue.deQueue()
}
// 15 16 17 18 19 5 6 7 8 9
for i in 15..<20 {
    circleQueue.enQueue(i)
}
print(circleQueue.front()) // 5
while !circleQueue.isEmpty() {
    print(circleQueue.deQueue())
}

循环双端队列

class CircleDeque<E> {
    var elements: [E?] = []
    var frontIndex: Int = 0
    var size: Int = 0
    
    init() {
        elements = Array(repeating: nil, count: 10)
    }
    
    // MARK: 是否为空
    func isEmpty() -> Bool {
        return size == 0
    }
    
    // MARK: 清空
    func clear() {
        for index in 0..<elements.count {
            elements[getIndex(index)] = nil
        }
        frontIndex = 0
        size = 0
    }
    
    // MARK: 从队尾入队
    func enQueueRear(_ element: E) {
        ensureCapacity(size + 1)
        elements[getIndex(size)] = element
        size += 1
    }
    
    // MARK: 从队头出队
    @discardableResult
    func deQueueFront() -> E? {
        let frontElement = elements[frontIndex]
        elements[frontIndex] = nil
        frontIndex = getIndex(1)
        size -= 1
        return frontElement
    }
    
    // MARK: 从队头入队
    func enQueueFront(_ element: E) {
        ensureCapacity(size + 1)
        frontIndex = getIndex(-1)
        elements[frontIndex] = element
        size += 1
    }
    
    // MARK: 从队尾出队
    @discardableResult
    func deQueueRear() -> E? {
        let rearIndex = getIndex(size - 1)
        let rear = elements[rearIndex]
        elements[rearIndex] = nil
        size -= 1
        return rear
    }
    
    // MARK: 获取队列的头元素
    @discardableResult
    func front() -> E? {
       return elements[frontIndex]
    }
    
    // MARK: 获取队列的尾元素
    func rear() -> E? {
        return elements[getIndex(size - 1)]
    }
    
    // MARK: 获取队列中真实的index
    private func getIndex(_ index: Int) -> Int {
        // 尽量避免使用乘、除、模、浮点运算,效率低下
        // return (frontIndex + index) % elements.count
        // n % m 等价于 n - (n >= m ? m : 0) 且 n < 2m
        let i = index + frontIndex
        if i < 0 {
            return i + elements.count
        }
        return i - (i >= elements.count ? elements.count : 0)
    }
    
    // MARK: 保证要有capacity的容量
    private func ensureCapacity(_ capacity: Int) {
        let oldCapacity = elements.count
        if oldCapacity >= capacity { return }
        let newCapacity = oldCapacity + (oldCapacity >> 1)
        var newElements = Array<E?>(repeating: nil, count: newCapacity)
        for index in 0..<size {
            newElements[index] = elements[getIndex(index)]
        }
        elements = newElements
        frontIndex = 0
    }
}

测试代码:

let circleDeque = CircleDeque<Any>()
// 头5 4 3 2 1 100 101 102 103 104尾
// 头5 4 3 2 1 100 101 102 103 104 nil nil nil nil nil尾
// 头5 4 3 2 1 100 101 102 103 104 105 106 8 7 6尾
// 头8 7 6 5 4 3 2 1 100 101 102 103 104 105 106 nil nil nil nil nil nil nil尾
// 头8 7 6 5 4 3 2 1 100 101 102 103 104 105 106 107 108 109 nil nil 10 9尾
for i in 0..<10 {
    circleDeque.enQueueFront(i + 1)
    circleDeque.enQueueRear(i + 100)
}

circleDeque.frontIndex // 20

// 头nil 7 6 5 4 3 2 1 100 101 102 103 104 105 106 nil nil nil nil nil nil nil尾
for i in 0..<3 {
    circleDeque.deQueueFront()
    circleDeque.deQueueRear()
}

// 头11 7 6 5 4 3 2 1 100 101 102 103 104 105 106 nil nil nil nil nil nil 12尾
circleDeque.enQueueFront(11)
circleDeque.enQueueFront(12)

circleDeque.frontIndex // 21

while !circleDeque.isEmpty() {
    print(circleDeque.deQueueFront())
}