返回

Swift 实战:用栈实现先入先出队列

闲谈

作为程序员,我们经常需要处理各种数据结构,其中队列和栈都是非常重要的两种。队列是一种先进先出(FIFO)的数据结构,而栈是一种后进先出(LIFO)的数据结构。在某些情况下,我们可能需要使用栈来模拟队列的行为。本文将使用 Swift 语言,通过两个栈来实现先入先出队列。

算法实现

class MyQueue {
    private var stack1: [Int] = [] // 用作入队栈
    private var stack2: [Int] = [] // 用作出队栈

    // 入队操作
    func enqueue(_ element: Int) {
        stack1.append(element) // 将元素压入入队栈
    }

    // 出队操作
    func dequeue() -> Int? {
        // 如果出队栈为空,则将入队栈中的元素全部压入出队栈
        if stack2.isEmpty {
            while !stack1.isEmpty {
                stack2.append(stack1.removeLast()) // 将入队栈中的元素依次弹出并压入出队栈
            }
        }

        // 如果出队栈非空,则弹出并返回队首元素
        return stack2.popLast() // 从出队栈中弹出并返回队首元素
    }

    // 获取队首元素
    func peek() -> Int? {
        // 如果出队栈为空,则将入队栈中的元素全部压入出队栈
        if stack2.isEmpty {
            while !stack1.isEmpty {
                stack2.append(stack1.removeLast()) // 将入队栈中的元素依次弹出并压入出队栈
            }
        }

        // 如果出队栈非空,则返回队首元素
        return stack2.last // 返回出队栈中的最后一个元素(即队首元素)
    }

    // 判断队列是否为空
    func isEmpty() -> Bool {
        return stack1.isEmpty && stack2.isEmpty // 如果入队栈和出队栈都为空,则队列为空
    }
}

分析&注意点

  • 为了实现队列的 FIFO 行为,我们使用两个栈来模拟队列。栈是一种后进先出(LIFO)的数据结构,但通过巧妙地使用两个栈,我们可以实现先入先出(FIFO)的行为。
  • 每次入队操作时,我们将元素压入入队栈。
  • 每次出队操作时,我们首先检查出队栈是否为空。如果出队栈为空,则将入队栈中的所有元素依次弹出并压入出队栈。然后,我们从出队栈中弹出并返回队首元素。
  • 获取队首元素时,我们也首先检查出队栈是否为空。如果出队栈为空,则将入队栈中的所有元素依次弹出并压入出队栈。然后,我们返回出队栈中的最后一个元素(即队首元素)。
  • 判断队列是否为空时,我们只需检查入队栈和出队栈是否都为空即可。

扩展阅读