Code:

package dataStucture2.stackandqueue;

/**
* 循环队列
*
* @param <E>
*/
public class MyLoopQueue<E> implements Queue<E> { /*
* 成员变量:泛型数组、两个指向变量、循环队列个数size
*/
private E[] data;
private int front, tail;
private int size; // 有参构造,初始化数组容量大小,指向变量指向索引为0
public MyLoopQueue(int capacity) {
// 判断tail在front前一位时队列为满,为了达到用户要求的容量,要求capacity比默认大1,此时多出的一位用于判断队列为满
//实际长度:capacity+1 可用长度:capacity
data = (E[]) new Object[capacity + 1];
front = 0;
tail = 0;
size = 0;
} // 无参构造,默认容量为10
public MyLoopQueue() {
this(10);
} // 获取循环队列容量 ,1的存在为了判断队列为满,并不存储元素,此处减去
int getCapacity() {
//实际长度:capacity+1 可用长度:capacity
return data.length - 1;
} @Override
// front和tail指向同一个位置,循环队列为空
public boolean isEmpty() {
return front == tail;
} @Override
// 获得循环队列元素个数
public int getSize() {
return size;
} @Override
//入队
public void enqueue(E e) {
//首先判断队列是满,如果满了,进行扩容
if((tail + 1) % data.length == front){
resize(getCapacity() * 2);
}
//如果没满,入队
data[tail] = e;
tail = (tail + 1) % data.length;
size ++;
} @Override
//出队
public E dequeue() {
//首先判断队列是否为空,如果为空,抛出异常
if(isEmpty()){
throw new IllegalArgumentException(" Cannot dequeue from an empty queue ! ");
}
//如果不为空,出队
E ret = data[front];
data[front] = null;
front = (front + 1) % data.length;
size -- ;
//动态扩容
if(size == getCapacity() / 4 && getCapacity() / 2 != 0)
resize(getCapacity() / 2);
return ret;
} @Override
//获取队首元素
public E getFront() {
if(isEmpty()){
throw new IllegalAccessError("Queue is empty.");
}
return data[front];
} //循环队列动态扩容
private void resize(int newCapacity){
E[] newData = (E[])new Object[newCapacity +1];
for(int i = 0 ; i < size ; i ++){
//循环队列,%data.length为了防止越界
newData[i] = data[( i + front ) % data.length];
}
/**
* 此处错误:不应当每次扩容遍历都resize,遍历的目的是复制元素到新的数组,复制完了原数组指向新的数组完成扩容
*/
data = newData;
front = 0;
tail = size; } @Override
//打印循环队列
public String toString() { StringBuilder res = new StringBuilder();
res.append(String.format("Queue: size = %d , capacity = %d\n", size , getCapacity()));
res.append("front [");
//遍历循环队列,和resize中的循环遍历是两种方式,都可以达到母的
for(int i = front ; i != tail ; i = (i+1) % data.length){
res.append(data[i]);
if((i + 1) % data.length != tail){
res.append(", ");
}
}
res.append("] tail");
return res.toString();
} }

循环队列解决了普通队列出队复杂度为O(n)的问题

toString方法和resize方法中,遍历循环队列的异同

循环队列的简单时间复杂度分析:

三 基于Java数组手写循环队列的更多相关文章

  1. 三 基于Java动态数组手写队列

    手写队列: package dataStucture2.stackandqueue; import com.lt.datastructure.MaxHeap.Queue; import dataStu ...

  2. 二 基于java动态数组手写栈

    package dataStucture2.stack; import dataStucture2.array.MyDynamicArray; /** * 基于动态数组手写栈 * 设计时,栈中仅栈顶对 ...

  3. 使用java语言基于SMTP协议手写邮件客户端

    使用java语言基于SMTP协议手写邮件客户端 1. 说明 电子邮件是互联网上常见的应用,他是互联网早期的产品,直至今日依然受到广大用户的喜爱(在中国可能因为文化背景不同,电子邮件只在办公的时候常用) ...

  4. java 从零开始手写 RPC (05) reflect 反射实现通用调用之服务端

    通用调用 java 从零开始手写 RPC (01) 基于 socket 实现 java 从零开始手写 RPC (02)-netty4 实现客户端和服务端 java 从零开始手写 RPC (03) 如何 ...

  5. 基于MATLAB的手写公式识别(6)

    基于MATLAB的手写公式识别 2021-03-29 10:24:51 走通了程序,可以识别"心脑血管这几个字",还有很多不懂的地方. 2021-03-29 12:20:01 tw ...

  6. Atitit.提升软件稳定性---基于数据库实现的持久化 循环队列 环形队列

    Atitit.提升软件稳定性---基于数据库实现的持久化  循环队列 环形队列 1. 前言::选型(马) 1 2. 实现java.util.queue接口 1 3. 当前指针的2个实现方式 1 1.1 ...

  7. java 从零开始手写 RPC (03) 如何实现客户端调用服务端?

    说明 java 从零开始手写 RPC (01) 基于 socket 实现 java 从零开始手写 RPC (02)-netty4 实现客户端和服务端 写完了客户端和服务端,那么如何实现客户端和服务端的 ...

  8. java 从零开始手写 RPC (04) -序列化

    序列化 java 从零开始手写 RPC (01) 基于 socket 实现 java 从零开始手写 RPC (02)-netty4 实现客户端和服务端 java 从零开始手写 RPC (03) 如何实 ...

  9. java 从零开始手写 RPC (07)-timeout 超时处理

    <过时不候> 最漫长的莫过于等待 我们不可能永远等一个人 就像请求 永远等待响应 超时处理 java 从零开始手写 RPC (01) 基于 socket 实现 java 从零开始手写 RP ...

随机推荐

  1. vCPU 和 CPU 的关系

    vCPU 和 pCPU 的关系不是数量,当被底层虚拟化之后,任何一个 vCPU 都是用到所有的 pCPU 核心总体的百分比,不是某一个核心这么去看的,并没有对应的关系,也不是一个很绝对的分配到具体某个 ...

  2. php之新的开始---php的相关及其环境搭建

    写在前面:首先,感谢“奇矩”给的这次机会,不论结果如何,我都会尽我最大的努力! 在今晚之前,如果说,我与php的接触是停留在知道的阶段,那今晚过后,我想我算是认识了php.php作为一门编程语言,已经 ...

  3. 【代码学习】PYHTON 元组

    Python的元组与列表类似,不同之处在于元组的元素不能修改.也可进行分片 和 连接操作. 元组使用小括号,列表使用方括号. 一.访问元组 #coding=utf-8 Tuple = ('name', ...

  4. java 操作 csv文件

    CSV是逗号分隔文件(Comma Separated Values)的首字母英文缩写,是一种用来存储数据的纯文本格式,通常用于电子表格或数据库软件.在 CSV文件中,数据“栏”以逗号分隔,可允许程序通 ...

  5. Community Cloud零基础学习(一)启用以及简单配置

    本篇参考: https://trailhead.salesforce.com/en/content/learn/trails/communities https://trailhead.salesfo ...

  6. Python磁力获取器命令行工具 torrent-cli

    作为一个搞代码的,找资源这种事肯定不能像普通人一样打开百度盲目查找,你需要写个爬虫工具来帮你完成这件事情啦! 兼容环境 Windows/Linux/MacOs 安装 pip 安装 $ pip inst ...

  7. missing required architecture x86_64 in file

    ios错误ignoring file xxx missing required architecture x86_64 in file   错误ignoring file xxx missing re ...

  8. js学习:基本语法结构

    语句 JavaScript 程序的执行单位为行(line),也就是一行一行地执行.一般情况下,每一行就是一个语句. 语句(statement)是为了完成某种任务而进行的操作,比如下面就是一行赋值语句. ...

  9. IDEA中使用GsonFormat

    版本:IDEA Community 2019.2.2 说明:GsonFormat是一个可以直接将Json对象转化为Java类的插件 流程:安装GsonFormat插件=>新建一个空类Book=& ...

  10. Struts2学习(七)

    Servlet实现下载 1.Servlet 3.1之前实现文件上传 package ecut.request; import java.io.BufferedReader; import java.i ...