//循环队列,本质就是用动态数组实现的,且出队入队时间复杂度均O(1)的队列
//相比普通队列,增设一个front指针,代表队头,代表下一个出队的元素
//循环队列的重点在于队头队尾的元素的下标的计算(本质是映射循环队列中的真实索引),以及队列满的判断条件
//真实元素下标:(index+front)%elements.length(index为队列中下标,计算得真实数组中下标)
// 队尾:index =size-1 入队位置 index =size 出队位置(队头):front(移动至(front+1)%elements.length)
public class CircleQueueZH<E> {
private int size;
private int front;
private E elements[];
private static final int DEFAULT_CAPACITY = 10;//默认数组大小,可以扩容
public CircleQueueZH(){
elements = (E[]) new Object[DEFAULT_CAPACITY];//构造函数,泛型这里用Object类时,别忘了强制转换为E
}
//计算队头队尾元素下标可以写一个函数,用来映射循环队列中的真实索引
public int realIndexCaculate(int index){
return (index+front)%elements.length;//!!!
//就是要找队列中的下标为index的(第index+1个)元素,返回它在我们数组里的真实下标
//我觉得影响以后的可读性就没用
}
//动态扩容函数,之前写过一个int版,现在又拿过来用了,把2倍扩容改为了位运算的1.5倍扩容
private void ifNeedEnLarge(int needCapacity){
int oldcapacity = elements.length;
if (needCapacity<=oldcapacity){
return;
}else{
int newcapacity = oldcapacity + (oldcapacity>>1);//位运算效率高,相当于除2
E[] newElements = (E[]) new Object[newcapacity];
for (int i=0;i<size;i++){
//循环队列获取第i个元素的下标的方式:
newElements[i]=elements[(i+front)%elements.length];
//这个扩容的方式就是把队列里的元素依次出队到另一个队列里,同时重置队头的位置
}
front = 0;
elements = newElements;
System.out.println("enLarge Success"+" newCapacity = "+newcapacity);
}
}
public int size(){
return size;
}
public boolean isEmpty(){
return size == 0;
}
//清空循环队列,涉及到元素的真实下标计算,同扩容那里
public void clear(){
for (int i = 0;i<size;i++){
elements[(i+front)%elements.length]=null;
}
size = 0;
front = 0;
}
//出队,主要注意对front的处理
public E deQueue(){
E element = elements[front];
elements[front] = null;
front = (front+1)%elements.length;
size--;
return element;
}
//入队,主要注意对入队位置的计算
public void enQueue(E element){
ifNeedEnLarge(size+1);
elements[(front+size)% elements.length] = element;
size++;
}
public String arrayPrint(){
//这里没重写toString函数,直接写了个打印函数,我改的前面的int动态数组版本的,是我懒了
//这里用了stringBuilder类,一看就明白应该
StringBuilder string = new StringBuilder();
string.append("size = ").append(size).append(" ").append("front= ").append(elements[front]).append(" [");
for (int i = 0; i< elements.length; i++ ){
if (elements[i]==null){
string.append("null,");
}else {
string.append(elements[i]).append(",");
}
}
string.append("]");
return string.toString();
//这里是因为在这里面string是stringbuilder类的对象,不是string类的,不能作为返回值,所以事先转换一下
//输出样例 size = 13 front= 5 [0,1,2,null,null,5,6,7,8,9,10,11,12,13,14,]
}
}
2021 - 9 下旬 数据结构-线性表-循环队列-java实现代码
最新推荐文章于 2024-11-11 20:46:27 发布
该博客介绍了循环队列的实现,它使用动态数组并保证入队和出队操作的时间复杂度为O(1)。文章详细阐述了队头和队尾元素下标的计算方法,以及队列满的判断条件。此外,还提供了动态扩容的函数,采用1.5倍扩容策略,并展示了队列元素的映射和清空过程。
摘要由CSDN通过智能技术生成