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] ----
收工.