数据结构与算法-队列
什么是队列
跟栈一样是一种操作受限的线性数据结构,满足先进先出的特性
顺序队列实现例子

1 // 用数组实现的队列 2 public class ArrayQueue { 3 // 数组:items,数组大小:n 4 private String[] items; 5 private int n = 0; 6 // head表示队头下标,tail表示队尾下标 7 private int head = 0; 8 private int tail = 0; 9 10 // 申请一个大小为capacity的数组 11 public ArrayQueue(int capacity) { 12 items = new String[capacity]; 13 n = capacity; 14 } 15 16 // 入队 17 public boolean enqueue(String item) { 18 // 如果tail == n 表示队列已经满了 19 if (tail == n) return false; 20 items[tail] = item; 21 ++tail; 22 return true; 23 } 24 25 // 出队 26 public String dequeue() { 27 // 如果head == tail 表示队列为空 28 if (head == tail) return null; 29 // 为了让其他语言的同学看的更加明确,把--操作放到单独一行来写了 30 String ret = items[head]; 31 ++head; 32 return ret; 33 } 34 }
基于链表的队列实现例子
需要两个指针:head 指针和 tail 指针。它们分别指向链表的第一个结点和最后一个结点。如图所示,入队时,tail->next= new_node, tail = tail->next;出队时,head = head->next
循环队列
用数组来实现队列的时候,在 tail==n 时,会有数据搬移操作,这样入队操作性能就会受到影响。那有没有办法能够避免数据搬移呢?我们来看看循环队列的解决思路。
这个队列的大小为 8,当前 head=4,tail=7。当有一个新的元素 a 入队时,我们放入下标为 7 的位置。但这个时候,我们并不把 tail 更新为 8,而是将其在环中后移一位,到下标为 0 的位置。当再有一个元素 b 入队时,我们将 b 放入下标为 0 的位置,然后 tail 加 1 更新为 1。所以,在 a,b 依次入队之后,循环队列中的元素就变成了下面的样子:
当队列满了 tail始终会浪费一个节点数据

public class CircularQueue { // 数组:items,数组大小:n private String[] items; private int n = 0; // head表示队头下标,tail表示队尾下标 private int head = 0; private int tail = 0; // 申请一个大小为capacity的数组 public CircularQueue(int capacity) { items = new String[capacity]; n = capacity; } // 入队 public boolean enqueue(String item) { // 队列满了 if ((tail + 1) % n == head) return false; items[tail] = item; tail = (tail + 1) % n; return true; } // 出队 public String dequeue() { // 如果head == tail 表示队列为空 if (head == tail) return null; String ret = items[head]; head = (head + 1) % n; return ret; } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!