用java以数组为底层结构创建循环队列
循环队列相对于普通队列最大的变化就是添加了一个头指针head,尾指针tail。原先的普通数组队列当入队列再出队列之后,前面就会空出位置,如果要再添加元素的话只能往尾部添加,当添加到容积大小的索引时就会自动扩容往后添加,但永远都不能在前面出队的空出的位置添加,前面的位置就浪费了。循环队列很有效的解决了这一问题,通过两个指针对capacity容积取余来改变指针指向位置从而杜绝上述问题。
尾指针是入队位置的索引,每入队一个元素后,tail++。头指针是出队元素的索引,每出队一个元素后,head++。但是怎么才能循环呢?当尾指针等于capacity时,说明需要改变尾指针到开头位置来插入元素了,tail=(tail+1)%capacity。如果用这样的方法,那队满条件也得改变:(tail+1)%capacity==head。
代码如下:
looparr:底层结构:循环数组
public class LoopArr<T> {
private T[] value; //保存数据
int size; //实际存放个数
int capacity; //容积
private int head;
private int tail;
// 构造方法
public LoopArr(int capacity){
//因为队满时要空出来一个位置,所以容积需要相较于之前的普通数组加1
if(capacity<=0){
this.capacity=11;
}else {
this.capacity=capacity+1;
}
this.size=0;
this.head=this.tail=0;
this.value=(T[])(new Object[this.capacity]);
//不可以直接new一个T[]类型,所以需要先new一个Object[]类型然后转为T[]
}
//判断数组是否为空
public boolean IsEmpty(){
if(this.head==this.tail){
return true;
}else{
return false;
}
}
//向数组中添加元素
public void add(T data){
//扩容
if((this.tail+1)%this.capacity==this.head){ //如果数组满了就重新设置容积
resize((this.capacity-1)*2+1); //先把容积变为原先的容积,再×2,加1是循环队列队满时有一个空
}
this.value[this.tail]=data;
//因为是循环的,当队尾指到最后了就需要重新回到第一个位置继续加
this.tail=(this.tail+1)%this.capacity;
this.size++;
}
//移除队首元素
public T remove(){
//缩容
if(this.size<=this.capacity/4&&this.capacity/2>0){
resize((this.capacity-1)/2+1); //与扩容同理
}
if(IsEmpty()){
return null;
}else{
T e=this.value[head];
this.value[head]=null;
//head指向末尾时需要重新循环到开头,所以如下
this.head=(this.head+1)%this.capacity;
this.size--;
return e;
}
}
//重新给容积
private void resize(int newcapacity){
//由于数组的容积都是不变的所以需要新建一个数组
T [] newvalue=(T[])(new Object[newcapacity]);
//转移数组
for (int i = 0; i < this.size; i++) {
newvalue[i]=this.value[(this.head+i)%this.capacity]; //给新数组赋值,此时capacity还没有变,所以%this.capacity
}
//改变容器,数组
this.value=newvalue;
this.capacity=newcapacity;
this.head=0; //从头开始
this.tail=this.size; //尾指针指向最后一个元素的下一个位置也就是size
}
public int getHead() {
return head;
}
public int getTail() {
return tail;
}
//获取索引位置的值
public T getindexdata(int index){
if(index<0||index>this.capacity){
throw new IllegalArgumentException("index is invalid.");
}
return this.value[index];
}
//获取实际长度
public int getSize() {
return this.size;
}
//获取数组的容积
public int getCapacity() {
return this.capacity;
}
}
队列接口:用于被循环队列实现功能
public interface selfqueue<T> {
//入队
void offer(T e);
//出队
T poll();
//查看队首元素
T peak();
//队列中元素的个数
int getsize();
//队列是否为空
boolean IsEmpty();
}
LoopQueue:文章来源:https://www.toymoban.com/news/detail-811539.html
public class LoopQueue<T> implements selfqueue<T> {
private LoopArr<T> data;
public LoopQueue(){
this.data=new LoopArr<T>(10);
}
//入队
public void offer(T e) {
this.data.add(e);
}
//出队
public T poll() {
return this.data.remove();
}
//获得队首元素
public T peak() {
return this.data.getindexdata(this.data.getHead());
}
//获取长度
public int getsize() {
return this.data.getSize();
}
//获取容积
public int getcapacity(){return this.data.getCapacity();}
//判断是否为空
public boolean IsEmpty() {
return this.data.IsEmpty();
}
}
测试:文章来源地址https://www.toymoban.com/news/detail-811539.html
public class queuetest<T> {
public void test(LoopQueue queue, List<T> list){
//开始时间
long startTime=System.nanoTime();
//入队
System.out.println("队尾先进,入队顺序:");
for (int i = 0; i < list.size(); i++) {
queue.offer(list.get(i));
System.out.print(list.get(i)+" ");
}
System.out.println("size:"+queue.getsize());
System.out.println("capacity:"+queue.getcapacity());
System.out.println("队列中元素个数:"+queue.getsize());
System.out.println("队头元素:"+queue.peak());
//出队
System.out.println("队头先出,出队顺序:");
while(!queue.IsEmpty()){
T e= (T) queue.poll();
System.out.print(e+" ");
}
//结束时间
long endTime=System.nanoTime();
System.out.println("总耗时:"+(endTime-startTime)/1000000000.0+"s");
}
public static void main(String[] args) {
queuetest<Integer> qt=new queuetest<Integer>();
selfqueue<Integer> queue=new LoopQueue<Integer>(); //继承了selfqueue的LoopQueue来实现selfqueue
List<Integer> list=new ArrayList<Integer>();
Random r=new Random();
for (int i = 0; i < 30; i++) {
list.add(r.nextInt(100));
}
qt.test((LoopQueue) queue,list);
}
}
到了这里,关于用java以数组为底层结构创建循环队列的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!