Java实现一个简单的循环队列
在某些时候,我们不能被要求像数组一样可以使用索引随机访问,而是需要被限制顺序处理业务,今天介绍一种先进先出(FIFO)的线性数据结构:队列,
当然,还有后进先出(LIFO)的处理方式,即为栈(后续有时间再另说)。
先进先出的数据结构:(以下图片非原创,来自网络)
在 FIFO 数据结构中,将首先处理添加到队列中的第一个元素
。
如上图所示,队列是典型的 FIFO 数据结构。插入(insert)操作也称作入队(enqueue),新元素始终被添加在队列的末尾
。 删除(delete)操作也被称为出队(dequeue)。 你只能移除第一个元素
。
低效的队列实现:(此小段内容非原创,来自网络)
为了实现队列,我们可以使用动态数组和指向队列头部的索引。
如上所述,队列应支持两种操作:入队和出队。入队会向队列追加一个新元素,而出队会删除第一个元素。 所以我们需要一个索引来指出起点。
这是一个供你参考的实现:
// "static void main" must be defined in a public class.
class MyQueue {
// store elements
private List<Integer> data;
// a pointer to indicate the start position
private int p_start;
public MyQueue() {
data = new ArrayList<Integer>();
p_start = 0;
}
/** Insert an element into the queue. Return true if the operation is successful. */
public boolean enQueue(int x) {
data.add(x);
return true;
};
/** Delete an element from the queue. Return true if the operation is successful. */
public boolean deQueue() {
if (isEmpty() == true) {
return false;
}
p_start++;
return true;
}
/** Get the front item from the queue. */
public int Front() {
return data.get(p_start);
}
/** Checks whether the queue is empty or not. */
public boolean isEmpty() {
return p_start >= data.size();
}
};
public class Main {
public static void main(String[] args) {
MyQueue q = new MyQueue();
q.enQueue(5);
q.enQueue(3);
if (q.isEmpty() == false) {
System.out.println(q.Front());
}
q.deQueue();
if (q.isEmpty() == false) {
System.out.println(q.Front());
}
q.deQueue();
if (q.isEmpty() == false) {
System.out.println(q.Front());
}
}
}
缺点
上面的实现很简单,但在某些情况下效率很低。 随着起始指针的移动,浪费了越来越多的空间。 当我们有空间限制时,这将是难以接受的。
让我们考虑一种情况,即我们只能分配一个最大长度为 5 的数组。当我们只添加少于 5 个元素时,我们的解决方案很有效。 例如,如果我们只调用入队函数四次后还想要将元素 10 入队,那么我们可以成功。
但是我们不能接受更多的入队请求,这是合理的,因为现在队列已经满了。但是如果我们将一个元素出队呢?
实际上,在这种情况下,我们应该能够再接受一个元素。
循环队列的实现(原创)
上面我们提供了一种简单但低效的队列实现。
更有效的方法是使用循环队列。 具体来说,我们可以使用固定大小的数组
和两个指针
来指示起始位置(head)和结束位置(tail)。 目的是重用
我们之前提到的被浪费的存储
。
循环队列的实现最为关键是要用检测队列空(empty)与满(full)的策略,以下附上原码和输出结果。
1、抽象了一个队列的简单接口(ICircleQueue)
package com.chengcai.util;
/**
* Created by chengcai on 2019/3/7.
*/
public interface ICircleQueue<E> {
boolean enQueue(E e);
E deQueue();
boolean isFull();
boolean isEmpty();
CircleQueueEntity getQueueEntity();
int getQueueItemSize();
int getRequestElementIndex();
}
2.抽像类(AbstractComDataSet),暂作了定义队列长度,留个扩展
public abstract class AbstractComDataSet {
static int QueueBufferSize=10;
} 3.队列属性类(CircleQueueEntity)
package com.chengcai.util;
import java.util.ArrayList;
import java.util.List;
/**
* Created by chengcai on 2019/3/7.
*/
public class CircleQueueEntity<T> {
private int head;
private int tail;
private int index;
private int size;
private List<T> list = null;
private List<T> deList=null; public CircleQueueEntity() {
head = 0;
tail = 0;
index = 0;
size = AbstractComDataSet.QueueBufferSize;
ConstructList();
}
void ConstructList()
{
list=new ArrayList<T>();
deList=new ArrayList<T>();
for (int i=0;i< size;i++)
{
list.add(null);
}
}
public void setHead(int pointer)
{
this.head=pointer;
}
public int getHead()
{
return this.head;
}
public void setTail(int pointer)
{
this.tail=pointer;
}
public int getTail()
{
return this.tail;
}
public void setIndex(int pointer)
{
this.index= pointer;
}
public int getIndex()
{
return this.index;
}
public int getSizeOnly()
{
return size;
}
public List<T> getListCollection()
{
return this.list;
}
public List<T> getDeListCollection(){ return this.deList;}
}
4.循环队列类(CircleQueue)
package com.chengcai.util;
import java.util.Iterator;
import java.util.List; /**
* Created by chengcai on 2019/3/7.
*/
public class CircleQueue<E> implements ICircleQueue<E>{
private CircleQueueEntity<E> entity=null;
private int requestElementIndex=0;
public CircleQueue()
{
entity=new CircleQueueEntity<E>();
} @Override
public boolean enQueue(E e)
{
if (isFull())
return false;
int index=entity.getIndex();
int tail=entity.getTail();
int size=entity.getSizeOnly();
if (tail>=size) {
entity.setTail(0);
tail=entity.getTail();
entity.setIndex(0);
index=entity.getIndex();
}
entity.getListCollection().set(entity.getTail(),e);
entity.setIndex(index + 1);
entity.setTail(tail + 1);
this.requestElementIndex++;
return true;
}
@Override
public E deQueue()
{
if (isEmpty())
return null;
int head =entity.getHead();
int size=entity.getSizeOnly();
E deQueueElement=entity.getListCollection().get(head);
entity.getDeListCollection().add(deQueueElement);
entity.getListCollection().set(head,null);
entity.setHead(head+1);
head=entity.getHead();
if (head>size-1)
{
entity.setHead(0);
}
return deQueueElement;
} @Override
public boolean isFull()
{
List<E> list=entity.getListCollection();
for(E obj:list)
{
if (obj==null)
return false;
}
return true;
} @Override
public boolean isEmpty()
{
List<E> list=entity.getListCollection();
boolean isnull=true;
for (E obj:list) {
if (obj!=null)
return false;
}
return isnull;
} @Override
public CircleQueueEntity getQueueEntity()
{
return entity;
}
@Override
public int getQueueItemSize(){
return entity.getListCollection().size();
} @Override
public int getRequestElementIndex()
{
return this.requestElementIndex;
}
public int getQueueElementCount()
{
int count=0;
Iterator it =entity.getListCollection().iterator();
while (it.hasNext())
{
if (it.next()!=null)
count++;
}
return count;
}
}
5.Main
package com.chengcai;
import com.chengcai.util.*;
public class Main { private static String enQueue(ICircleQueue q, int[] data)
{
StringBuilder sb =new StringBuilder();
String strTemp="";
boolean isSuccess =false;
int requestElementIndex=q.getRequestElementIndex(); sb.append("已成功入队:");
for (int i=requestElementIndex;i<data.length;i++)
{
isSuccess=q.enQueue(data[i]);
if (isSuccess) {
strTemp += Integer.toString(data[i]) + ",";
}
}
sb.append(strTemp);
return sb.toString();
} private static String waitQueue(ICircleQueue q, int[] data)
{
StringBuilder sb =new StringBuilder();
String strTemp="";
int requestElementIndex=q.getRequestElementIndex(); strTemp="正在排队的元素:";
for (int i=requestElementIndex;i<data.length;i++)
{
strTemp += Integer.toString(data[i]) + ",";
}
sb.append(strTemp);
return sb.toString();
} private static String deQueue(ICircleQueue q,int deQueueFlag)
{
StringBuilder sb =new StringBuilder();
String strTemp=""; sb.append("已成功出队(FIFO):");
for (int i=0;i<deQueueFlag;i++)
{
strTemp= strTemp + q.deQueue().toString();
strTemp += ",";
}
sb.append(strTemp);
return sb.toString();
} public static void main(String[] args) {
int[] data={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,20,21,22,23,24,25};
ICircleQueue q=new CircleQueue();
String strPrint;
strPrint="当前队列长度为:"+q.getQueueItemSize();
System.out.println(strPrint);
strPrint=enQueue(q,data);
System.out.println(strPrint);
strPrint=waitQueue(q,data);
System.out.println(strPrint);
strPrint=deQueue(q,3);
System.out.println(strPrint);
strPrint=enQueue(q,data);
System.out.println(strPrint);
strPrint=waitQueue(q,data);
System.out.println(strPrint);
strPrint=deQueue(q,8);
System.out.println(strPrint);
strPrint=enQueue(q,data);
System.out.println(strPrint);
strPrint=waitQueue(q,data)+"全部元素已入队列";
System.out.println(strPrint);
}
}
6.运行结果:
当前队列长度为:10
已成功入队:1,2,3,4,5,6,7,8,9,10,
正在排队的元素:11,12,13,14,15,20,21,22,23,24,25,
已成功出队(FIFO):1,2,3,
已成功入队:11,12,13,
正在排队的元素:14,15,20,21,22,23,24,25,
已成功出队(FIFO):4,5,6,7,8,9,10,11,
已成功入队:14,15,20,21,22,23,24,25,
正在排队的元素:全部元素已入队列
Java实现一个简单的循环队列的更多相关文章
- Java编程的逻辑 (61) - 内存映射文件及其应用 - 实现一个简单的消息队列
本系列文章经补充和完善,已修订整理成书<Java编程的逻辑>,由机械工业出版社华章分社出版,于2018年1月上市热销,读者好评如潮!各大网店和书店有售,欢迎购买,京东自营链接:http:/ ...
- 使用Java编写一个简单的Web的监控系统cpu利用率,cpu温度,总内存大小
原文:http://www.jb51.net/article/75002.htm 这篇文章主要介绍了使用Java编写一个简单的Web的监控系统的例子,并且将重要信息转为XML通过网页前端显示,非常之实 ...
- 使用JAVA写一个简单的日历
JAVA写一个简单的日历import java.text.DateFormat;import java.text.ParseException;import java.text.SimpleDateF ...
- Java实现一个简单的文件上传案例
Java实现一个简单的文件上传案例 实现流程: 1.客户端从硬盘读取文件数据到程序中 2.客户端输出流,写出文件到服务端 3.服务端输出流,读取文件数据到服务端中 4.输出流,写出文件数据到服务器硬盘 ...
- 使用 java 实现一个简单的 markdown 语法解析器
1. 什么是 markdown Markdown 是一种轻量级的「标记语言」,它的优点很多,目前也被越来越多的写作爱好者,撰稿者广泛使用.看到这里请不要被「标记」.「语言」所迷惑,Markdown 的 ...
- java:jsp: 一个简单的自定义标签 tld
java:jsp: 一个简单的自定义标签 tld 请注意,uri都是:http://www.tag.com/mytag,保持统一,要不然报错,不能访问 tld文件 <?xml version=& ...
- Java实现一个简单的网络爬虫
Java实现一个简单的网络爬虫 import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileWri ...
- BAT面试题:使用数组实现一个简单的阻塞队列
这道题是我亲身经历的一道大厂面试题,非常值得分享! 这道题可以分为两个步骤进行编码解答,第一步是基于数组实现一个队列,第二步是实现线程阻塞. 如果是基于数组实现栈的数据结构,那么我们只需要一个指针进行 ...
- Java写一个简单学生管理系统
其实作为一名Java的程序猿,无论你是初学也好,大神也罢,学生管理系统一直都是一个非常好的例子,初学者主要是用数组.List等等来写出一个简易的学生管理系统,二.牛逼一点的大神则用数据库+swing来 ...
随机推荐
- Django框架基础之Form组件
服务端假设所有用户提交的数据都是不可信任的,所以Django框架内置了form组件来验证用户提交的信息 form组件的2大功能: 1 验证(显示错误信息) 2 保留用户上次输入 ...
- Nacos环境搭建
先去下载↓↓↓↓ https://github.com/alibaba/nacos/releases 单机版 单机版主要为了测试,没啥意思,你下载一个zip包,然后解压,进入bin目录,双击 star ...
- 第八周java学习总结
学号 20175206 <Java程序设计>第八周学习总结 教材学习内容总结 第十五章:泛型与集合框架 主要内容 泛型 链表 堆栈 散列映射 树集 树映射 重点和难点 重点:泛型和集合的使 ...
- NFV-Bench A Dependability Benchmark for Network Function Virtualization Systems
文章名称:NFV-Bench A Dependability Benchmark for Network Function Virtualization Systems 发表时间:2017 期刊来源: ...
- 人生苦短,Let's Go目录
目录 GO语言系列(一)- 初识go语言 GO语言系列(二)- 基本数据类型和操作符 Go语言系列(三)- 基础函数和流程控制 GO语言系列(四)- 内置函数.闭包与高级数据类型 GO语言系列(五)- ...
- Linux命令_sed_2
2.替换(将包含"xxx"的行中的"yyy"替换成"zzz") 现有文件“replace_specified_contained_line” ...
- vue DES 加密
安装crypto-js cnpm install crypto-js --save 封装一个des.js ECB模式 import cryptoJs from 'crypto-js' // DES加密 ...
- RPC-dubbo基本使用
22.本地存根 消费者通过创建实现一个服务接口的实例,可以在执行远程调用前拿到远程调用的代理实例,进而可以在远程调用前.后添加一些操作,在出现异常后进行一些容错处理. 这个使用场景,可以调用前作数 ...
- H5_0005:JS判断域名和时间有效期的方法
(function () { var n = { c: function (t, e) { //console.log("c"); //把i(15)的d数组转换成字串 for (v ...
- avg 的使用
select * from emp where sal>(select avg(sal) as ssalfrom emp);--要求查询出高于公司平均工资的全部雇员信息