Java - 可循环队列
队列是一种特殊的线性表,是一种先进先出的数据结构。只允许在表的前端进行删除操作,在表的后端进行插入操作。进行插入操作的端称为队尾,进行删除操作的端称为队头。队列中没有元素时,称为空队列。
简单的循环队列实现比较容易,队头获取数据、队头弹出获取数据,队尾插入数据。下面来研究一下可以无限循环使用的队列。思路如下:
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 - 可循环队列的更多相关文章
- atitit. java queue 队列体系and自定义基于数据库的队列总结o7t
atitit. java queue 队列体系and自定义基于数据库的队列总结o7t 1. 阻塞队列和非阻塞队列 1 2. java.util.Queue接口, 1 3. ConcurrentLink ...
- lesson2:java阻塞队列的demo及源码分析
本文向大家展示了java阻塞队列的使用场景.源码分析及特定场景下的使用方式.java的阻塞队列是jdk1.5之后在并发包中提供的一组队列,主要的使用场景是在需要使用生产者消费者模式时,用户不必再通过多 ...
- Java消息队列-Spring整合ActiveMq
1.概述 首先和大家一起回顾一下Java 消息服务,在我之前的博客<Java消息队列-JMS概述>中,我为大家分析了: 消息服务:一个中间件,用于解决两个活多个程序之间的耦合,底层由Jav ...
- java 数据结构 队列的实现
java 数据结构队列的代码实现,可以简单的进行入队列和出队列的操作 /** * java数据结构之队列的实现 * 2016/4/27 **/ package cn.Link; import java ...
- MinerQueue.java 访问队列
MinerQueue.java 访问队列 package com.iteye.injavawetrust.miner; import java.util.HashSet; import java.ut ...
- Java操作队列
Java操作队列 常见的几种模式: 1 简单队列simple 模型:(p + 队列 + c) P:生产者producer,将消息发送到队列 红色:消息队列 C:消费者consumer,从队列消费消 ...
- 数据结构与算法Java描述 队列
package com.cjm.queue; /** * 数据结构与算法Java实现 队列 * * @author 小明 * */ public class Myqueue { private Nod ...
- 细说并发5:Java 阻塞队列源码分析(下)
上一篇 细说并发4:Java 阻塞队列源码分析(上) 我们了解了 ArrayBlockingQueue, LinkedBlockingQueue 和 PriorityBlockingQueue,这篇文 ...
- Java阻塞队列(BlockingQueue)实现 生产者/消费者 示例
Java阻塞队列(BlockingQueue)实现 生产者/消费者 示例 本文由 TonySpark 翻译自 Javarevisited.转载请参见文章末尾的要求. Java.util.concurr ...
随机推荐
- Unknown column '字段名' in 'field list' 错误解决方案
当后台报这个错误的时候,说明实体类中的字段名出错了,解决方案: 1,检查数据库中的字段名与实体类中的字段名是否一致,特别要注意单词字母, 2,检查数据库中的字段是否与实体类中的字段一致.比如数据库中没 ...
- vue-loading图
父组件给子组件src地址: columns(){ return [ {'title': '图片', 'key': 'img', render(h, {row}){ return h(LoadingIm ...
- 一种移动端position:absolute布局:
一种移动端position:absolute布局: 1.他父级不需要加上 position:relative; 如果父级不是不是body,则加position:absolute; 2.红色加量部分 ...
- java 中 get post
package wzh.Http; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStr ...
- spring ioc aop 理解
OC,依赖倒置的意思,所谓依赖,从程序的角度看,就是比如A要调用B的方法,那么A就依赖于B,反正A要用到B,则A依赖于B.所谓倒置,你必须理解如果不倒置,会怎么着,因为A必须要有B,才可以调用B,如果 ...
- JVM学习(二):垃圾回收
我刚工作的时候问一个前辈,我们能针对JVM做出什么样的优化.前辈说,我们系统现在的性能并不需要调优,用默认的配置就能满足现在的需求了.我又问,那你为什么要看JVM相关的书呢?前辈微微一笑,悠悠地来了句 ...
- centos7重启网卡报Job for network.service failed because...错误
解决: [root@mina0 hadoop]# systemctl stop NetworkManager[root@mina0 hadoop]# systemctl disable Network ...
- 第九章·Logstash深入-Logstash配合rsyslog收集haproxy日志
rsyslog介绍及安装配置 在centos 6及之前的版本叫做syslog,centos 7开始叫做rsyslog,根据官方的介绍,rsyslog(2013年版本)可以达到每秒转发百万条日志的级别, ...
- SQL语句复习【专题二】
SQL语句复习[专题二] 单行函数(日期.数学.字符串.通用函数.转换函数)多行函数.分组函数.多行数据计算一个结果.一共5个.sum(),avg(),max(),min(),count()分组函数 ...
- 原创:(一)TCP/IP学习笔记之概述
端到端论点和命运共享其实不应该在底层,差错控制应该在应用程序附近来实现.这是因为考虑了连接,而不是传输的准确,因为差错可以根据某些算法(通信中的滤波等)来恢复,不过在大面积网络出现问题的时候有必要进行 ...