用 Swift 实现常用的数据结构 - 队列

667 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第3天,点击查看活动详情

什么是队列

队列,是一种常见的线性数据结构。它与栈经常相提并论,它只能在队尾添加元素,只能在对头移除元素。队列是先入队的元素先出队,即 First In First Out - FIFO。而栈则不同,栈是只能在栈顶添加和移除元素,栈是 LIFO。

队列这种结构在日常生活中随处可见,比如火车站排队购票,你只能在站在排队的最后一个人的后面排队,而不能插到别的位置(这样很容易引发冲突),即只能队尾入队。而且,第一个排队的人肯定是第一个购票的人,即队头先出对。

理解了队列是什么,下面来看一下如何用 Swift 来实现队列这种数据结构。

代码实现

对于队列的底层数据存储,我们采用 Array 来存储。

需要实现的函数

func first() -> Element? // 获取队头元素
func count() -> Int // 获取队列中元素的个数
func isEmpty() -> Bool // 判断队列是否为空
func inQueue(_ newElement: Element) // 将元素添加到队尾
func outQueue() -> Element? // 将队头元素出队

完整代码

class Queue<Element> {
    private var _content = [Element]()

    func first() -> Element? {
        return _content.first
    }
    
    func count() -> Int {
        return _content.count
    }
    
    func isEmpty() -> Bool {
        return _content.isEmpty
    }
    
    func inQueue(_ newElement: Element) {
        _content.append(newElement)
    }
    
    func outQueue() -> Element? {
       return _content.removeFirst()
    }
}

可以看到,队列的代码实现还是非常简单的,主要还是借助 Array 的相关函数来进行一个封装,从而来实现队列这种数据结构。

经典题目

用栈来实现队列

此为 LeetCode 的原题,链接在这里

这道题,我们需要用两个栈来解决。因为栈与队列的顺序性,若将所有元素先入栈 inStack,再依次弹出所有元素到 outStack,则 outStack 的元素顺序正好对应所有元素入队的顺序。

解题思路:

  • 当入队时,将元素入栈到 inStack。
  • 当出队时,若 outStack 不为空,直接将 outStack 栈顶元素出栈;否则,将 inStack 所有元素入栈到 outStack,再将 outStack 栈顶元素出栈。
  • 获取队头元素,若 outStack 不为空,直接返回 outStack 栈顶元素;否则,将 inStack 所有元素入栈到 outStack,再返回 outStack 栈顶元素。

代码:

class MyQueue {
    let inStack = MyStack()
    let outStack = MyStack()
    
    init() { }
    
    func push(_ x: Int) {
        inStack.push(x)
    }
    
    func pop() -> Int {
        if outStack.empty() {
            while !inStack.empty() {
                outStack.push(inStack.pop())
            }
        }
        return outStack.pop()
    }
    
    func peek() -> Int {
        if outStack.empty() {
            while !inStack.empty() {
                outStack.push(inStack.pop())
            }
        }
        return outStack.peek()
    }
    
    func empty() -> Bool {
        return inStack.empty() && outStack.empty()
    }
}