1.使用场景

银行排队的案例:

2.队列介绍

队列是一个有序列表,可以用数组或是链表来实现。

遵循先入先出的原则

  • 先存入队列的数据,要先取出。
  • 后存入的要后取出

示意图:(使用数组模拟队列示意图)

3.实现方式1:数组模拟队列

思路分析

队列本身是有序列表,若使用数组的结构来存储队列的数据,则队列数组的声明如下图, 其中 maxSize 是该队列的最大容量。

  • front 是队列最前元素之前一个位置【不含最前】
  • rear 是队列最后元素 【含最后】
  • 插入队列,判断是否已满,将尾指针往后移:rear++,然后插入arr[rear]
  • 移出队列,判断是否为空,将前指针往后移:front++,然后移出arr[front]
  • 队列为空判断条件:当front == rear 【空】
  • 队列是否满判断条件:rear == maxSize - 1【队列满】

代码实现

// 使用数组模拟队列-编写一个ArrayQueue类
class ArrayQueue {
private int maxSize; // 表示数组的最大容量
private int front; // 队列头
private int rear; // 队列尾
private int[] arr; // 该数据用于存放数据, 模拟队列 // 创建队列的构造器
public ArrayQueue(int arrMaxSize) {
maxSize = arrMaxSize;
arr = new int[maxSize];
front = -1; // 指向队列头部,分析出front是指向队列头的前一个位置.
rear = -1; // 指向队列尾,指向队列尾的数据(即就是队列最后一个数据)
} // 判断队列是否满
public boolean isFull() {
return rear == maxSize - 1;
} // 判断队列是否为空
public boolean isEmpty() {
return rear == front;
} // 添加数据到队列
public void addQueue(int n) {
// 判断队列是否满
if (isFull()) {
System.out.println("队列满,不能加入数据~");
return;
}
rear++; // 让rear 后移
arr[rear] = n;
} // 获取队列的数据, 出队列
public int getQueue() {
// 判断队列是否空
if (isEmpty()) {
// 通过抛出异常
throw new RuntimeException("队列空,不能取数据");
}
front++; // front后移
return arr[front]; } // 显示队列的所有数据
public void showQueue() {
// 遍历
if (isEmpty()) {
System.out.println("队列空的,没有数据~~");
return;
}
for (int i = 0; i < arr.length; i++) {
System.out.printf("arr[%d]=%d\n", i, arr[i]);
}
} // 显示队列的头数据, 注意不是取出数据
public int headQueue() {
// 判断
if (isEmpty()) {
throw new RuntimeException("队列空的,没有数据~~");
}
return arr[front + 1];
}
}

出现问题

目前数组不能复用,用一次就用不了了

优化方式:将数组模拟成环形队列

4. 数组模拟环形队列

思路:

1.front变量的含义做调整:front指向队列的第一个元素,即arr[front]就是队列的第一个元素

2.rear变量的含义做调整:rear指向队列的最后一个元素的后一个元素,因为希望空出一个空间作为约定(队列实际容量=maxSize-1,理解为防止指向超出数组范围的地方报错)

3.当队列满时,条件是:(rear + 1) % maxSize == front [满] 

4.当队列空时,条件是:rear == front [空]

5.队列中有效数据的个数:(rear + maxSize - front) % maxSize

6.插入队列时,判断队满,先插入队列arr[rear],然后rear++

7.移出队列时,判断队空,先移出队列arr[front],然后front++

代码实现

class CircleArray {
private int maxSize; // 表示数组的最大容量
//front 变量的含义做一个调整: front 就指向队列的第一个元素, 也就是说 arr[front] 就是队列的第一个元素
//front 的初始值 = 0
private int front;
//rear 变量的含义做一个调整:rear 指向队列的最后一个元素的后一个位置. 因为希望空出一个空间做为约定.
//rear 的初始值 = 0
private int rear; // 队列尾
private int[] arr; // 该数据用于存放数据, 模拟队列 public CircleArray(int arrMaxSize) {
maxSize = arrMaxSize;
arr = new int[maxSize];
} // 判断队列是否满
public boolean isFull() {
return (rear + 1) % maxSize == front;
} // 判断队列是否为空
public boolean isEmpty() {
return rear == front;
} // 添加数据到队列
public void addQueue(int n) {
// 判断队列是否满
if (isFull()) {
System.out.println("队列满,不能加入数据~");
return;
}
//直接将数据加入
arr[rear] = n;
//将 rear 后移, 这里必须考虑取模
rear = (rear + 1) % maxSize;
} // 获取队列的数据, 出队列
public int getQueue() {
// 判断队列是否空
if (isEmpty()) {
// 通过抛出异常
throw new RuntimeException("队列空,不能取数据");
}
// 这里需要分析出 front是指向队列的第一个元素
// 1. 先把 front 对应的值保留到一个临时变量
// 2. 将 front 后移, 考虑取模
// 3. 将临时保存的变量返回
int value = arr[front];
front = (front + 1) % maxSize;
return value; } // 显示队列的所有数据
public void showQueue() {
// 遍历
if (isEmpty()) {
System.out.println("队列空的,没有数据~~");
return;
}
// 思路:从front开始遍历,遍历多少个元素
// 动脑筋
for (int i = front; i < front + size() ; i++) {
System.out.printf("arr[%d]=%d\n", i % maxSize, arr[i % maxSize]);
}
} // 求出当前队列有效数据的个数
public int size() {
// rear = 2
// front = 1
// maxSize = 3
return (rear + maxSize - front) % maxSize;
} // 显示队列的头数据, 注意不是取出数据
public int headQueue() {
// 判断
if (isEmpty()) {
throw new RuntimeException("队列空的,没有数据~~");
}
return arr[front];
}
}

Java数据结构之队列(Queue)的更多相关文章

  1. Java数据结构之队列的实现以及队列的应用之----简单生产者消费者应用

    Java数据结构之---Queue队列 队列(简称作队,Queue)也是一种特殊的线性表,队列的数据元素以及数据元素间的逻辑关系和线性表完全相同,其差别是线性表允许在任意位置插入和删除,而队列只允许在 ...

  2. Java中的队列Queue,优先级队列PriorityQueue

    队列Queue 在java5中新增加了java.util.Queue接口,用以支持队列的常见操作.该接口扩展了java.util.Collection接口. Queue使用时要尽量避免Collecti ...

  3. Java 中的队列 Queue

    一.队列的定义 我们都知道队列(Queue)是一种先进先出(FIFO)的数据结构,Java中定义了java.util.Queue接口用来表示队列.Java中的Queue与List.Set属于同一个级别 ...

  4. Java线程安全队列Queue实现原理

    原文链接:https://www.cnblogs.com/DreamRecorder/p/9223016.html 在Java多线程应用中,队列的使用率很高,多数生产消费模型的首选数据结构就是队列.J ...

  5. Python与数据结构[2] -> 队列/Queue[0] -> 数组队列的 Python 实现

    队列 / Queue 数组队列 数组队列是队列基于数组的一种实现,其实现类似于数组栈,是一种FIFO的线性数据结构. Queue: <--| 1 | 2 | 3 | 4 | 5 |<-- ...

  6. 数据结构:队列queue 函数push() pop size empty front back

    队列queue: push() pop() size() empty() front() back() push()  队列中由于是先进先出,push即在队尾插入一个元素,如:可以输出:Hello W ...

  7. 数据结构之队列(queue)

    队列介绍 1.队列是一个有序列表,可以用数组或是链表来实现. 2.遵循先入先出的原则.即:先存入队列的数据,要先取出.后存入的要后取出. 应用场景 比如某某银行叫号系统: 数组模拟队列 队列本身是有序 ...

  8. java数据结构之队列

    队列概述队列是一种特殊的线性表,它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作.进行插入操作的端称为队尾,进行删除操作的端称为队头.队列中没有元素时,称为空队列.– ...

  9. 算法与数据结构基础 - 队列(Queue)

    队列基础 队列具有“先进先出”的特点,用这个特点我们可以用它来处理时间序列相关或先后次序相关的问题,例如 LeetCode题目 933. Number of Recent Calls,时间复杂度O(1 ...

随机推荐

  1. qt04 中文显示问题

    sockettools识别GB2312,接收qt server 数据时 QByteArray ba = str.toLocal8Bit(); char *ss = ba.data(); obj-> ...

  2. [易学易懂系列|golang语言|零基础|快速入门|(二)]

    现在我们来写代码,首先我们要新建一个项目. 新建项目: 点击:File>>New>>Project...如下图: 在New Project窗口,Location:输入:“goP ...

  3. GUI学习之二十九—QInputDialog学习总结

    最后一种对话框是QInputDialog,,用来提供个输入的窗口. 一常用的静态方法 由于输入的类型不同,QInputDialog分为多种静态方法使用 #有步长调节器的整形数据,step为步长调节器的 ...

  4. nginx的配置和基本参数说明

    16 117 118 119 120 121 122 123 #运行用户 user nobody; #启动进程,通常设置成和cpu的数量相等 worker_processes  1;   #全局错误日 ...

  5. Python pdfkit

    序言 住在地下室的人,依然有仰望星空的权利. pdfkit python使用pdfkit中,如果使用pdfkit.fromurl 或者pdfkit.fromstring等,就会出现上述错误.而且如果你 ...

  6. 51Nod 1277 字符串中的最大值 ( KMP && DP )

    题意 : 一个字符串的前缀是指包含该字符第一个字母的连续子串,例如:abcd的所有前缀为a, ab, abc, abcd.给出一个字符串S,求其所有前缀中,字符长度与出现次数的乘积的最大值.例如:S ...

  7. [转]SQLServer : EXEC和sp_executesql的区别

    MSSQL为我们提供了两种动态执行SQL语句的命令,分别是EXEC和sp_executesql.通常,sp_executesql则更具有优势,它提供了输入输出接口,而EXEC没有.还有一个最大的好处就 ...

  8. BigDecimal.setScale 处理java小数点[转]

    BigDecimal.setScale()方法用于格式化小数点setScale(1)表示保留一位小数,默认用四舍五入方式 setScale(1,BigDecimal.ROUND_DOWN)直接删除多余 ...

  9. vim推荐的光标移动配置文件?

    http://roclinux.cn/?p=1466 inoremap jk inoremap ... 参考较好的vim设置文件 : 共享粘贴板: set clipboard+=unnamed 除了映 ...

  10. ReentrantLock 源码分析

    ReentrantLock 1)ReentrantLock 类实现了和 synchronized 一样的内存语义,同时该类提供了更加灵活多样的可重入互斥锁定操作. 2)ReentrantLock 实例 ...