翻译自raywenderlich网站iOS教程Swift Algorithm Club系列算法
准备开始编程
队列(Queue)是一个列表,您只能在后面插入新项目并从前面删除项目。 这可确保入队的第一个元素也是首先出队的元素。 先到先出
在许多算法中,咱们但愿在某个时间点将项目添加到临时列表中,而后在之后再次将它们从列表中拉出。 添加和删除这些项目的顺序很是重要。swift
队列提供先进先出或先入先出的顺序。 首先插入的元素也是第一个出来的元素(和堆栈(Stack)很是相似,是LIFO或后进先出。)segmentfault
这是一个栗子
理解队列的最简单方法是看看它是如何使用的。数据结构
想象一下你有一个队列。 如下是你如何入选一个数字:app
queue.enqueue(10)
队列如今是[10]。 而后,继续将下一个号码添加到队列中:工具
queue.enqueue(3)
队列如今是[10,3]。 继续添加:学习
queue.enqueue(57)
队列如今是[10,3,57]。 咱们能够将队列中的第一个元素从队列中拉出:测试
queue.dequeue()
将返回10,由于这是插入的第一个数字。 队列如今将是[3,57]。 每一个项目都向上移动一个地方。网站
queue.dequeue()
这将返回3.下一个出列将返回57,依此类推。 若是队列为空,则出队将返回零。
实现队列
在本节中,将实现一个存储Int值的简单通用队列。
建立一个新的playground,添加以下代码:
public struct Queue { }
playground还包含LinkedList的代码(能够经过转到查看 Project Navigators Show Project Navigator并打开Sources LinkedList来看到这一点。
入队(Enqueue)
队列须要入队方法。 咱们使用项目中包含的LinkedList
实现来实现队列。 在花括号之间添加如下内容:
// 1 fileprivate var list = LinkedList<Int>() // 2 public mutating func enqueue(_ element: Int) { list.append(element) }
fileprivate
LinkedList
变量,用于将这些项目存储在队列中。mutating
关键字。出列(Dequeue)
队列也须要一个出队方法。
// 1 public mutating func dequeque() -> Int? { // 2 guard !list.isEmpty, let element = list.first else { return nil} list.remove(element) return element.value }
guard
语句处理队列为空。 若是这个队列是空的,那么guard
将会进入else块。查看(Peek)
队列还须要一个peek方法,它在队列的开始处返回该项目而不删除它。
public func peek() -> Int? { return list.first?.value }
IsEmpty
队列能够是空的。 添加一个isEmpty
属性,该属性将返回基于LinkedList
的值:
public var isEmpty: Bool { return list.isEmpty }
打印队列
让咱们试试新队列。 在队列实现下面,将如下内容写入playground中:
var queue = Queue() queue.enqueue(10) queue.enqueue(3) queue.enqueue(57)
定义队列后,尝试将队列打印到控制台:
print(queue)
输出以下:
Queue(list: [10, 3, 57])
这输出的样式不是很好。 要显示更可读的输出字符串,可使队列采用CustomStringConvertable协议。 为此,请在Queue类的实现下方添加如下内容:
// 1 extension Queue: CustomStringConvertible { // 2 public var description: String { // 3 return list.description } }
Queue
类的扩展,让它遵循CustomStringConvertible
协议。 该协议指望使用字符串类型实现带名称描述的计算属性。description
属性。 这是一个计算属性,它是一个返回String的只读属性。LinkedList
的描述。如今控制台的输出编程以下样式:
[10, 3, 57]
Swift通用队列实现
此时,咱们已经实现了一个存储Int值的通用队列,并提供了在Queue类中查看,排队和出列项目的功能。
在本节中,咱们使用泛型从队列中抽象出类型需求。
将Queue类的实现更新为如下内容:
// 1 public struct Queue<T> { // 2 fileprivate var list = LinkedList<T>() // 3 public mutating func enqueue(_ element: T) { list.append(element) } // 4 public mutating func dequeque() -> T? { guard !list.isEmpty, let element = list.first else { return nil} list.remove(element) return element.value } // 5 public func peek() -> T? { return list.first?.value } public var isEmpty: Bool { return list.isEmpty } }
修正测试代码以下:
var queue = Queue<Int>() queue.enqueue(10) queue.enqueue(3) queue.enqueue(57) print(queue)
还能够尝试使用不一样类型的Queue:
var queue2 = Queue<String>() queue2.enqueue("mad") queue2.enqueue("lad") if let first = queue2.dequeque() { print(first) } print(queue2)
以上是本人在raywenderlich学习时为方便本身,用翻译工具翻译以后作的一个记录。
本系列其余文章:
Swift算法俱乐部:Swift栈(Stack)数据结构