队列是一种特殊的线性表,其删除和插入过程都是在线性表的两端进行的。向队列中插入元素的过程叫做入队,只允许在队尾入队。删除元素的过程称为出队,只允许在队头删除。其特点为先进先出(First In First Out).
队列按其存储方式来分,又可以分为顺序队列和链表队列。
顺序队列使用的顺序表,下面贴代码。
class SequenceQueue{
//顺序队列存在,顺序队列出队效率低(需要移动元素),并且存在加溢出(当rear>=length()时,会出现假溢出),所以就出现了顺序循环队列
//开始时,font=rear=0,对列为空,当(rear+1)%length=font时,队列满
private Object[] array;
private int font,rear;
public SequenceQueue(){};
public SequenceQueue(int length){
array=new Object[length];
font=rear=0;
}
//入队
public boolean add(Object o){
if(o==null)
return false;
if(font==(rear+1)%array.length){
Object[] copy=array;
array=new Object[array.length*2];
int j=0;//新数组的下标
for(int i=font;i!=rear;i=(i+1)%copy.length){
array[j++]=copy[i];
}
array[rear]=o;
this.rear=(rear+1)%array.length;
}
return true;
}
//出队
public Object poll(){
if(font==rear)
return null;
Object o=array[font];
font=(font+1)%array.length;
return o;
}
}
链式队列使用的是单链表,入队效率低。
class LinkedQueue<T>{
//对于单链表来说,入队效率低(从队尾入,需要先从头结点,遍历到最后一个节点,才能进行队尾插入),当然可以通过循环双链表来实现,但这会占用较多的空间,
//另一个解决方案就是,增加尾指针,使font指向头节点,rear指向尾节点
class Node<T>{
Node<T> next;
T data;
public Node(){}
public Node(T data,Node<T> next){
this.data=data;
this.next=next;
}
}
private Node<T> font=null;//指向头节点
private Node<T> rear=null;//指向尾节点
//向链表队尾增加节点
public boolean add(T data){
if(data==null)
return false;
Node<T> node=new Node<T>(data,null);
if(this.font==null)
this.font=node;
else
{
this.rear.next=node;
}
this.rear=node;
return true;
}
//从链表队头出队
public T poll(){
if(this.font==null)
return null;
T x=this.font.data;
this.font=this.font.next;
if(this.font==null)
this.rear=null;
return x;
}
}