概念
队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(head)进行删除操作,而在表的后端(tail)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。队列中没有元素时,称为空队列。
队列的数据元素又称为队列元素。在队列中插入一个队列元素称为入队,从队列中删除一个队列元素成为出队。因为队列只允许在一段插入,在另一端删除,所以只有最早进入队列的元素才能最先从队列中删除,故队列又称为先进先出(FIFO—first in first out)线性表。
循环队列
在实际使用队列时,为了使队列空间能重复使用,无论插入或删除,一旦tail指针增1或head指针增1 时超出了所分配的队列空间,就让它指向这片连续空间的起始位置。自己真从MaxSize-1增1变到0,可用取余运算tail%MaxSize和head%MaxSize来实现。这实际上是把队列空间想象成一个环形空间,环形空间中的存储单元循环使用,用这种方法管理的队列也就称为循环队列。处了一些简单应用之外,真正实用的队列时循环队列。
在循环队列中,当队列为空时,有head=tail,而当所有队列空间全占满时,也有head=tail。为了区别这两种情况,规定循环队列最多只能有MaxSize-1个队列元素,当循环队列中只剩下一个空存储单元时,队列就已经满了。因此,队列判空的条件时head=tail,而队列判满的条件时head=(tail+1)%MaxSize。队空和队满的情况如图:
本文讲述使用数组实现循环队列,是使用两个栈实现队列
数组实现循环队列
代码实现
package com.billJiang.queue;
/**
* Created by billJiang on 2016/11/30.
* 使用数组实现循环队列
*/
public class QueueArray<T> {
private int head;
private int tail;
private static final int INITIAL_SIZE=3;
private T[] array;
public QueueArray(int initial){
if(initial<=0)
initial=INITIAL_SIZE;
array= (T[]) new Object[initial];
}
//入队列
public boolean put(T obj){
if(isFull()){
return false;
}
array[tail]=obj;
tail=(tail+1)%array.length;
return true;
}
//获取队列头 而不出队列
public T peek(){
if(isEmpty()){
return null;
}
return array[head];
}
//出队列
public T poll(){
if(isEmpty()){
return null;
}
int cur=head;
head=(head+1)%array.length;
return array[cur];
}
public int size(){
if(tail>head){
return tail-head;
}else{
return tail-head+array.length;
}
}
public boolean isEmpty(){
return head==tail;
}
public boolean isFull(){
return head==(tail+1)%array.length;
}
}
两个栈实现队列
实现代码
package com.billJiang.queue;
import com.billJiang.stack.StackList;
/**
* Created by billJiang on 2016/12/1.
* 两个栈实现队列,stack1入栈,stack2出栈,如果stack2为空则从stack1导过来
*/
public class QueueStack<T> {
private StackList<T> stack1;
private StackList<T> stack2;
private int maxLength;
public QueueStack(int capacity){
this.maxLength=capacity;
stack1=new StackList<>(capacity);
stack2=new StackList<>(capacity);
}
public boolean put(T element){
if(stack1.isFull()||maxLength==size()){
return false;
}
stack1.push(element);
return true;
}
public T poll(){
if(!stack2.isEmpty()){
return stack2.pop();
}else{
while(!stack1.isEmpty()){
stack2.push(stack1.pop());
}
return stack2.pop();
}
}
public int size(){
return this.stack1.size()+this.stack2.size();
}
}