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. phantomjs安装步骤

    Windows环境:1.下载http://phantomjs.org/download.html2.解压phantomjs-2.1.1-windows.zip3.配置环境变量将解压的bin目录的路径配 ...

  2. Euler Sums系列(四)

    \[\Large\displaystyle \sum_{n=1}^\infty (-1)^n \frac{H_n}{2n+1}=\mathbf{G}-\frac{\pi}{2}\ln(2)\] \(\ ...

  3. 进程作业管理2-kill,前后台作业,并行执行

    kill命令:向进程发送控制信号,以实现对进程管理,每个信号对应一个数字,信号名称以SIG开 头(可省略),不区分大小写 显示当前系统可用信号: kill –l   或者  trap -l 常用信号: ...

  4. WLC-安装license

    在CLI界面安装licenseStep 1 Install a license on the controller by entering this command:①license install  ...

  5. C语言-数组与指针 字符与字符串

    1 字符与字符串:char c='a'而不能写出char c="a" //字符变量用单引号'',而字符串用双引号. 2 字符数组与字符指针的初始化: char s[10]={0}, ...

  6. 洛谷 P2925 [USACO08DEC]干草出售Hay For Sale

    嗯... 题目链接:https://www.luogu.org/problemnew/show/P2925 这是一道简单的01背包问题,但是按照正常的01背包来做会TLE一个点,所以要加一个特判(见代 ...

  7. SpringMVC中在Controller类的每个方法执行前调用某个方法的实现

    在使用SpringMVC做项目的时候,如果想在@Controller类中每个@RequestMapping方法执行前都调用某个方法,要怎么实现呢?答案是使用Spring的@ModelAttribute ...

  8. php面试题之PHP核心技术

    一.PHP核心技术 更多PHP相关知识请关注我的专栏PHP​zhuanlan.zhihu.com 1.写出一个能创建多级目录的PHP函数(新浪网技术部) <?php /** * 创建多级目录 * ...

  9. VS误删sln项目文件怎么办

    以项目名为Test为例 打开Test/Test目录下的 Test.vcxproj 文件,试着运行一下,退出后提示保存sln文件,选择一个目录即可.

  10. 第一个Tornado程序

    环境:Python3.8 系统:win10 1903 工具:pycharm2019.3 import tornado.web # web服务基本功能都封装在此模块中 import tornado.io ...