定义:只允许在表的一端插入数据,而在表的另一端访问数据。根据存储方式可分为顺序队列和链队列。
运算限制:先进先出。
基本概念:允许插入的一端称为队尾(rear),允许访问的一端称为队头(front)。
基本运算:
1::创建一个空的队列。
2:判空。
3:入队。添加到队尾,修改队尾指针。
4:出队。删除队头,修改队头指针。
5:读队头数据。
顺序队列说明:
利用一组地址连续的存储单元存放队列中的元素。为了降低运算的复杂度,元素入队时只修改队尾指针,元素出队时只修改队头指针,由于顺序队列的存储空间容量是提前设定的,所以队尾指针会有一个上限值,当队尾指针达到该上限时,就不能再向队尾添加元素,而应该从队头前被删除的地址添加,所以顺序队列通常被设计为环状结构,指针通过整除取余运算实现,这种队列称为循环队列。在队列空和队列满的时候,循环队列的队头和队尾指向相同的指针,无法判断是队空还是对满。针对这个情况有两个处理方式,一,添加一个标识用来区分队空或队满。二,牺牲一个存储单元,约定队尾的下一个位置是队头时为满,队尾等于队头是为空。
下面看一下两种的实现。
添加标识法。
public class RoundQueue implements Queue{
private Integer[] array;
private int size ;//循环队列的存储空间
private int front ;//对头
private int rear ;//对尾
private int length ;//数组中元素的个数,=0时空,=size时满
public RoundQueue(int initSize){
this.size = initSize;
array = new Integer[initSize];
front = 0 ;
rear = 0 ;
length = 0 ;
}
@Override
public boolean isEmpty() {
return (length == 0);
}
@Override
public boolean isFull() {
return (length == size) ;
}
//入队时,判队满,修改队尾
@Override
public void enterQueue(int value) {
if(isFull()) throw new ArrayIndexOutOfBoundsException(size);
//队尾赋值
array[rear] = value ;
//队尾指向下一个位置
rear = (rear + 1) % size ;
//元素个数加1
length++ ;
}
//出队时,判对空,修改对头
@Override
public Integer deleteQueue() {
if(isEmpty()) return null;
//取队头值
int num = array[front] ;
//队头值置空
array[front] = null ;
//队头指针指向下一个位置
front = (front + 1) % size ;
//元素个数-1
length-- ;
return num;
}
//查看队头
@Override
public Integer frontQueue() {
return isEmpty()?null:array[front];
}
}
牺牲一个存储单元法。
/**
* <p>Title: RoundQueueInsteadOne
* 数组长度不可变,初始化长度必须大于1,实际应用中长度不大于1的话也不需要用到队列</p>
* <p>Description: </p>
* @author 未知神秘人物
* @date 2019年3月6日
*/
public class RoundQueueInsteadOne implements Queue{
private Integer[] array;
private int size ;//循环队列的存储空间
private int front ;//对头
private int rear ;//对尾
public RoundQueueInsteadOne(int initSize){
this.size = initSize;
array = new Integer[initSize];
front = 0 ;
rear = 0 ;
}
@Override
public boolean isEmpty() {
return (front == rear);
}
@Override
public boolean isFull() {
return (((rear + 1) % size) == front) ;
}
//入队时,判队满,修改队尾
@Override
public void enterQueue(int value) {
if(isFull()) throw new ArrayIndexOutOfBoundsException(size);
array[rear] = value ;
rear = (rear + 1) % size ;
}
//出队时,判对空,修改对头
@Override
public Integer deleteQueue() {
if(isEmpty()) return null;
int num = array[front] ;
array[front] = null ;
front = (front + 1) % size ;
return num;
}
//查看队头
@Override
public Integer frontQueue() {
return isEmpty()?null:array[front];
}
}
链队列实现
public class LinkQueue implements Queue {
private Link base;
private Link front;
private Link rear;
static class Link{
Integer data;
Link next ;
}
@Override
public void enterQueue(int value) {
Link link = new Link();
link.data = value ;
if(isEmpty()){
base = link;
rear = base;
front = base;
return ;
}
rear.next = link;
rear = rear.next ;
}
@Override
public Integer deleteQueue() {
if(isEmpty()){
return null ;
}
int num = front.data;
front = front.next;
return num;
}
@Override
public Integer frontQueue() {
return isEmpty()?null:front.data;
}
@Override
public boolean isEmpty() {
return (base==null || front==null);
}
//没有了数组的长度限制,不需要判满
@Override
public boolean isFull() {
return false;
}
}
测试结果
public class Test {
public static void main(String[] args) {
RoundQueueInsteadOne roundQueue = new RoundQueueInsteadOne(2);
System.out.println("roundQueue");
System.out.println("isEmpty:"+roundQueue.isEmpty());
System.out.println("isFull:"+roundQueue.isFull());
roundQueue.enterQueue(111);
System.out.println("deleteQueue:"+roundQueue.deleteQueue());
System.out.println("frontQueue:"+roundQueue.frontQueue());
RoundQueue rQueue = new RoundQueue(1);
System.out.println("rQueue");
System.out.println("isEmpty:"+rQueue.isEmpty());
System.out.println("isFull"+rQueue.isFull());
rQueue.enterQueue(111);
System.out.println("deleteQueue:"+rQueue.deleteQueue());
System.out.println("frontQueue:"+rQueue.frontQueue());
LinkQueue queue = new LinkQueue();
System.out.println("LinkQueue");
System.out.println("isEmpty:"+queue.isEmpty());
System.out.println("frontQueue:"+queue.frontQueue());
System.out.println("deleteQueue:"+queue.deleteQueue());
queue.enterQueue(111);
queue.enterQueue(111);
queue.enterQueue(111);
System.out.println("isEmpty:"+queue.isEmpty());
System.out.println("frontQueue:"+queue.frontQueue());
System.out.println("deleteQueue:"+queue.deleteQueue());
System.out.println("deleteQueue:"+queue.deleteQueue());
System.out.println("deleteQueue:"+queue.deleteQueue());
System.out.println("deleteQueue:"+queue.deleteQueue());
}
}
roundQueue
isEmpty:true
isFull:false
deleteQueue:111
frontQueue:null
rQueue
isEmpty:true
isFullfalse
deleteQueue:111
frontQueue:null
LinkQueue
isEmpty:true
frontQueue:null
deleteQueue:null
isEmpty:false
frontQueue:111
deleteQueue:111
deleteQueue:111
deleteQueue:111
deleteQueue:null