Python实现队列
队列 (queue) 是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。
队列符合先进先出[FIFO]的原则。因为要排队的第一个项目,最终将是第一个要出列的项目,如在现实生活中的队列,先来的站在队列前面,后来的就只能站在队列后面啦。
队列有两种实现形式,分为两种:数组和链表。
在接下来的内容里,我们将以链表的形式实现队列,逐步介绍具体功能是如何实现的。
1. 创建 Node 类
创建一个 Node 的类,作为基础数据结构:链点,并初始化对应的内参。
具体实现代码如下:
1 2 3 4 | class Node( object ): def __init__( self ,elem, next = None ): self .elem = elem #表示对应的元素值 self . next = next #表示下一个链接的链点 |
2. 创建 Queue 类
创建一个 Queue 的类,以链表形式的队列,并初始化对应的内参。
具体实现代码如下:
1 2 3 4 | class Queue( object ): def __init__( self ): self .head = None #头部链点为 None self .rear = None #尾部链点为 None |
3. 添加 is_empty 函数
添加一个 is_empty 的函数,功能是判断队列是否为空
具体实现代码如下:
1 2 | def is_empty( self ): return self .head is None #判断队列是否为空 |
4. 添加 enqueue 函数
添加一个 enqueue(elem) 函数,功能是往队列中添加一个 elem 元素
流程如下:
- Vertex vtx = new Vertex(v) 初始化一个新的点
- tail.next = vtx 队列尾部的后继是这个新的点
- tail = vtx 然后让队列尾部指针指向这个新的点
效果演示:往已知队列[29,9,53]里面添加一个 80 元素
具体实现代码如下:
1 2 3 4 5 6 7 8 | def enqueue( self , elem): p = Node(elem) #初始化一个新的点 if self .is_empty(): self .head = p #队列头部为新的链点 self .rear = p #队列尾部为新的链点 else : self .rear. next = p #队列尾部的后继是这个新的点 self .rear = p #然后让队列尾部指针指向这个新的点 |
5. 添加 dequeue 函数
添加一个 dequeue() 函数,功能是从队列头部删除一个元素
流程如下:
- 先判断队列是否为空,为空即退出 dequeue 操作,不为空即继续后续操作
- temp = head 设置一个 temp 指针,使它的指针指向队列头部
- head = head.next 队列头部指针,使之指向队列头部的后继(即队列头部元素出队)
- delete temp 删除 temp 指针
效果演示:对已知队列[29,9,53,80] 删除头部元素
具体实现代码如下:
1 2 3 4 5 6 7 | def dequeue( self ): if self .is_empty(): #判断队列是否为空 print ( 'Queue_is_empty' ) #若队列为空,则退出 dequeue 操作 else : result = self .head.elem #result为队列头部元素 self .head = self .head. next #改变队列头部指针位置 return result #返回队列头部元素 |
6. 添加 peek 函数
添加一个 peek() 函数,功能是查看队列头部的元素
流程如下:
- 判断队列是否为空,为空即返回 NOT_FOUND
- 队列如果不为空,返回队列头部元素
具体代码实现如下:
1 2 3 4 5 | def peek( self ): if self .is_empty(): #判断队列是否为空 print ( 'NOT_FOUND' ) #为空则返回 NOT_FOUND else : return self .head.elem #返回队列头部元素 |
7. 添加 print_queue 函数
添加一个 print_queue() 函数,功能是展现队列的元素
1 2 3 4 5 6 7 8 | def print_queue( self ): print ( "queue:" ) temp = self .head myqueue = [] #暂时存放队列数据 while temp is not None : myqueue.append(temp.elem) temp = temp. next print (myqueue) |
最终代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | class Node( object ): def __init__( self ,elem, next = None ): self .elem = elem #表示对应的元素值 self . next = next #表示下一个链接的链点 class Queue( object ): def __init__( self ): self .head = None #头部链点为 None self .rear = None #尾部链点为 None def is_empty( self ): return self .head is None #判断队列是否为空 def enqueue( self , elem): p = Node(elem) #初始化一个新的点 if self .is_empty(): self .head = p #队列头部为新的链点 self .rear = p #队列尾部为新的链点 else : self .rear. next = p #队列尾部的后继是这个新的点 self .rear = p #然后让队列尾部指针指向这个新的点 def dequeue( self ): if self .is_empty(): #判断队列是否为空 print ( 'Queue_is_empty' ) #若队列为空,则退出 dequeue 操作 else : result = self .head.elem #result为队列头部元素 self .head = self .head. next #改变队列头部指针位置 return result #返回队列头部元素 def peek( self ): if self .is_empty(): #判断队列是否为空 print ( 'NOT_FOUND' ) #为空则返回 NOT_FOUND else : return self .head.elem #返回队列头部元素 def print_queue( self ): print ( "queue:" ) temp = self .head myqueue = [] #暂时存放队列数据 while temp is not None : myqueue.append(temp.elem) temp = temp. next print (myqueue) |
复杂度分析
队列属于常见的一种线性结构,对于出队和进队而言,时间复杂度都为 O(1)
队列有两种实现形式,数组和链表。我们在前面已经介绍了如何用链表实现的队列,这里就不再赘述,直接给出另一种用数组实现的队列代码,供大家学习参考。
形式:用数组实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | class Queue(): def __init__( self ): self .entries = [] #表示队列内的参数 self .length = 0 #表示队列的长度 self .front = 0 #表示队列头部位置 def enqueue( self , item): self .entries.append(item) #添加元素到队列里面 self .length = self .length + 1 #队列长度增加 1 def dequeue( self ): self .length = self .length - 1 #队列的长度减少 1 dequeued = self .entries[ self .front] #队首元素为dequeued self .front - = 1 #队首的位置减少1 self .entries = self .entries[ self .front:] #队列的元素更新为退队之后的队列 return dequeued def peek( self ): return self .entries[ 0 ] #直接返回队列的队首元素 请点击选择想要使用的环境 默认环境 |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现