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. 11,html5为什呢只需要写<!DOCTYPE HTML>

    11,html5为什呢只需要写<!DOCTYPE HTML> html5不基于SGML,不需要对dtd(百科:翻译为文档类型定义,作用是定义xml文档的合法构建模块,成行声明于xml文档中 ...

  2. git 工具常见命令

    1.git是什么 git是分布式版本管理工具,一台电脑既可以是客户端,也可以是服务端.工作过程中可以断开网络. git中的三个概念: 1.版本库:在初始化git版本库之后会生成一个隐藏的文件, .gi ...

  3. mcast_set_loop函数

    #include <errno.h> #include <sys/socket.h> #include <net/if.h> #include <netine ...

  4. 计算机二级-C语言-程序设计题-190111记录-两种指针赋值的不同,普通输入输出函数和文件输入输出函数的使用

    //程序设计题:函数fun的功能是:将两位数的正整数a,b合并形成一个整数放在c中.合并的方式是:将a数的十位和个位数依次放在c数的个位和百位上,b数的十位和个位数依次放在c数的十位和千位上.例如:当 ...

  5. python获取当前文件的上一级目录

    import osos.path.dirname(os.path.abspath(__file__))

  6. Plastic Bottle Manufacturer Tips - Attention To Plastic Bottle Processing Technology

    In fact, the processing technology of plastic bottles is actually quite strict. In fact, regular man ...

  7. ZOJ4110 Strings in the Pocket(2019浙江省赛)

    给出两个字符串,询问有多少种反转方法可以使字符串1变成字符串2. 如果两个串相同,就用马拉车算法找回文串的数量~ 如果两个串不同,从前往后找第一个不同的位置l,从后往前找第二个不同的位置r,反转l和r ...

  8. Qt5基于smtp服务发送电子邮件

    1.设置邮箱 先登录163邮箱,然后在邮箱界面找到设置,在里面开通smtp服务. 这一步比较关键,要开通smtp服务,在开通的过程中会让你输入一个邮箱客户端授权码,这个才是你后面要用到的密码,而不是你 ...

  9. java课极限测试

    在临近国庆的9月30号补课日 碰到了惨绝人寰的java课极限测试 我从下午两点半做到晚上九点 不得不说人在烦躁的时候是真的没办法写代码的 根本不想思考也不想学习.最后的几个小时基本就是在叹息和坐着.也 ...

  10. day03-MyBatis的动态SQL语句查询

    场景一: 例如当我们想实现这样的查询的时候之前的操作貌似满足不了我们.  场景二: 还有些时候我们如果输入的信息越多满足要求的就越多,所查找出来的用户就越少 当我们之输入姓名的时候可能查找出10个人, ...