日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Queue(队列)-Swift实现与广度优先搜索应用

發布時間:2023/12/15 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Queue(队列)-Swift实现与广度优先搜索应用 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
  • 定義

僅可以在隊首進行刪除,隊尾進行插入的線性表,稱為隊列。

  • 特點

先入隊列,則先刪除(First In First Out),類似Stack

  • 應用

鍵盤的輸入輸出

廣度優先搜索等算法的實現

  • Swift的實現(普通)
struct Queue<T> {//這里可以用鏈表代替private var array = Array<T>()//判空var isEmpty: Bool {return array.isEmpty}//隊列中元素個數var count: Int {return array.count}//查看隊首元素var front: T? {return array.first}//入隊mutating func enqueque(_ element: T) {array.append(element)}//出隊mutating func dequeue() -> T? {guard !isEmpty else { return nil }return array.removeFirst()} } 復制代碼

現在實現的這個隊列就可以工作了,但是還有些地方是不太完美的。

  • 1.當enqueue(入隊)操作時,因為是將新的元素加到數組的尾部,所以入隊的時間復雜對為O(1)。 原因:在Swift中,在數組的后面,會預留出一些空的位置
var queue = Queue<String>() queue.enqueque("a") queue.enqueque("b") queue.enqueque("c") //實際在數組中情況為 ["a", "b", "c", **, **, **] //** 就是預留出來的內存,以備將來插入新的元素 queue.enqueque("d") 后 // 實際情況為 ["a", "b", "c", "d", **, **] 復制代碼

Array的這種機制也會有問題,因為在數組的末端只會預留少量的位置,當最后一個預留的位置也被插入新的元素后,就需要將整個數組中的元素一起拷貝,到一個新的擁有更多位置的數組中,這時的時間復雜度為O(n),但是這種情況只是偶爾發生,所以平均的時間復雜對還是O(1)。

  • 2.當dequeue(出隊)操作時,因為是將數組中的第一個元素刪除,當刪除第一個元素后,數組中剩余的所有元素都需要向前移動一個位置,來填充前面的空白,所以這個時候的時間復雜度為O(n),每當dequeue一次后,時間復雜度都為O(n),這種操作效率是很低的。

  • Swift的實現(稍高效) 稍稍高效些的隊列的實現辦法有好幾種,比如循環隊列等,我們介紹一個比循環隊列實現簡單些的。

  • 思路:不再是每出隊一次,就將數組中的元素向前移動,而是等到滿足一定條件后,才統一的向前移動。

  • 代碼

struct Queue<T> {private var array = Array<T?>()///用來標記隊列的頭位置private var headIndex = 0//判空var isEmpty: Bool {return array.isEmpty}//隊列中元素個數var count: Int {return array.count}//查看隊首元素var front: T? {if isEmpty { return nil }return array[headIndex]}//入隊mutating func enqueque(_ element: T) {array.append(element)}//出隊mutating func dequeue() -> T? {//存在隊首元素guard !isEmpty, let firstElement = array[headIndex] else { return nil }array[headIndex] = nil//重新標記隊首的位置headIndex += 1//達到條件,刪除前面的空位置,條件可以按照需要進行更改let percentage = Double(headIndex)/Double(array.count)if array.count > 20 && percentage > 0.25 {array.removeFirst(headIndex)headIndex = 0}return firstElement} } 復制代碼
  • 廣度優先搜索

  • 尋找大兵瑞恩,從下面的人物關系圖中,最終找到瑞恩的最短路徑

  • 思路 -- 先找你直接認識的朋友中,是否有瑞恩,有查找完成 -- 如果在你直接認識的朋友中沒有,則在朋友的朋友中查找,直到找到,或所有人都找過 -- 關鍵,只有你直接認識的朋友中找完后,才能去從朋友的朋友中去查找,這就需要通過隊列的先進先出特性來實現 -- 記錄查找過的人,防止循環查找

//通過字典(散列)來記錄整張關系圖var relationGraph: [String: [String]] = {var dic: [String: [String]] = ["Me": ["A", "C"]]dic["A"] = ["B"]dic["C"] = ["B", "D", "Ryan"]dic["B"] = ["Ryan"]dic["D"] = ["Ryan"]return dic}()//創建一個存儲,朋友及朋友的朋友的隊列var queue = Queue<String>()//用來記錄已經查詢過的人var checked = [String]()func find(_ name: String) {findFromQueue(name)}//到朋友隊列中找Ryanfunc findFromQueue(_ name: String) {while queue.count > 0 {guard let person = queue.dequeue() else {return print("Can not find \(name)")}//如果查過則找下一個if checked.contains(person) { continue }//記錄已經查詢過的checked.append(person)//找到if person == name {print("Find \(name)")break//未找到}else {//將朋友的朋友加入到隊列中enQueueFriends(person)}}}//將朋友加入到隊列中func enQueueFriends(_ name: String) {guard let friends = relationGraph[name] else { return }let _ = friends.map {return queue.enqueque($0)}} 復制代碼
  • 調用
//將自己的朋友加入到待查找隊列中 enQueueFriends("Me") //從自己的朋友及朋友的朋友中尋找Ryan find("Ryan") 復制代碼

總結

以上是生活随笔為你收集整理的Queue(队列)-Swift实现与广度优先搜索应用的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。