队列 (先入先出原则)
-
如果说链表和顺序表是对数据的存取位置的组织方式,那么队列就是一种对于存取方式限制的组织方式。换一种方式描述的话就是,队列既可以采用链表来表示,也可以采用数组(线性表)来表示,我们限制的是对于存放数据的存取方式。
-
出从队首出,入插入队尾
-
队列:只允许在一端进行插入操作,而另一端进行删除操作的线性表。
-
空队列:不含任何数据元素的队列。
-
允许插入(也称入队、进队)的一端称为队尾,允许删除(也称出队)的一端称为队头。
例题:
银行排队问题, 银行只有两个接待窗口,VIP 窗口和普通窗口,VIP 用户进入 VIP 用户窗口,剩下的进入普通窗口排队。
现在有以下输入:
第一行 M 次操作(M<1000) 第二行 到 第M+1行 输入操作 格式: IN name V OUT V IN name2 N OUT N 即 第一个字符串为操作 是IN进入排队和OUT 出队 IN 排队 跟着两个字符串为姓名和权限V或N OUT 为出队即完成操作,V和N代表那个窗口完成了操作 输出:M次操作后V队列和N队列中姓名,先输出V队列后输出N队列。 样例: 输入: 5 IN xiaoming N IN Adel V IN laozhao N OUT N IN CLZ V 输出: Adel CLZ laozhao
分析思路:
- 第一步,创建两个队列,以及两个队列的首尾指针
- 第二步,我们要写入队函数:按照队列的定义使用尾指针模拟即可;设置 Type 位来表示是哪一个队列;Type为V,那么Name进入V队列;Type为N,那么Name进入N队列;
- 第三步,我们要写出队函数:按照队列的定义使用头指针模拟即可;仍需设置 Type 位来表示是哪一个队列
- 第四步,写出获取队头元素的代码,队列我们只关心谁排在第一个;按照队列的定义使用头指针模拟即可;仍需设置 Type 位来表示是哪一个队列;
- 主函数代码:
输入M
循环M次:
输入操作符OP
OP为IN,则输入name和Type
OP为Out,则输入Type
根据执行OP执行in或out操作
若队列V不为空,执行以下操作:
输出队首元素,队首出队
直到为空为止
若队列N不为空,执行以下操作:
输出队首元素,队首出队
直到为空为止
代码实现(用数组模拟队列):
package 队列;
import java.util.Scanner;
public class Quque_01 {
//1. 创建两个队列,以及两个队列的首尾指针
static String Vqueue[] = new String[1000]; // V队列
static int Vhead = 0; // 首指针
static int Vtail = 0; // 尾指针
static String Nqueue[] = new String[1000]; // N队列
static int Nhead = 0; // 首指针
static int Ntail = 0; // 尾指针
//2.入队函数: 尾指针模拟 设置 Type 位来表示是哪一个队列
static void in(String name,String type) {
if(type.contains("V")) {
Vqueue[Vtail++] = name;
}
else {
Nqueue[Ntail++] = name;
}
}
//3.出队函数:头指针模拟 设置 Type 位来表示是哪一个队列
static boolean out(String type) {
if(type.contains("V")) {
//先判断队列是否为空 为空的条件就是首尾指针相等
if(Vhead == Vtail) {
return false;
}
else {
Vhead++;
return true;
}
}
else {
if(Nhead == Ntail) {
return false;
}
else {
Nhead++;
return true;
}
}
}
//4.获取队头元素
static String getHead(String type) {
if(type.contains("V")) {
return Vqueue[Vhead];
}
else {
return Nqueue[Nhead];
}
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
//输入操作次数
int m = scanner.nextInt();
while(m>0) {
m--;
// 输入操作符 若为IN,则输入name和Type; 若为Out,则输入Type
String opString = scanner.next();
if(opString.contains("IN")){
String name = scanner.next();
String type = scanner.next();
in(name, type);
}
else {
String type = scanner.next();
out(type);
}
}
//若队列V不为空,输出队首元素,队首出队,直到为空为止
String v = getHead("V");
while(out("V")) {//此处显示了出队函数中的功能:判断是否空 头指针后移 以及返回类型是boolean
System.out.println(v);
v = getHead("V");//获取下一个队首元素
}
//若队列N不为空,输出队首元素,队首出队,直到为空为止
String n= getHead("N");
while(out("N")) {
System.out.println(n);
n = getHead("N");
}
}
}
使用java中已经定义好的队列数据结构(用数组模拟是为了更好地了解队列的实现原理,以后用到队列时,直接调用Queue)
定义方式:
Queue<String> queue = new LinkedList<String>();
部分成员函数(包括继承的):
add(): 增加一个元索,如果队列已满,则抛出一个异常 |
---|
remove():移除并返回队列头部的元素,如果队列为空,则抛出一个异常 |
element():返回队列头部的元素,如果队列为空,则抛出一个异常 |
offer():添加一个元素并返回 true,如果队列已满,则返回 false |
put(): 添加一个元素, 如果队列满,则阻塞 |
take(): 移除并返回队列头部的元素,如果队列为空,则阻塞 |
size(): 返回队列长度。 |
peek(): 返回队列头部的元素,如果队列为空,则返回 null |
poll(): 移除并返问队列头部的元素,如果队列为空,则返回 null |
代码实现:
package 队列;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
public class Quque_02 {
// 1. 创建两个队列
static Queue<String> vqueue = new LinkedList<>();
static Queue<String> nqueue = new LinkedList<>();
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// 输入操作次数
int m = scanner.nextInt();
while (m > 0) {
m--;
// 输入操作符 若为IN,则输入name和Type; 若为Out,则输入Type
String opString = scanner.next();
if (opString.contains("IN")) {
String name = scanner.next();
String type = scanner.next();
if (type.contains("V")) {
vqueue.offer(name);// offer():添加一个元素并返回 true,如果队列已满,则返回 false
} else {
nqueue.offer(name);
}
} else {
String type = scanner.next();
if (type.contains("V")) {
vqueue.poll();// poll(): 移除并返问队列头部的元素,如果队列为空,则返回 null
} else {
nqueue.poll();
}
}
}
//输出:
//若队列V不为空,输出队首元素,队首出队,直到为空为止
while(vqueue.size()!=0) {
System.out.println(vqueue.poll());
}
//若队列N不为空,输出队首元素,队首出队,直到为空为止
while(nqueue.size()!=0) {
System.out.println(nqueue.poll());
}
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现