队列Queue
队列是一种特殊的线性表,特殊之处在于它只允许在表的前端front进行删除操作,而在表的后端rear进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作端称为队尾,进行删除操作端称为队头。
Queue队列是一个先入先出FIFO的数据结构
队列遵循先入先出、后入后出的基本原则,一般来说,它只允许在表的前端进行删除操作,而在表的后端进行插入操作,但是java的某些队列运行在任何地方插入删除;比如常用的LinkedList集合,它实现了Queue接口,因此可以理解为LinkedList就是一个队列
根据实现方式不同分为顺序队列和链式队列
顺序队列
采用数组实现
队列的基本操作为添加数据的入队操作enqueue和删除并获取数据的dequeue出队操作
private Object[] items; // 具体存储数据的数组
private int head=0; // 队头下标
private int tail=0; // 队尾下标public boolean enqueue(Object item) //入队操作
public Object dequeue() // 出队操作
public class ArrayQueue {
private Object[] items; // 具体存储数据的数组
private int head=0; // 队头下标
private int tail=0; // 队尾下标
public ArrayQueue() {
this(10);
}
public ArrayQueue(int capacity) {
items=new Object[capacity];
}
public boolean enqueue(Object item) { //入队操作
if(tail==items.length)
return false; // 队伍已满,拒绝插入操作
items[tail++]=item;
return true;
}
public Object dequeue() { // 出队操作
if(head==tail)
return null; // 队列为空
return items[head++];
}
}
循环队列
基于数组的队列实现中,当tail=items.length时需要搬移大量的数据,就会导致入队操作的性能降低,可以使用循环队列解决。
典型算法题目:约瑟夫环
import java.util.Arrays;
public class CircleQueue {
private Object[] items;
private int head=0,tail=0;
public CircleQueue() {
this(10);
}
public CircleQueue(int capacity) {
items=new Object[capacity];
}
public boolean enqueue(Object item) {
// 如果尾指针和头指针重合则表示不能插入数据,因为头指针指向的位置上有数据
if((tail)%items.length==head&&items[head]!=null) {
return false; //拒绝插入操作
}
tail=(tail)%items.length;
items[tail++]=item;
return true;
}
public Object dequeue() {
if(head==tail&&items[head]!=null)
return null;
Object res=items[head];
items[head]=null;
head=(head+1)%items.length;
return res;
}
public static void main(String[] args) {
CircleQueue cq=new CircleQueue();
for(int i=0;i<10;i++)
cq.enqueue(i);
System.out.println(Arrays.toString(cq.items));
System.out.println("dsas:"+cq.head);
for(int i=0;i<4;i++)
System.out.println(cq.dequeue());
for(int i=11;i<20;i++)
cq.enqueue(i);
System.out.println(Arrays.toString(cq.items));
System.out.println(9%10);
}
}