数据结构之队列(一般队列)
1. 什么是队列?
队列是一种特殊的线性表,一般只允许在队列的两端进行操作,队列前端进行删除操作,队列的末尾进行添加操作(双向队列的前端、末尾都可以进行删除、添加操作)。
队列可以用数组或链表实现。主要有两个指针:一个front指向队首元素,一个rear指向队尾元素。
2. 队列常见操作
队列常用的操作有:
- enqueue(e): 将元素e加入队尾
- dequeue(): 返回队首元素,并将其从队列中移除
- peek(): 返回队首元素的值,但不删除
- size():返回队列中元素的个数
- isEmpty(): 队列是否为空
- show(): 返回队列的字符串形式
3. 队列的特点
·1. 线性数据结构
2. 先进先出
3. 有两个指针:一个front指向队首元素,一个rear指向队尾元素
4. 一般队首进行出列,队尾进行入列
5. 队列的长度是动态变化的,可以根据需要自动扩容或者缩减(特别注意数组实现队列时,可能会越界,需要扩容或缩进)。
4. 应用场景
队列是一种具有先进先出(FIFO)特性的数据结构,常用于需要按顺序处理数据的场景。以下是一些使用队列的示例:
-
消息队列:在消息系统中,消息发送者将消息添加到队列的尾部,而消息接收者从队列的头部获取消息进行处理。这种方式可以实现消息的异步处理,提高系统的并发能力。
-
请求排队:在服务器端,当有大量请求同时达到时,通过队列来对请求进行排队处理,以避免服务器过载。
-
生产者-消费者模型:在多线程或分布式系统中,生产者负责生成数据,消费者负责处理数据。通过队列作为缓冲区,可以实现生产者和消费者之间的解耦,提高系统的稳定性和性能。
-
广度优先搜索:在图论算法中,广度优先搜索通过队列来管理待访问的节点,实现对图的层次遍历。这在寻找最短路径等问题中非常常见。
-
缓存淘汰策略:在缓存系统中,当缓存空间不足时,可以使用队列来记录每个缓存项的访问时间,按照一定的策略删除最早访问的缓存项,以腾出空间给新的缓存项。
-
系统任务调度:在操作系统中,任务调度器可以使用队列来管理各个进程的执行顺序,按照优先级等规则进行调度。
-
打印机队列:打印机作为共享资源,当多个任务需要打印时,可以通过队列管理打印请求的顺序,避免打印机被多个任务同时访问。
总之,队列在很多需要按照顺序处理数据的场景中都有应用,它能够提供高效的插入和删除操作,并且保证元素的顺序性。
5. Python
5.1 数组实现队列
1 ''' 2 数组实现队列 3 ''' 4 5 6 class Queue: 7 def __init__(self): 8 self.items = [] 9 10 def is_empty(self): 11 # 返回队列是否为空 12 return self.items == [] 13 14 def enqueue(self, item): 15 # 在队尾添加元素 16 self.items.append(item) 17 18 def dequeue(self): 19 # 删除队首元素 20 if not self.is_empty(): 21 return self.items.pop(0) 22 23 def peek(self): 24 # 获取队首元素的值 25 if not self.is_empty(): 26 return self.items[0] 27 28 def size(self): 29 # 获取队列中的元素个数 30 return len(self.items) 31 32 def __str__(self): 33 return str(self.items) 34 35 36 myQueue = Queue() 37 myQueue.enqueue(1) 38 myQueue.enqueue(2) 39 40 print(myQueue.is_empty()) # 返回 False 41 print(myQueue.peek()) # 返回 1 42 print(myQueue.peek()) # 返回 1 43 44 print(myQueue.dequeue()) # 1 45 print(myQueue.dequeue()) # 2 46 print(myQueue.is_empty()) # 返回 True
输出:
1 2 3 4 5 6 | False 1 1 1 2 True |
5.2 链表实现队列示例
1 ''' 2 链表实现队列 3 ''' 4 5 6 class Node(): 7 def __init__(self, data): 8 self.data = data 9 self.next = None 10 11 12 class Queue(): 13 def __init__(self): 14 self.head = None 15 self.tail = None 16 17 def enqueue(self, item): 18 if self.is_empty(): # 队列为空 19 self.head = Node(item) 20 self.tail = self.head 21 else: # 队列不为空 22 node = Node(item) # 创建一个节点 23 self.tail.next = node # 把新节点接到尾部 24 self.tail = node # 更新尾部指针 25 26 def dequeue(self): 27 28 if self.is_empty(): # 当队列为空时,返回None 29 return None 30 else: 31 cur = self.head 32 self.head = cur.next # 删除第一个节点 33 if self.head is None: # 如果删除后队列已经空了 34 self.tail = None 35 return cur 36 37 def is_empty(self): 38 return self.head is None 39 40 41 myQueue = Queue() 42 print(myQueue.is_empty()) # True 43 myQueue.enqueue(1) 44 myQueue.enqueue(2) 45 print(myQueue.is_empty()) # 返回 False 46 print(myQueue.dequeue().data) # 返回 1 47 print(myQueue.dequeue().data) # 返回 2 48 print(myQueue.is_empty()) # 返回 True
输出:
1 2 3 4 5 | True False 1 2 True |
6. Java
在Java中,可以使用数组来实现队列。具体实现的方式有以下几种:
-
使用固定长度的数组:可以创建一个固定长度的数组,然后使用指针指向队列的头部和尾部。当入队操作时,将元素添加到队列尾部,同时移动尾指针。当出队操作时,将头指针指向的元素删除,并将头指针向后移动一位。这种方式的缺点是队列的长度固定,不能动态调整。
-
使用循环数组:可以创建一个循环数组,使用两个指针分别指向队列的头部和尾部。当入队操作时,将元素添加到尾部,并将尾指针向后移动一位,如果尾指针超过了数组的长度,则将其重置为0。当出队操作时,将头指针指向的元素删除,并将头指针向后移动一位,如果头指针超过了数组的长度,则将其重置为0。这种方式可以实现队列的动态扩容。
-
使用LinkedList类:Java提供了LinkedList类,可以直接用来实现队列。LinkedList类实现了Queue接口,提供了队列的常见操作方法,如入队、出队、获取队首元素等。使用LinkedList类实现队列的好处是不需要手动处理数组的大小和扩容问题,同时具有较好的插入和删除性能。
1 import java.util.LinkedList; 2 import java.util.Queue; 3 4 public class QueueExample { 5 public static void main(String[] args) { 6 // 创建一个队列 7 Queue<Integer> queue = new LinkedList<>(); 8 9 // 入队操作 10 queue.offer(1); 11 queue.offer(2); 12 queue.offer(3); 13 14 // 出队操作 15 int firstElement = queue.poll(); 16 System.out.println("出队元素:" + firstElement); 17 18 // 获取队首元素(不出队列) 19 int frontElement = queue.peek(); 20 System.out.println("队首元素:" + frontElement); 21 22 // 获取队列中的元素个数 23 int size = queue.size(); 24 System.out.println("队列大小:" + size); 25 26 // 打印队列 27 System.out.println("队列内容:" + queue); 28 } 29 }
输出:
1 2 3 4 | 出队元素: 1 队首元素: 2 队列大小: 2 队列内容:[ 2 , 3 ] |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)