基础数据结构—队列,Java模拟队列,循环队列
先进先出的队列

队列的相关操作
push x 将x加入队尾,保证x为int型整数
pop 输出队首,并让队首出队
front 输出队首值,不出队
input
6
push 1
pop
front
push 2
push 3
pop
output
1
error
2
1)Java模拟队列
①通过数组
图示思路:
代码实现:
class myQueue{
int[] data; //用数组来模拟队列中存放的数据
int size=0; //队列中元素的个数
int maxSize; //队列中最多存放数据的个数
myQueue(){}
myQueue(int maxSize){
this.maxSize=maxSize;
data = new int[maxSize]; //一定记得初始化数组,不然后续操作空指针
}
//入队
void push(int val){
if(this.size==this.maxSize){
System.out.println("error");
}else{
data[this.maxSize-size-1]=val;
this.size++;
}
}
//出队
void pop(){
if(this.size==0){ System.out.println("error"); }
else{
System.out.println(data[this.maxSize-1]);
if(size>=2){
this.size--;
for(int i=0;i<size;i++){
data[this.maxSize-i-1]=data[this.maxSize-i-2];
}
}else{
this.size--;
}
}
}
//查看队首元素
void front(){
if(this.size==0){ System.out.println("error"); }
else{ System.out.println(data[maxSize-1]); }
}
}
②通过集合
图示思路:
代码实现:
public class Main{
static ArrayList list = new ArrayList<>();
static void push(int x){
list.add(x);
}
//注意Object返回值类型
static Object pop(){
if(!list.isEmpty()){
int str = (Integer)list.get(0); //ArrayList第一元素就是最先进去的
list.remove(0);
return str;
}else{ return "error"; }
}
static Object front(){
if(!list.isEmpty()){
return list.get(0);
}else{
return "error";
}
}
public static void main(String[] args) {
...
}
}
2)循环队列
操作
push x:将x加入到循环队列尾端。若循环队列已满,输出"full"(不含引号),否则不输出任何内容。保证x为int型整数。
front:输出队首元素,队首不出队。若队列为空,输出"empty"(不含引号)。
pop:输出队首元素,且队首出队。若队列为空,输出"empty"(不含引号)。
循环队列组成
存放元素的数组,队头指针, 队尾指针。
队头指针:front,指向队头元素;队尾指针:rear,指向队尾的下一个元素
arr[front]的值就是当前队列的队头元素值
arr[rear-1]的值就是当前队列的队尾元素值
- 初始状态:front=rear=0,队列为空
- 某一状态:front=0,rear=3
- 例如数组arr[5]实时情况为:{1,2,3,0,0},队头元素arr[0]=1,队尾元素arr[2]=3
解释:每次push一个元素到队列尾部,rear++,当arr[4]放入元素,rear将会达到5
- 队列装满状态:front=0=rear??
但是数组下标为0-4,5并没有意义。所以rear如果等于5了应该再将它置为0。
改进:元素入队时rear=(rear+1)%maxSize,假如maxSize=5,rear+1=5时对maxSize取余为0达到效果。
发现问题:无法通过判断front==rear来确定循环队列是否装满。
牺牲一个存储单元,(rear+1)%maxSize=front的话,证明队满。rear=front的话,证明队空。
- 有元素出队的情况:front=1,rear=3
- 例如数组arr[5]实时情况为:{0,2,3,0,0},队头元素arr[0]出队了,队尾元素arr[2]=3
解释:每一次pop队头元素,front++,上述情况如果2,3再依次出队,front=rear=3,队空了。
改进:元素出队front=(front+1)%maxSize
循环队列长度计算公式:(rear-front+maxSize)%maxSize
{0,2,3,0,0}:front=1,rear=3,size=(3-1+5)%5=2
{6,0,3,4,5}:front=2,rear=1,size=(1-2+5)%5=4
代码实现:
/**
* 循环队列,队列元素存到数组中
*/
import java.util.Scanner;
public class queue3 {
int[] data;
int maxSize;
static int front=0;
static int rear=0;
queue3(){}
queue3(int n){
maxSize=n+1;
data = new int[maxSize];
}
String push(int x){
if((rear+1)%maxSize==front){
return "full";
}else{
data[rear]=x;
rear=(rear+1)%maxSize;
return "";
}
}
//注意Object返回值类型
Object pop(){
if(!(rear==front)){
int str = data[front];
front=(front+1)%maxSize;
return str;
}else{ return "empty"; }
}
//返回队头元素
Object front(){
if(!(rear==front)){
return data[front];
}else{
return "empty";
}
}
int queueLength(){
return (rear-front+maxSize)%maxSize;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入循环队列大小和操作次数(空格分开)");
String str = sc.nextLine();
String[] strArr = str.split(" ");
queue3 q = new queue3(Integer.parseInt(strArr[0]));
int i = Integer.parseInt(strArr[1]);
for(;i>0;i--){
String str2 = sc.nextLine();
String[] strArr2 = str2.split(" ");
switch(strArr2[0]){
case "push":
str2=q.push(Integer.parseInt(strArr2[1]));
if(str2.equals("full")){
System.out.println(str2);
}
break;
case "pop":
System.out.println(q.pop());
break;
case "front":
System.out.println(q.front());
break;
}
}
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)