Swift 算法俱樂部:隊列

數(shù)據(jù)結(jié)構(gòu):隊列

原文鏈接: Swift Algorithm Club: Swift Queue Data Structure
翻譯: coderJoey

通過本教程伟件,你將學(xué)習(xí)怎樣用Swift3實現(xiàn)隊列數(shù)據(jù)結(jié)構(gòu)富拗。隊列是一種非常流行的數(shù)據(jù)結(jié)構(gòu)慌申,而且用Swift實現(xiàn)也相當(dāng)簡單饲化。

開始吧

隊列 很像排隊吃引,先到的排在前面后來的排在隊伍的后面灸芳。這能保證第一個入列的元素將第一個出列痹仙。

這種數(shù)據(jù)結(jié)構(gòu)有什么用呢期升?在很多算法中惊奇,例如某個時刻你想添加一些新的對象到一個臨時列表中,然后不就之后你需要刪除掉這些對象播赁,添加和刪除這些對象的順序有時候是很重要的颂郎。

隊列的順序是FIFO( first-in first-out order:先進先出),也就是最先入列的元素最先被移除容为。(這非常像數(shù)據(jù)結(jié)構(gòu)堆棧LIFO:后進先出))

例子

理解隊列最好的方式就是看它是如何工作的乓序。

假設(shè)你現(xiàn)在有一個隊列寺酪,下面是如何添加一個數(shù)字:

queue.enqueue(10)

隊列現(xiàn)在變成了[10],然后你再添加一個數(shù)字:

queue.enqueue(3)

隊列變成了[10,3]替劈,然后你又添加一個數(shù)字:

queue.enqueue(57)

隊列變成了[10,3,57]寄雀,你現(xiàn)在將隊列的最前面的元素刪掉:

queue.dequeue()

這個方法將返回第一次插入的數(shù)字10,隊列變成了[3,57]抬纸。每個元素都將向前移一位咙俩。

queue.dequeue()

這個方法將返回3,下一次dequeue將返回57湿故。如果這個隊列是空的阿趁,操作出列方法將返回nil。

實現(xiàn)隊列

在本節(jié)中坛猪,你將實現(xiàn)一個存儲Int類型的簡單通用隊列脖阵。
首先先下載queue starter project。playground項目中包含了一個空的Queue

public struct Queue {

}

playground中也包含了一個鏈表類 LinkedList墅茉,你可以在View\Project Navigators\Show Project Navigator中打開Sources\LinkedList(或者用組合鍵command+1)

想知道鏈表是如何工作的命黔?點擊這里查看譯文教程,或者點擊Swift linked list 查看原文就斤。

入列

隊列需要一個enqueue函數(shù)進行入列操作悍募。你將使用啟動項目中包含的鏈表來實現(xiàn)隊列。 在花括號之間添加以下內(nèi)容:

// 1
fileprivate var list = LinkedList()

// 2
public mutating func enqueue(_ element: Int) {
  list.append(element)
}

上面代碼做了什么:

  1. 添加了私有的變量LinkedList洋机,用來存儲隊列的元素坠宴。

  2. 添加了一個入列函數(shù)。該函數(shù)會使LinkedList內(nèi)容發(fā)生改變绷旗,所以你需要在方法前添加mutating關(guān)鍵字喜鼓。

出列

隊列也需要一個dequeue函數(shù)進行出列操作。

// 1
public mutating func dequeue() -> Int? {
  // 2
  guard !list.isEmpty, let element = list.first else { return nil }

  list.remove(element)

  return element.value
}

上面代碼做了什么:

  1. 添加一個返回值為隊列第一個元素的dequeue方法衔肢,返回值類型nullable是為了處理隊列為空的情況庄岖。該函數(shù)會使LinkedList內(nèi)容發(fā)生改變,所以你需要在方法前添加mutating關(guān)鍵字角骤。

  2. guard語句來處理隊列為空的情況隅忿。如果隊列為空。guard將執(zhí)行else語句塊代碼邦尊。

查看

隊列也需要一個peek函數(shù)來查看隊列的第一個元素硼控。與dequeue不同的是你不能將這個元素從隊列中移除掉。

public func peek() -> Int? {
  return list.first?.value
}

是否為空

隊列是可以為空的胳赌。你需要在 LinkedList下邊添加一個判斷隊列是否為空的isEmpty屬性。

public var isEmpty: Bool {
  return list.isEmpty
}

打印隊列

現(xiàn)在我們使用下這個隊列匙隔。在Queue實現(xiàn)下面疑苫,我們添加如下代碼:

var queue = Queue()
queue.enqueue(10)
queue.enqueue(3)
queue.enqueue(57)

定義隊列后,我們試著將鏈表的內(nèi)容打印到控制臺:

print(queue)

你可以使用組合鍵 Command-Shift-Y喚起控制臺。然而你看到的打印結(jié)果是:

Queue

這顯然沒什么用。要使打印的字符串更具可讀性捍掺,你需要讓LinkedList遵守CustomStringConvertable 協(xié)議撼短。我們將下面的代碼添加到Queue 類的下面。

// 1
extension Queue: CustomStringConvertible {
  // 2
  public var description: String {
    // 3
    return list.description
  }
}

上面代碼做了什么:

  1. 你聲明了一個 Queue 類的擴展挺勿,而且遵守了CustomStringConvertable 協(xié)議曲横。這個協(xié)議希望你實現(xiàn)String類型的description,這里的description為計算型屬性(computed property)不瓶。

  2. 定義description屬性禾嫉,它的返回類型是String,而且是只讀的蚊丐。

  3. LinkedList的描述屬性作為返回值熙参。

現(xiàn)在打印Queue的內(nèi)容,你將看到不錯的結(jié)果:

"[10, 3, 57]"

泛型實現(xiàn)

到目前為止麦备,你已經(jīng)實現(xiàn)了一個存儲Int值的通用隊列孽椰, 并提供了在隊列類中查看,入列和出列的功能函數(shù)凛篙。
在本節(jié)中黍匾,我們將使用泛型來實現(xiàn)抽象類型的隊列。

如下更新Queue類:

// 1
public struct Queue<T> {

  // 2
  fileprivate var list = LinkedList<T>()

  public var isEmpty: Bool {
    return list.isEmpty
  }
  
  // 3
  public mutating func enqueue(_ element: T) {
    list.append(element)
  }

  // 4
  public mutating func dequeue() -> 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
  }
}

代碼解析:

  1. Queue類的聲明更改為泛型T呛梆。
  2. 你的目的是要讓Queue類存儲任何類型锐涯,所以要將LinkedList的類型定義為泛型T
  3. enqueue類定義的類型更改為泛型T削彬。
  4. dequeue類定義的類型更改為泛型T全庸。
  5. peek類定義的類型更改為泛型T。

修改測試代碼:

var queue = Queue<Int>()
queue.enqueue(10)
queue.enqueue(3)
queue.enqueue(57)

當(dāng)然你還可以測試其他不同的類型:

var queue2 = Queue<String>()
queue2.enqueue("mad")
queue2.enqueue("lad")
if let first = queue2.dequeue() {
  print(first)
}
print(queue2)

何去何從

希望你對制作隊列的這套教程感到滿意融痛!
上面的代碼可點擊 這里下載壶笼。你還可以去往 這里 查看其他的實現(xiàn)方式以及進行隊列的進一步的討論。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末雁刷,一起剝皮案震驚了整個濱河市覆劈,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌沛励,老刑警劉巖责语,帶你破解...
    沈念sama閱讀 216,591評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異目派,居然都是意外死亡坤候,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評論 3 392
  • 文/潘曉璐 我一進店門企蹭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來白筹,“玉大人智末,你說我怎么就攤上這事⊥胶樱” “怎么了系馆?”我有些...
    開封第一講書人閱讀 162,823評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長顽照。 經(jīng)常有香客問我由蘑,道長,這世上最難降的妖魔是什么代兵? 我笑而不...
    開封第一講書人閱讀 58,204評論 1 292
  • 正文 為了忘掉前任尼酿,我火速辦了婚禮,結(jié)果婚禮上奢人,老公的妹妹穿的比我還像新娘谓媒。我一直安慰自己,他們只是感情好何乎,可當(dāng)我...
    茶點故事閱讀 67,228評論 6 388
  • 文/花漫 我一把揭開白布句惯。 她就那樣靜靜地躺著,像睡著了一般支救。 火紅的嫁衣襯著肌膚如雪抢野。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,190評論 1 299
  • 那天各墨,我揣著相機與錄音指孤,去河邊找鬼。 笑死贬堵,一個胖子當(dāng)著我的面吹牛恃轩,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播黎做,決...
    沈念sama閱讀 40,078評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼叉跛,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了蒸殿?” 一聲冷哼從身側(cè)響起筷厘,我...
    開封第一講書人閱讀 38,923評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎宏所,沒想到半個月后酥艳,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,334評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡爬骤,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,550評論 2 333
  • 正文 我和宋清朗相戀三年充石,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片霞玄。...
    茶點故事閱讀 39,727評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡赫冬,死狀恐怖浓镜,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情劲厌,我是刑警寧澤,帶...
    沈念sama閱讀 35,428評論 5 343
  • 正文 年R本政府宣布听隐,位于F島的核電站补鼻,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏雅任。R本人自食惡果不足惜风范,卻給世界環(huán)境...
    茶點故事閱讀 41,022評論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望沪么。 院中可真熱鬧硼婿,春花似錦、人聲如沸禽车。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽殉摔。三九已至州胳,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間逸月,已是汗流浹背栓撞。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留碗硬,地道東北人瓤湘。 一個月前我還...
    沈念sama閱讀 47,734評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像恩尾,于是被迫代替她去往敵國和親弛说。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,619評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 隊列像一個列表特笋,您只能在最后插入新元素剃浇,并從最前面刪除元素。 這確保了您第一個入隊的元素也是您出隊的第一個元素猎物。 ...
  • 在經(jīng)過一次沒有準(zhǔn)備的面試后虎囚,發(fā)現(xiàn)自己雖然寫了兩年的android代碼,基礎(chǔ)知識卻忘的差不多了蔫磨。這是程序員的大忌淘讥,沒...
    猿來如癡閱讀 2,839評論 3 10
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)堤如,斷路器蒲列,智...
    卡卡羅2017閱讀 134,652評論 18 139
  • 通過資格考試和研究生入學(xué)考試窒朋。 (堅持每天學(xué)習(xí)2小時專業(yè)+1小時英語)
    其實Xl閱讀 120評論 0 0
  • 一、群內(nèi)讀規(guī)畫蝗岖,祈禱文侥猩,了凡能量、經(jīng)文 二抵赢、行動: 1.聆聽:中午孩子回家吃飯欺劳,先生早已把飯準(zhǔn)備好,請大家來吃铅鲤。孩...
    陽光中的晨薇閱讀 224評論 0 0