翻譯自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)數據結構