|
| 1 | +// |
| 2 | +// Created by Jiandan on 2018/10/11. |
| 3 | +// Copyright (c) 2018 Jiandan. All rights reserved. |
| 4 | +// |
| 5 | + |
| 6 | +import Foundation |
| 7 | + |
| 8 | +/// 用数组实现的队列 |
| 9 | +struct ArrayQueue<T>: Queue { |
| 10 | + typealias Element = T |
| 11 | + |
| 12 | + /// 数组 |
| 13 | + private var items: [Element] |
| 14 | + /// 数组最大长度 |
| 15 | + private var capacity = 0 |
| 16 | + /// 队头下标 |
| 17 | + private var head = 0 |
| 18 | + /// 队尾下标 |
| 19 | + private var tail = 0 |
| 20 | + |
| 21 | + /// 构造方法 |
| 22 | + /// - parameter defaultElement: 默认元素 |
| 23 | + /// - parameter capacity: 数组长度 |
| 24 | + init(defaultElement: Element, capacity: Int) { |
| 25 | + self.capacity = capacity |
| 26 | + items = [Element](repeating: defaultElement, count: capacity) |
| 27 | + } |
| 28 | + |
| 29 | + // MARK: Protocol: Queue |
| 30 | + |
| 31 | + var isEmpty: Bool { return head == tail } |
| 32 | + |
| 33 | + var size: Int { return tail - head } |
| 34 | + |
| 35 | + var peek: Element? { return isEmpty ? nil : items[head] } |
| 36 | + |
| 37 | + // 没有数据搬移的实现,即实现了一个有界序列 |
| 38 | +// mutating func enqueue(newElement: Element) -> Bool { |
| 39 | +// // 整个队列都占满了 |
| 40 | +// if tail == capacity { |
| 41 | +// return false |
| 42 | +// } |
| 43 | +// |
| 44 | +// items[tail] = newElement |
| 45 | +// tail += 1 |
| 46 | +// return true |
| 47 | +// } |
| 48 | + // 有数据搬移的实现,即实现了一个无界序列 |
| 49 | + mutating func enqueue(newElement: Element) -> Bool { |
| 50 | + // 如果 tail == capacity 表示队列末尾没有空间了 |
| 51 | + if tail == capacity { |
| 52 | + // 整个队列都占满了 |
| 53 | + if head == 0 { return false } |
| 54 | + // 数据搬移 |
| 55 | + for i in head ..< tail { |
| 56 | + items[i - head] = items[i] |
| 57 | + } |
| 58 | + // 搬移完之后重新更新 head 和 tail |
| 59 | + tail -= head |
| 60 | + head = 0 |
| 61 | + } |
| 62 | + |
| 63 | + items[tail] = newElement |
| 64 | + tail += 1 |
| 65 | + return true |
| 66 | + } |
| 67 | + |
| 68 | + mutating func dequeue() -> Element? { |
| 69 | + if isEmpty { |
| 70 | + return nil |
| 71 | + } |
| 72 | + |
| 73 | + let item = items[head] |
| 74 | + head += 1 |
| 75 | + return item |
| 76 | + } |
| 77 | +} |
| 78 | + |
| 79 | +/// 使用2个数组实现无界队列,用到 Swift 中 Array 较多的方法 |
| 80 | +/// 来源:《iOS 面试之道》(故胤道长,唐巧) |
| 81 | +struct ArrayQueue2<T>: Queue { |
| 82 | + typealias Element = T |
| 83 | + |
| 84 | + /// 输入数组,主要负责入队 |
| 85 | + var inArray = [Element]() |
| 86 | + /// 输出数组,主要负责出队 |
| 87 | + var outArray = [Element]() |
| 88 | + |
| 89 | + var isEmpty: Bool { return inArray.isEmpty && outArray.isEmpty } |
| 90 | + |
| 91 | + var size: Int { return inArray.count + outArray.count } |
| 92 | + |
| 93 | + // 当 outArray 为空时,返回 inArray 首个元素,否则返回 outArray 末尾元素 |
| 94 | + var peek: Element? { return outArray.isEmpty ? inArray.first : outArray.last } |
| 95 | + |
| 96 | + mutating func enqueue(newElement: Element) -> Bool { |
| 97 | + // inArray 添加元素 |
| 98 | + inArray.append(newElement) |
| 99 | + return true |
| 100 | + } |
| 101 | + |
| 102 | + mutating func dequeue() -> Element? { |
| 103 | + if outArray.isEmpty { |
| 104 | + // 将 inArray 倒序存入 outArray 中 |
| 105 | + outArray = inArray.reversed() |
| 106 | + // 清空 inArray |
| 107 | + inArray.removeAll() |
| 108 | + } |
| 109 | + // 弹出 outArray 最后一个元素 |
| 110 | + return outArray.popLast() |
| 111 | + } |
| 112 | +} |
0 commit comments