• 定义

仅可以在队首进行删除,队尾进行插入的线性表,称为队列。

  • 特点

先入队列,则先删除(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实现与广度优先搜索应用相关推荐

  1. 二叉树层序遍历(广度优先搜索)基础概念与经典题目(Leetcode题解-Python语言)

    二叉树的广度优先搜索即从上到下.从左到右地进行搜索,对于层序遍历(Level Order)问题,即依次遍历第一层节点.第二层节点-等,基本可以秒杀. 广度优先搜索是通过队列来实现的,python中优先 ...

  2. 分别用邻接矩阵和邻接表实现图的深度优先遍历和广度优先遍历_数据结构|图的邻接表与深度、广度优先搜索

    线性存储元素时,元素的关系也同时确定了.而非线性数据结构就不同了,需要同时考虑存储数据元素和数据元素的关系. 由于图的结构比较复杂,任意两个顶点之间都可能存在联系,因此无法以数据元素在存储区中的物理位 ...

  3. Leecode第九天,广度优先搜索之矩阵,腐烂的橘子

    第九天,两个广度优先搜索的算法题,先来看第一个 乍一看没有头绪,那我们先简化一下题目,假如只有一个0,那问题是不是很简单,以唯一的0作为中心做广度优先搜索,设个变量depth,每搜索一层,depth+ ...

  4. 算法图解第六章笔记与习题(广度优先搜索)

    算法图解第六章笔记与习题(广度优先搜索) 文章目录 算法图解第六章笔记与习题(广度优先搜索) 6.1 图(graph) 6.2 广度优先搜索 6.3.1 查找最短路径 6.3.2 队列 6.4 实现图 ...

  5. 限界分支法(实际上没有剪枝,介绍的是广度优先搜索):01背包问题,队列实现方式(FIFO)

    限界分支法:队列实现方式 前面已经介绍过限界分支法大部分是基于广度优先搜索,广度优先搜索一般借助于队列实现,剪枝的情况可以借助于优先级队列. 实现如下: #%% class FIFO_01_Pack: ...

  6. 队列的JS实现及广度优先搜索(BFS)的实现

    队列是先进先出(FIFO)的数据结构,插入操作叫做入队,只能添加在队列的末尾:删除操作叫做出队,只能移除第一个元素.在JS中,用数组可以很简单的实现队列. function Queue () {thi ...

  7. 刷穿剑指offer-Day21-队列II 使用队列实现广度优先搜索!

    昨日回顾 昨天,我们介绍了队列的基础知识,并分别学习了Python与Java中队列的操作方法. 在此基础上,通过两道简单的队列题,掌握了基本的入队与出队操作.然而,队列的题目可不只是简单按照顺序出入队 ...

  8. 广度优先搜索 宽度优先搜索 迷宫问题 最短路径 最少操作 由近及远 队列

    广度优先搜索,也叫宽度优先搜索,从开始状态,到第一次能到达的状态,再从第一次能到达的状态到下一个能到达的状态,直到探索所有可到达的状态,其时间复杂度为O(状态数×转移的方式). 广度优先搜索使用了队列 ...

  9. LeetCode 752. 打开转盘锁 (C#实现)——队列,广度优先搜索

    一.代码实现 思路:使用先进先出的队列,广度优先搜索,使用字典可大幅减少遍历时间 问题:https://leetcode-cn.com/problems/open-the-lock/submissio ...

最新文章

  1. Windows Store获得Fluent Design加成
  2. 在spring中集成webservice 框架 CXF
  3. 微观经济学的学习和理解
  4. python中封装一个枚举_JavaScript可扩展枚举封装
  5. 开源项目|从0到1教你搭建一个适配于智能车的目标检测系统
  6. 第三届蓝桥杯省赛---第39级台阶
  7. python爬取商城数据_Python爬取新版CRMEB小程序商城后台订单数据,保存为excel
  8. 一些服务器客户端的c例子
  9. java http data chunk_HTTP协议之Chunked解析
  10. ICP许可证的办理条件
  11. AI前言技术,一文带你深入了解语音识别的前世今生
  12. wps excel 表格给一列数据添加相同的内容的方法
  13. 语义分割中样本分布不均衡怎么办
  14. Crack:GrapeCity Documents for Excel 6.0.1
  15. 申请微信小程序流程步骤
  16. 小程序支付后台实现(服务商)
  17. SeekBarVolumizer.java
  18. Burp Suite下载CA证书
  19. 蓝牙电子秤方案_IC/PCBA
  20. 独家 度小满教育、医美分期不做直营了

热门文章

  1. kali中安转python3_Kali环境下安装Python3.7
  2. P4390 [BOI2007]Mokia 摩基亚 (CDQ解决三维偏序问题)
  3. python 爬虫 selenium
  4. 在Linux上安装nginx时遇到的问题,真的好坑啊!!!!
  5. 信号 应用场景 内置信号 内置信号操作 自定义信号
  6. 使用html元素的getBoundingClientRect来获取dom元素的时时位置和大小
  7. 如何在ASP.NET服务器控件库中嵌入JavaScript脚本文件 [适用于.NET 2.0]
  8. 发现asp.net 2.0 在MSDN中的多个BUG 关于无刷新窗体的
  9. sqlite-常用语句
  10. opencv----(1) mat最好用,和IplImage,cvmat 比较