生活随笔
收集整理的這篇文章主要介紹了
                                
Queue(队列)-Swift实现与广度优先搜索应用
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.                        
 
                                
                            
                            
                            僅可以在隊(duì)首進(jìn)行刪除,隊(duì)尾進(jìn)行插入的線性表,稱為隊(duì)列。
 先入隊(duì)列,則先刪除(First In First Out),類似Stack
 鍵盤的輸入輸出
 廣度優(yōu)先搜索等算法的實(shí)現(xiàn)
 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()}
}
復(fù)制代碼現(xiàn)在實(shí)現(xiàn)的這個(gè)隊(duì)列就可以工作了,但是還有些地方是不太完美的。
 - 1.當(dāng)enqueue(入隊(duì))操作時(shí),因?yàn)槭菍⑿碌脑丶拥綌?shù)組的尾部,所以入隊(duì)的時(shí)間復(fù)雜對(duì)為O(1)。 原因:在Swift中,在數(shù)組的后面,會(huì)預(yù)留出一些空的位置
var queue = 
Queue<
String>()
queue.enqueque(
"a")
queue.enqueque(
"b")
queue.enqueque(
"c")
[
"a", 
"b", 
"c", **,  **, **]
queue.enqueque(
"d") 后
[
"a", 
"b", 
"c", 
"d",  **, **]
復(fù)制代碼Array的這種機(jī)制也會(huì)有問題,因?yàn)樵跀?shù)組的末端只會(huì)預(yù)留少量的位置,當(dāng)最后一個(gè)預(yù)留的位置也被插入新的元素后,就需要將整個(gè)數(shù)組中的元素一起拷貝,到一個(gè)新的擁有更多位置的數(shù)組中,這時(shí)的時(shí)間復(fù)雜度為O(n),但是這種情況只是偶爾發(fā)生,所以平均的時(shí)間復(fù)雜對(duì)還是O(1)。
 -  2.當(dāng)dequeue(出隊(duì))操作時(shí),因?yàn)槭菍?shù)組中的第一個(gè)元素刪除,當(dāng)刪除第一個(gè)元素后,數(shù)組中剩余的所有元素都需要向前移動(dòng)一個(gè)位置,來填充前面的空白,所以這個(gè)時(shí)候的時(shí)間復(fù)雜度為O(n),每當(dāng)dequeue一次后,時(shí)間復(fù)雜度都為O(n),這種操作效率是很低的。 
-  Swift的實(shí)現(xiàn)(稍高效) 稍稍高效些的隊(duì)列的實(shí)現(xiàn)辦法有好幾種,比如循環(huán)隊(duì)列等,我們介紹一個(gè)比循環(huán)隊(duì)列實(shí)現(xiàn)簡(jiǎn)單些的。 
-  思路:不再是每出隊(duì)一次,就將數(shù)組中的元素向前移動(dòng),而是等到滿足一定條件后,才統(tǒng)一的向前移動(dòng)。 
-  代碼 
struct Queue<T>{
private var array = 
Array<
T?>()
private var headIndex = 
0var 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] = 
nilheadIndex += 
1let percentage = 
Double(headIndex)/
Double(array.
count)
if array.
count > 
20 && percentage > 
0.25 {array.removeFirst(headIndex)headIndex = 
0}
return firstElement}
}
復(fù)制代碼-  廣度優(yōu)先搜索 
-  尋找大兵瑞恩,從下面的人物關(guān)系圖中,最終找到瑞恩的最短路徑  
-  思路 -- 先找你直接認(rèn)識(shí)的朋友中,是否有瑞恩,有查找完成 -- 如果在你直接認(rèn)識(shí)的朋友中沒有,則在朋友的朋友中查找,直到找到,或所有人都找過 -- 關(guān)鍵,只有你直接認(rèn)識(shí)的朋友中找完后,才能去從朋友的朋友中去查找,這就需要通過隊(duì)列的先進(jìn)先出特性來實(shí)現(xiàn) -- 記錄查找過的人,防止循環(huán)查找 
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)}
func 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)}}
復(fù)制代碼
enQueueFriends(
"Me")
find(
"Ryan")
復(fù)制代碼
                            總結(jié)
                            
                                以上是生活随笔為你收集整理的Queue(队列)-Swift实现与广度优先搜索应用的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
                            
                            
                                如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。