1)系统采用一组地址连续的存储单元依次存放队列从rear端到front端的所有数据,程序只需要front和rear两个整型变量来记录队列front端的元素索引和rear端的元素索引。
(2)顺序队列的front总是保存着即将出队的元素的索引,顺序队列中的rear总是保存着下一个即将进入队列的元素的索引。
(3)队列中元素的个数是rear - front.
(4)顺序队列的底层采用的是数组来保存队列元素,每个元素在队列中的位置是不变的,变的是front和rear两个整型变量。有元素进入队列时rear变量的值+1,有元素从队列中移除时,front变量的值+1;
public class SequenceQueue<T>
{
//数组初始默认长度
private int DEFAULT_SIZE = 10;
//保存数组的长度
private int capacity;
//定义一个数组可以保存顺序队列的元素
private Object[] elementData;
private int front;//
private int rear;
public SequenceQueue()
{
capacity = DEFAULT_SIZE;
elementData = new Object[capacity];
}
//以一个初始化元素创建队列
public SequenceQueue(T element)
{
this();
elementData[0] = element;
rear++;
}
//以一个初始化元素和指定的数组长度来初始化队列
public SequenceQueue(T element, int initSize)
{
this.capacity = initSize;
elementData = new Object[capacity];
elementData[0] = element;
rear++;
}
//队列的长度
public int length()
{
return rear - front;
}
//插入队列
public void add(T element)
{
if(rear > capacity - 1 )
{
throw new IndexOutOfBoundsException("队列已满");
}
elementData[rear++] = element;
}
//移除队列的front元素
public T remove()
{
if(isEmpty())
{
throw new IndexOutOfBoundsException("空队列异常");
}
T oldElement = (T)elementData[front];
elementData[front++] = null;
return oldElement;
}
//判断队列是否已空
public boolean isEmpty()
{
return rear == front;
}
//清除队列
public void clear()
{
Arrays.fill(elementData,null);
front = 0;
rear = 0;
}
public String toString()
{
if(isEmpty())
{
return "[]";
}
else
{
StringBuilder sb = new StringBuilder("[");
for (int i = front; i < rear; i++)
{
sb.append(elementData[i].toString() + ",");
}
int len = sb.length();
return sb.delete(len-1,len).append("]").toString();
}
}
}
测试
public class SequenceQueueTest
{
public static void main(String[] args)
{
SequenceQueue<String> queue = new SequenceQueue<String>();
queue.add("hello");
queue.add("world");
queue.add("welcome");
System.out.println(queue);
System.out.println("删除队列的front元素:" + queue.remove());
System.out.println(queue);
queue.clear();
System.out.println(queue);
}
}
结果:
[hello,world,welcome]
删除队列的front元素:hello
[world,welcome]
[]
对于这种实现的顺序队列,当删除front元素时,删除元素的内存空间就不可以被再次利用。当把队列加满,再逐个删除时,队列就无法再加入元素。
对于这种“假满”问题:可以采用如下两种方式进行解决:
方式一:每次将元素移出队列时,将队列中所有的元素向front方向移动一位,这样front永远为0,rear-1;将元素插入队列时,将rear的值+1;但是这种方式在每次删除元素时岁整体元素移动,会使程序的时间复杂度变高。
方式二:循环队列将数组的储存区域看成是首位相连的环形区域,当存放到最大的位置时rear的值变为0。