# andyRon/swift-algorithm-club-cn

Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
..
Failed to load latest commit information.
Deque.playground
Deque-Optimized.swift
Deque-Simple.swift

# 双端队列(Deque)

Swift中双端队列的一个非常基本的实现：

public struct Deque<T> {
private var array = [T]()

public var isEmpty: Bool {
return array.isEmpty
}

public var count: Int {
return array.count
}

public mutating func enqueue(_ element: T) {
array.append(element)
}

public mutating func enqueueFront(_ element: T) {
array.insert(element, atIndex: 0)
}

public mutating func dequeue() -> T? {
if isEmpty {
return nil
} else {
return array.removeFirst()
}
}

public mutating func dequeueBack() -> T? {
if isEmpty {
return nil
} else {
return array.removeLast()
}
}

public func peekFront() -> T? {
return array.first
}

public func peekBack() -> T? {
return array.last
}
}

var deque = Deque<Int>()
deque.enqueue(1)
deque.enqueue(2)
deque.enqueue(3)
deque.enqueue(4)

deque.dequeue()       // 1
deque.dequeueBack()   // 4

deque.enqueueFront(5)
deque.dequeue()       // 5

Deque的这种实现很简单但效率不高。几个操作是 O(n)，特别是enqueueFront()dequeue()。这个实现只是为了说明双端队列的作用原理。

## 更高效的版本

dequeue()enqueueFront()的时间复杂度是O(n)，原因是它们在数组的前面（开始）工作。如果删除数组前面的元素，那么所有剩余的元素都需要在内存中移位。

[ 1, 2, 3, 4 ]

[ 2, 3, 4 ]

[ 5, 2, 3, 4 ]

[ 1, 2, 3, 4, x, x, x ]

[ 1, 2, 3, 4, 6, x, x ]

dequeueBack()函数使用array.removeLast()删除元素。这不会缩小数组的内存，只会将array.count减1。这里没有涉及昂贵的内存拷贝。因此在数组末尾的操作很快，复杂度是O(1)

[ x, x, x, 1, 2, 3, 4, x, x, x ]

public struct Deque<T> {
private var array: [T?]
private var capacity: Int
private let originalCapacity:Int

public init(_ capacity: Int = 10) {
self.capacity = max(capacity, 1)
originalCapacity = self.capacity
array = [T?](repeating: nil, count: capacity)
}

public var isEmpty: Bool {
return count == 0
}

public var count: Int {
}

public mutating func enqueue(_ element: T) {
array.append(element)
}

public mutating func enqueueFront(_ element: T) {
// this is explained below
}

public mutating func dequeue() -> T? {
// this is explained below
}

public mutating func dequeueBack() -> T? {
if isEmpty {
return nil
} else {
return array.removeLast()
}
}

public func peekFront() -> T? {
if isEmpty {
return nil
} else {
}
}

public func peekBack() -> T? {
if isEmpty {
return nil
} else {
return array.last!
}
}
}

init方法分配一个包含一定数量的nil值的新数组。 在数组开头处添加了空白空间，默认情况下，会创建10个空白空间。

[ x, x, x, x, x, x, x, x, x, x ]
|

[ x, x, x, x, x, x, x, x, x, 5 ]
|

enqueueFront(7)的结果:

[ x, x, x, x, x, x, x, x, 7, 5 ]
|

public mutating func enqueueFront(element: T) {
}

[ x, x, x, x, x, x, x, x, 7, 5, 1, x, x, x, x, x, x, x, x, x ]
|

[ x, x, x, x, x, x, x, x, 7, 5, 1, 2, x, x, x, x, x, x, x, x ]
|

public mutating func dequeue() -> T? {
guard head < array.count, let element = array[head] else { return nil }

return element
}

public mutating func enqueueFront(element: T) {
capacity *= 2
let emptySpace = [T?](repeating: nil, count: capacity)
array.insert(contentsOf: emptySpace, at: 0)
}

}

[ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, 1, 2, 3 ]
|

public mutating func dequeue() -> T? {
guard head < array.count, let element = array[head] else { return nil }

if capacity >= originalCapacity && head >= capacity*2 {
let amountToRemove = capacity + capacity/2
array.removeFirst(amountToRemove)
capacity /= 2
}
return element
}

[ x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, x, 1, 2, 3 ]
|                             |

[ x, x, x, x, x, 1, 2, 3 ]
|
capacity