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. 【MySQL】多表查询

    " 目录 多表链接查询 笛卡尔积 内链接 inner join 外链接之左链接 left join 外链接之右链接 right join 全外链接 符合条件链接查询 子查询 先准备两张表:部 ...

  2. 洛谷 P1843 奶牛晒衣服(二分答案)

    嗯... 题目链接:https://www.luogu.com.cn/problem/P1843 我们二分枚举时间,看看那些衣服在蒸发后还要用烘干机,则用cnt记录它的时间. 注意w数组在操作中不能变 ...

  3. jsp用equals判断两个字符串变量是否相等

    使用即可: s1.equals(s2) 如果使用场景: if(s1==s2){} 这样使用可能会出现判断无效的情况. 使用if(s1.equals(s2)){}就可以了.

  4. Codeforces Round #576 (Div. 2) 题解

    比赛链接:https://codeforc.es/contest/1199 A. City Day 题意:给出一个数列,和俩个整数\(x,y\),要求找到序号最靠前的数字\(d\),使得\(d\)满足 ...

  5. JavaSE复习~常量、变量、关键字、标识符

    标识符.关键字 标识符:指程序中为了代表一些东西,用户自己定义的名字 关键字:系统预先定义的一些具有特殊意义的标识符, 保留字:系统预先定义,不作为关键字,也不允许用户使用 Java中的关键字: 标识 ...

  6. 【代码学习】PYTHON 列表循环遍历及列表常见操作

    一.for循环 为了更有效率的输出列表的每个数据,可以使用循环来完成 代码: A = ['xiaoWang','xiaoZhang','xiaoHua'] for tempName in A: pri ...

  7. Intellij IDEA中创建Package变成一级目录

    1.创建包,但是出来的却是一级目录 2.因为Compact Middle Packages默认勾选上了,取消掉即可

  8. Passive Client Feature

    Q. How is the passive client feature used on Wireless LAN Controllers? A. Passive clients are wirele ...

  9. vjudge Trailing Zeroes (III) (二分答案 && 数论)

    嗯... 题目链接:https://vjudge.net/contest/318956#problem/E 这道题是二分答案+数论,但首先是数论,否则你不知如何二分... 首先关于一个阶乘的结果最后会 ...

  10. #P2010 回文日期 的题解

    题目描述 在日常生活中,通过年.月.日这三个要素可以表示出一个唯一确定的日期. 牛牛习惯用88位数字表示一个日期,其中,前44位代表年份,接下来22位代表月 份,最后22位代表日期.显然:一个日期只有 ...