队列是一种特殊的线性表,是一种先进先出的数据结构。只允许在表的前端进行删除操作,在表的后端进行插入操作。进行插入操作的端称为队尾,进行删除操作的端称为队头。队列中没有元素时,称为空队列。

简单的循环队列实现比较容易,队头获取数据、队头弹出获取数据,队尾插入数据。下面来研究一下可以无限循环使用的队列。思路如下:

1、数据结构

int[] elements:底层采用数组实现,用来存储队列的所有元素;

maxSize:数组最大容量;

first:队头索引属性;

size:队列有效元素的个数;

1,2,3,4,5

2、算法

这里采用最大容量为5的队列来说明,即maxSize设为5。

(1) 第一次使用队列时,依次添加5个元素:1,2,3,4,5,first指向1,size 大小为5,maxSize为5。

1,2,3,4,5

算法很简单:添加1时,各种为空、队列已满的判断条件暂时省掉;

add(int value) {

if (size == 0) {

first = 0;

}

elements[size++] = value;

}

(2) 调用2次pop()方法弹出获取队列元素,此时队列数据结构如下:

1,2,3,4,5

size为3,first指向3,maxSize始终为5。

pop() {

size--;

return elements[first++];

}

(3) 此时我们再向队列添加元素6、7,此时队列数据结构如下:

1,2,3,4,5

6,7,3,4,5

访问的顺序应该为:3, 4, 5, 6, 7,其中size为5,first指向3。此时步骤1、2的算法明显不支持数组的循环使用,我们需要利用取模来循环添加数据到数组,具体算法如下:

public class MyQueue {

    /**
* 底层数组
*/
private int[] elements; /**
* 队列最大容量
*/
private int maxSize; /**
* 队列头索引
*/
private int first; /**
* 队列有效元素的个数
*/
private int size; public MyQueue(int maxSize) {
this.maxSize = maxSize;
elements = new int[maxSize];
first = -1;
size = 0;
} /**
* 添加元素
*
* @param value
*/
public void add(int value) {
if (isFull()) {
throw new RuntimeException("队列已满。");
}
if (isEmpty()) {
first = 0;
}
// 队列未满但是(first + size >= maxSize)时,说明数组elements的first索引之后所有位置已填满,
// first索引之前有空位置可以插入元素, 新增元素插入位置算法为:(first + size) % maxSize。
if (first + size >= maxSize) {
elements[(first + size) % maxSize] = value;
} else {
elements[first + size] = value;
}
size++;
} /**
* 获取队列元素,只能取队列头,弹出式获取。
*
* @return
*/
public int pop() {
if (isEmpty()) {
throw new RuntimeException("队列为空。");
}
size--;
// first 索引指向maxSize - 1时,即first已到达数组最后的位置,则弹出之后需将first指向第1个元素,
// 实现数组循环使用
if (first == maxSize -1) {
int tmp = elements[first];
first = 0;
return tmp;
} else {
return elements[first++];
}
} /**
* 获取元素,不弹出
*
* @return
*/
public int peek() {
if (isEmpty()) {
throw new RuntimeException("队列为空。");
}
return elements[first];
} public boolean isFull() {
return size == maxSize;
} public boolean isEmpty() {
return size <= 0;
} public void display() {
if (isEmpty()) {
System.out.println("Queue is empty.");
return;
}
StringBuilder str = new StringBuilder();
for (int i = first; i < first + size; i++) {
if (i >= maxSize) {
str.append(elements[i % maxSize] + ", ");
} else {
str.append(elements[i] + ", ");
}
}
System.out.println(str.substring(0, str.length() - 2));
} public int size() {
return size;
}
}

Java - 可循环队列的更多相关文章

  1. atitit. java queue 队列体系and自定义基于数据库的队列总结o7t

    atitit. java queue 队列体系and自定义基于数据库的队列总结o7t 1. 阻塞队列和非阻塞队列 1 2. java.util.Queue接口, 1 3. ConcurrentLink ...

  2. lesson2:java阻塞队列的demo及源码分析

    本文向大家展示了java阻塞队列的使用场景.源码分析及特定场景下的使用方式.java的阻塞队列是jdk1.5之后在并发包中提供的一组队列,主要的使用场景是在需要使用生产者消费者模式时,用户不必再通过多 ...

  3. Java消息队列-Spring整合ActiveMq

    1.概述 首先和大家一起回顾一下Java 消息服务,在我之前的博客<Java消息队列-JMS概述>中,我为大家分析了: 消息服务:一个中间件,用于解决两个活多个程序之间的耦合,底层由Jav ...

  4. java 数据结构 队列的实现

    java 数据结构队列的代码实现,可以简单的进行入队列和出队列的操作 /** * java数据结构之队列的实现 * 2016/4/27 **/ package cn.Link; import java ...

  5. MinerQueue.java 访问队列

    MinerQueue.java 访问队列 package com.iteye.injavawetrust.miner; import java.util.HashSet; import java.ut ...

  6. Java操作队列

    Java操作队列 常见的几种模式:   1 简单队列simple 模型:(p + 队列 + c) P:生产者producer,将消息发送到队列 红色:消息队列 C:消费者consumer,从队列消费消 ...

  7. 数据结构与算法Java描述 队列

    package com.cjm.queue; /** * 数据结构与算法Java实现 队列 * * @author 小明 * */ public class Myqueue { private Nod ...

  8. 细说并发5:Java 阻塞队列源码分析(下)

    上一篇 细说并发4:Java 阻塞队列源码分析(上) 我们了解了 ArrayBlockingQueue, LinkedBlockingQueue 和 PriorityBlockingQueue,这篇文 ...

  9. Java阻塞队列(BlockingQueue)实现 生产者/消费者 示例

    Java阻塞队列(BlockingQueue)实现 生产者/消费者 示例 本文由 TonySpark 翻译自 Javarevisited.转载请参见文章末尾的要求. Java.util.concurr ...

随机推荐

  1. CF505E Mr. Kitayuta vs. Bamboos

    cf luogu 要使得最高的柱子高度最小,考虑二分这个高度,那么剩下的就是要指定一个操作方案,使得最终每个柱子高度\(\le mid\) 因为有个柱子高度不会\(<0\)的限制,所以正着模拟不 ...

  2. 在Markdown中写公式块

    Markdown是一种可以使用普通文本编辑器编写的标记语言,通过简单的标记语法,它可以使普通文本内容具有一定的格式. Markdown中的公式语法是遵循LaTex语法的 $ sum = \sum_{i ...

  3. MySQL的左连接查询,只取出最大的一条数据

    今天有个需求,是通过两张表进行查询.一对多的关系.通过一个主键,取出其中的一条.开始以为还好,直接用用了left join on进行查询.却发现了问题所在.其他的好弄.开始的写法借鉴这篇博客:http ...

  4. 八,kubernetes集群存储卷基础。

    目录 存储卷 存储的分类 emptyDir 测试及使用 hostpath实例 Pod测试挂在共享NFS 写测试清单 测试 pv, pvc 创建几个PV 创建测试的Pod 和 PVC 存储卷 pod运行 ...

  5. C++面试高频题

    作者:守望者1028链接:https://www.nowcoder.com/discuss/55353来源:牛客网 面试高频题: 校招过程中参考过牛客诸位大佬的面经,但是具体哪一块是参考谁的我也忘记了 ...

  6. 线上MYSQL同步报错故障处理总结(转)

    前言 在发生故障切换后,经常遇到的问题就是同步报错,数据库很小的时候,dump完再导入很简单就处理好了,但线上的数据库都150G-200G,如果用单纯的这种方法,成本太高,故经过一段时间的摸索,总结了 ...

  7. Task扩展方法取消操作

    /// <summary> /// 任务扩展,传入取消操作 /// </summary> public static class TaskExtensionDemo { //因 ...

  8. c++字符和字符串转整数类型及大小端

    在网络传输中,很多数据都是按字节传递而不是字符串.最近就遇到了这个问题,在刚开始学c语言时都没有问题,可能太久不用了,记录一下 在报中文,用2个字节hex码来表示报文正文长度,什么是hex码呢 就是1 ...

  9. Numpy 文件读写

    NumPy 文件读写主要有二进制的文件读写和文件列表形式的数据读写两种形式 二进制的文件读写 save  np.save ("./文件名", 数组名):以二进制的格式保存数据 保存 ...

  10. JAVA面试/笔试经典题

    1.short s1 = 1; s1 = s1 + 1;有什么错? short s1 = 1; s1 += 1;有什么错? 对于short s1 = 1; s1 = s1 + 1; 由于s1+1运算时 ...