数组模拟环形队列
前言
相对于普通队列,环形队列front
指向第一个数据的位置,即0
,read
指向最后一个数据的位置的后一个位置
,maxSize
同样表示队列容量,有效数据个数为maxSize-1
。
一、手写一个环形队列
package com.darkForest.annularQueue;
import lombok.extern.slf4j.Slf4j;
/*
* 数组模拟环形队列
* */
@Slf4j(topic = "e")
public class AnnularQueue {
//定义一个数组模拟环形队列
int [] annularArray;
//队列容器,队列最大有效数据为maxSize-1
int maxSize;
//队列头
int front ;
//队列尾
int read;
//初始化环形队列
public AnnularQueue(int size){
maxSize=size;
annularArray=new int[maxSize];
front=0;
read=0;
}
//判断是否为空
public boolean isEmpty(){
if (front==read){
return true;
}
return false;
}
//判断是否容器已满
public boolean isFull(){
if ((read+1)%maxSize==front){
return true;
}
return false;
}
//添加数据
public void add(int value){
if (isFull()){
throw new RuntimeException("队列已满!!!");
}else {
annularArray[read]=value;
//把read后移,取模(因为要实现数据添加到数组最后一个位置时read要指向第一个位置)
read=(read+1)%maxSize;
}
}
//取出一个数据
public int get(){
int getValue=0;
if (isEmpty()){
throw new RuntimeException("队列为空!!!");
}else {
getValue=annularArray[front];
front=(front+1)%maxSize;
return getValue;
}
}
//取出所有数据
public int[] getAll(){
int [] arr=new int[getNumber()];
int te=0;
if (isEmpty()){
throw new RuntimeException("队列为空");
}else {
for (int i = front; i <front+getNumber() ; i++) {
arr[te]=annularArray[i%maxSize];
te++;
}
}
return arr;
}
//返回队列有效数据的个数
public int getNumber(){
if (isEmpty()){
return 0;
}else {
return (read+maxSize-front)%maxSize;
}
}
}
二、测试
测试1
package com.darkForest.annularQueue;
import lombok.extern.slf4j.Slf4j;
@Slf4j(topic = "e")
public class Test {
public static void main(String[] args) {
AnnularQueue annularQueue=new AnnularQueue(5);
annularQueue.add(1);
annularQueue.add(2);
annularQueue.add(3);
annularQueue.add(4);
int i = annularQueue.get();
log.debug("第一个数据:{}",i);
}
}
测试结果
测试2
package com.darkForest.annularQueue;
import lombok.extern.slf4j.Slf4j;
@Slf4j(topic = "e")
public class Test {
public static void main(String[] args) {
AnnularQueue annularQueue=new AnnularQueue(5);
annularQueue.add(1);
annularQueue.add(2);
annularQueue.add(3);
annularQueue.add(4);
annularQueue.add(5);
}
}
测试结果
这里虽然定义了队列容器是5,但是他实际能够存放的最大数量的有效数据是5-1,也就是4,所有当我们添加第5个数据时会报我们定义的异常“队列已满”
测试3
package com.darkForest.annularQueue;
import lombok.extern.slf4j.Slf4j;
@Slf4j(topic = "e")
public class Test {
public static void main(String[] args) {
AnnularQueue annularQueue=new AnnularQueue(5);
annularQueue.add(1);
annularQueue.add(2);
annularQueue.add(3);
annularQueue.add(4);
int number = annularQueue.getNumber();
log.debug("队列有效数据个数:{}",number);
log.debug("取出全部队列数据");
int[] all = annularQueue.getAll();
for (int i : all) {
log.debug("{}",i);
}
}
}
测试结果
小彩蛋
调用get()方法后,队列有效数据个数就发生了变化,大家可以把代码运行一下试试。
总结
环形队列也是一个有序列表,遵循先入先出原则,但是他相比较于普通队列不可动态更新数据,移动数据的缺点做出了改进。