Swift -- 使用数组实现队列 / 两个队列实现栈

1,336 阅读2分钟

1. 数组实现队列:

队列的概念: 只允许在一端进行插入操作,而在另一端进行删除操作的线性表。 队列是一种先进先出(First In First Out)的线性表,简称FIFO。 允许插入的一端称为队尾,允许删除的一端称为队头。

数组实现队列满足入列(enqueue), 出列(dequeue)方法和几个查询方法即可.

    public struct ArrayQueue<T> {
    
    fileprivate var array = [T]()
    
    public var isEmpty: Bool {
        return array.isEmpty
    }
    
    public var count: Int {
        return array.count
    }
    
    public mutating func enqueue(_ element: T?) {
        guard let ele = element else {
            return
        }
        array.append(ele)
    }
    
    public mutating func dequeue() -> T? {
        return array.removeFirst()
    }
    
    public mutating func front() -> T? {
        return array.first
    }
    
} 

考虑到性能因素的情况, 需要实现预留数组尾部空间的功能, 不过Swift已经替我们做好了这些工作了(手动狗头)

2. 两个队列实现栈:

思路: 当前有两个队列, leftQueue, rightQueue. 由于是要实现一个栈, 我们的目标是先进后出,首先在元素进栈的时候应该把所有元素enqueue到leftQueue中, 在栈pop的时候我们需要依次把有元素的队列中的元素dequeue到另一边的队列中, 直到当前队列的元素只剩下最后一个元素为止.

当只剩下最后一个的时候我们把这个元素从队列中dequeue就好了.

即: 每次做完pop之后, 总有一个队列是空的, 没有任何元素的.

上代码:

public struct MyStack<T> {
    private var leftQueue = ArrayQueue(array: [T]())
    private var rightQueue = ArrayQueue(array: [T]())
    
    var stackList: [T] {
        return leftQueue.array + rightQueue.array
    }
    
    mutating func push(element: T) {
        leftQueue.enqueue(element)
        print("pushing element: \(element) into stacklist, stacklist: \(stackList)")
    }
    
    mutating func pop() -> T? {
        if stackSize() != 0 {
            if (!leftQueue.isEmpty) {
                transportElementTo()
                guard let pop = leftQueue.dequeue() else {
                    return nil
                }
                print("poping last element: ---- \(pop) ----")
                return pop
            } else {
                transportElementTo()
                guard let pop = rightQueue.dequeue() else {
                    return nil
                }
                print("poping last element: ---- \(pop) ----")
                return pop
            }
        } else {
            print("Stack is empty, can't pop it anymore.")
            return -1 as? T
        }
    }
    
    func stackSize() -> Int {
        return leftQueue.count + rightQueue.count
    }
    
    private mutating func transportElementTo() {
        if !leftQueue.isEmpty {
            // 如果左边队列不是空队列
            while (leftQueue.count > 1) {
                /*
                 在左边队列元素数量大于1的情况下,
                 右边队列添加左边队列的最后一位, 直到左边队列只剩最后一位
                 */
                rightQueue.enqueue(leftQueue.dequeue())
            }
        } else if !rightQueue.isEmpty {
            // 如果右边队列不是空队列
            while rightQueue.count > 1 {
                /*
                 在右边队列元素数量大于1的情况下,
                 左边数列添加右边数列的最后一位, 直到右边数列只剩最后一位
                */
                leftQueue.enqueue(rightQueue.dequeue())
            }
        }
    }
}

测试一下:

var stack = MyStack<Int>()

for n in 0..<5 {
    stack.push(element: n)
}

for _ in 0..<3 {
    stack.pop()
}

print("result after pop: ---- \(stack.stackList) ----")

控制台结果:

pushing element: 0 into stacklist, stacklist: [0]
pushing element: 1 into stacklist, stacklist: [0, 1]
pushing element: 2 into stacklist, stacklist: [0, 1, 2]
pushing element: 3 into stacklist, stacklist: [0, 1, 2, 3]
pushing element: 4 into stacklist, stacklist: [0, 1, 2, 3, 4]
poping last element: ---- 4 ----
poping last element: ---- 3 ----
poping last element: ---- 2 ----
result after pop: ---- [0, 1] ----

收工.