当前位置: 首页 > news >正文

队列-概念【Queue1】

1、什么是队列

队列 (Queue) 是一种基础的线性数据结构。想象一下在超市排队结账的场景:最先到达收银台的人会最先完成结账离开。后来的人需要排在队伍的末尾,并等待前面的人全部处理完毕。

核心原则:先进先出 (First-In, First-Out),这个原则通常缩写为 FIFO。它规定了数据处理的顺序:最早进入队列的元素,将是第一个被移除和处理的元素

2、队列的基本结构

为什么要有队首和队尾?

  • 队首(front):用于删除元素,保证最先入队的元素最先出队
  • 队尾(rear):用于添加元素,新元素总是添加到队列末尾
  • 单向操作:这种设计确保了FIFO原则的严格执行

3、队列的基本操作

操作描述时间复杂度
入队在队尾添加一个元素O(1)
出队从队首删除一个元素并返回O(1)
查看队首查看队首元素但不删除O(1)
判断空队列检查队列是否为空O(1)
获取大小返回队列中元素的数量O(1)

3.1 入队操作

因为队列遵循FIFO原则,新来的元素应该排在队伍的最后面,等待轮到它时才能被处理。

3.2 出队操作

因为队首的元素是最早入队的,按照FIFO原则,它应该最先被处理和移除。

4、有界和无界队列

一个非常重要的细节是队列的容量。根据容量是否有限,队列可以分为两类:

  • 无界队列 : 理论上可以无限增长,只要系统内存充足。Python 的 <font style="color:rgb(31, 41, 55);background-color:rgb(249, 250, 251);">list</font><font style="color:rgb(31, 41, 55);background-color:rgb(249, 250, 251);">deque</font>默认都是无界队列。
  • 有界队列 : 具有固定的容量上限。当队列满了之后,任何新的入队请求都需要根据预设的策略来处理。这在资源有限或需要控制生产速率的场景中非常关键。

5、可视化演示

juejin

6、基于 Java 实现的队列

6.1 基于数组的队列
public class ArrayQueue {private Object[] items;private int head;private int tail;private int capacity;public ArrayQueue(int capacity) {this.capacity = capacity;items = new Object[capacity];head = 0;tail = 0;}// 入队public boolean enqueue(Object item) {if (tail == capacity) { // 队列已满return false;}items[tail] = item;tail++;return true;}// 出队public Object dequeue() {if (head == tail) { // 队列为空return null;}Object item = items[head];head++;return item;}@Overridepublic String toString() {StringBuilder sb = new StringBuilder();sb.append("Queue: [");for (int i = head; i < tail; i++) {sb.append(items[i]);if (i < tail - 1) {sb.append(", ");}}sb.append("]");return sb.toString();}
}
6.2 基于 LinkedList 的队列

Java 中 LinkedList 本身实现了 Queue 接口,可直接用于队列操作:

import java.util.LinkedList;
import java.util.Queue;public class LinkedListQueueDemo {public static void main(String[] args) {Queue<Integer> queue = new LinkedList<>();// 入队queue.offer(10);queue.offer(20);queue.offer(30);// 出队System.out.println(queue.poll()); // 输出 10// 查看队首元素(不出队)System.out.println(queue.peek()); // 输出 20System.out.println(queue); // 输出 [20, 30]}
}
6.3 两种方式的性能对比
操作数组队列LinkedList 队列
入队/出队若不扩容,时间复杂度为 O(1);若扩容,为 O(n)时间复杂度始终为 O(1)
空间占用需预先分配容量,可能有空间浪费元素按需分配,空间利用率更高
适用场景已知队列最大容量,追求高吞吐队列容量不确定,或频繁进行增删
6.4 使用链表实现队列(自定义)
public class LinkedQueue {// 节点类private static class Node {Object data;Node next;public Node(Object data) {this.data = data;}}private Node head;private Node tail;private int size;public LinkedQueue() {head = null;tail = null;size = 0;}// 入队public void enqueue(Object item) {Node newNode = new Node(item);if (tail == null) { // 队列为空head = newNode;tail = newNode;} else {tail.next = newNode;tail = newNode;}size++;}// 出队public Object dequeue() {if (head == null) { // 队列为空return null;}Object item = head.data;head = head.next;if (head == null) { // 队列空了,tail 置空tail = null;}size--;return item;}@Overridepublic String toString() {StringBuilder sb = new StringBuilder();sb.append("Queue: [");Node cur = head;while (cur != null) {sb.append(cur.data);if (cur.next != null) {sb.append(", ");}cur = cur.next;}sb.append("]");return sb.toString();}
}
6.5 线程安全的队列

Java 提供了 java.util.concurrent 包下的线程安全队列,如 ConcurrentLinkedQueue(非阻塞)、ArrayBlockingQueue(阻塞)等。

示例(ConcurrentLinkedQueue):

import java.util.concurrent.ConcurrentLinkedQueue;public class ThreadSafeQueueDemo {public static void main(String[] args) {ConcurrentLinkedQueue<Integer> queue = new ConcurrentLinkedQueue<>();// 入队queue.offer(100);queue.offer(200);// 出队System.out.println(queue.poll()); // 输出 100}
}

7、特殊类型的队列

7.1 循环队列(参考前文的 CircularQueue 实现)

核心是利用取模运算实现“环形复用”,避免数组队列的“假溢出”问题。

7.2 双端队列(Deque

Java 中 Deque 接口支持两端(队首、队尾)的入队/出队操作,LinkedListArrayDeque 都实现了该接口。

示例(ArrayDeque):

import java.util.ArrayDeque;
import java.util.Deque;public class DequeDemo {public static void main(String[] args) {Deque<String> deque = new ArrayDeque<>();// 队尾入队deque.offerLast("A");deque.offerLast("B");// 队首入队deque.offerFirst("C");// 队首出队System.out.println(deque.pollFirst()); // 输出 C// 队尾出队System.out.println(deque.pollLast()); // 输出 B}
}
7.3 优先队列(PriorityQueue

基于堆结构实现,元素按优先级(默认自然序或自定义比较器)出队。

示例:

import java.util.PriorityQueue;public class PriorityQueueDemo {public static void main(String[] args) {PriorityQueue<Integer> pq = new PriorityQueue<>();pq.offer(30);pq.offer(10);pq.offer(20);// 出队时按从小到大顺序System.out.println(pq.poll()); // 输出 10System.out.println(pq.poll()); // 输出 20}
}

自定义比较器(实现大顶堆):

PriorityQueue<Integer> pq = new PriorityQueue<>((a, b) -> b - a);
pq.offer(30);
pq.offer(10);
pq.offer(20);
System.out.println(pq.poll()); // 输出 30
7.4 队列对比
队列类型核心特性典型实现类/接口适用场景
普通队列先进先出(FIFO)Queue/LinkedList/ArrayQueue任务调度、消息队列等基础场景
循环队列数组环形复用,减少空间浪费自定义 CircularQueue已知容量上限的高性能场景
双端队列两端均可增删Deque/ArrayDeque/LinkedList滑动窗口、栈模拟等场景
优先队列按优先级出队PriorityQueue任务优先级调度、TopK 问题
线程安全队列支持多线程并发操作ConcurrentLinkedQueue/ArrayBlockingQueue并发编程中的数据共享

8、应用场景

  • 普通队列:消息队列(如 RabbitMQ 底层逻辑)、广度优先搜索(BFS)。
  • 循环队列:数据库连接池、生产者-消费者模型的缓冲区。
  • 双端队列:滑动窗口算法(如“最长无重复子串”问题)、栈的模拟(Deque 可当栈用)。
  • 优先队列:任务调度(如高优先级任务先执行)、求数据流的中位数。
  • 线程安全队列:多线程环境下的日志收集、任务分发。

9、总结

Java 中队列的实现丰富多样,从基础的数组、链表队列,到特殊的循环队列、双端队列、优先队列,再到线程安全队列,每种队列都有其适用场景。在实际开发中,需根据容量是否确定、是否需要并发支持、元素优先级要求等因素,选择合适的队列实现。

http://www.dtcms.com/a/541991.html

相关文章:

  • OCR用于Llamaindex与OCR运用的展望
  • DeepSeek-OCR MoE结构梳理(其它LLM原理类似)
  • 浙江建设银行网站多少钱算有钱
  • 青岛正规公司网站建设公司国内网如何看国外网站
  • 商城网站建设公司报价如何搜索公司所有的网站
  • 成绩查询和成绩分析发布工具搭建教程
  • 控制网站的大量访问连云港建设工程质量监督站网站
  • Visual Studio 2010 Ultimate 中文版安装教程(ISO文件安装步骤附安装包下载)​
  • 【前端高频面试题】深入理解 JavaScript 内存管理与闭包原理(附高分答题模板)
  • 样本熵和泊松指数的计算流程!!!
  • 在平台企业网站推广怎么做网站建设合同详细
  • C++运算符重载中的引用返回:链式操作的关键技巧
  • Python文件操作全解析:打开、关闭与读写实战
  • 服装 多语言 网站源码国外做鞋子的网站
  • Maven 项目模板
  • 安全可信网站网页设计师培训在哪里
  • 我的网站模板下载下面哪些不是网页制作工具
  • 西安优秀的集团门户网站建设公司wordpress页面默认模板
  • 怎么往网站添加视频网站建设 计入哪个科目
  • 做网站放网站广告南阳建设网站
  • 从 0 到 1 掌握 std::packaged_task:C++ 异步任务的 “隐形胶水“
  • 传统文化网站建设方案空间放两个网站
  • 品牌展示设计网站简洁类wordpress主题
  • 基于AI智能算法的装备结构可靠性分析与优化设计技术专题
  • 地平线J6的基础简介
  • 郓城网站建设价格沈阳做网站优化的公司
  • 一键部署MySQL
  • 网站 做 专家问答汽车网站开发思路
  • float16精度、bfloat16、混合精度
  • 北京网站建设公司有哪些学代码的网站