前言
模拟的非常简单,简单到只是大概体现其思想。
高端的队列实现我也不会(逃
关于队列
队列是什么?
生活中很简单的一个例子,排队。
就说买电影票,先去的人,先买到票。后来的人,在后面排队等待。
程序中的例子,迅雷下载。
下载各种.avi时,如果有15个以上的任务需要下载,假设指定5个同时下载,那么剩下的十个就是在队列里等待,先下载的先完成。
队列就是这样一个“先进先出”、”后进后出”的数据结构。
数组模拟队列
考虑到队列的“先进先出”、”后进后出”,则需要两个变量来充当队列的头指针和尾指针,都是数组角标。
同时为了防止队列填充元素过多,我们还需要一个变量来实时更新数组中实际存在的元素个数。
具体实现的部分解析:
初始状态:
//一个长度为3的数组
Object[] queue = new Queue[3];
//头尾和大小初始都为0,因为没有元素存在
int head = 0;
int tail = 0;
int size = 0;
添加操作:
//在尾角标指向的位置添加该元素
queue[tail] = 1;
//然后尾角标自增指向下一个位置
tail++;
//因为有元素入队了,所以大小也要自增
size++;
移除操作:
//只要头角标自增,此时队列头就指向了下一个位置的元素
head++;
//因为有元素出队,所以大小也要同步更新
size--;
/*
此时怪异的地方出现了,添加元素时tail自增,删除元素是head自增。
它们这是无穷无尽的自增啊,会不会越界呢?
当然会。所以还需要处理头尾角标。
*/
//当空队列添加三个元素之后,三个变量的值分别是
tail = 3;
size =3;
head = 0;
//然后删除一个元素,此时三个变量的值是
tail = 3;
size = 2;
head = 1;
//可以看到size等于2,可以继续添加元素
//然而tail的值是3,如果按上面的方法添加元素就会报异常。
//所以我们需要改进一下
//已经知道head=1,且队列长度只有2
//这意味着第0个位置的元素是不需要的,所以我们可以使用第0个位置存储我们的第三个元素。
//代码实现,如果数组长度允许的情况下,使用取模处理尾角标,防止越界
if(size < queue.length) {
tail = tail % queue.length;
queue[tail] = 3;
tail++;
}
//移除元素同理,需要处理角标。
具体实现代码
public class GodQueue {
public static void main(String[] args) {
GodQueue godQueue = new GodQueue(10);
//添加操作
for (int i = 0; i < 10; i++) {
godQueue.add(i);
}
System.out.println("添加后,size = " + godQueue.size());
//移除
System.out.println("-------------------------------");
while (true) {
System.out.print(godQueue.remove());
if (godQueue.size() != 0) {
System.out.print(" ");
} else {
System.out.println();
break;
}
}
System.out.println("-------------------------------");
System.out.println("移除后,size = " + godQueue.size());
}
//用于模拟队列的数组
private Object[] myQueue;
//队列头
private int queueHead;
//队列尾
private int qeueTail;
//队列实际元素个数
private int queueSize;
/**
* 构造函数
* @param maxSize 指定队列的最大长度
*/
GodQueue(int maxSize) {
myQueue = new Object[maxSize];
queueHead = qeueTail = queueSize = 0;
}
/**
* 查看队列的实际元素个数
*
* @return 返回队列实际元素个数
*/
public int size() {
return queueSize;
}
/**
* 查看队列是否为空
*
* @return 当队列为空返回真,否则返回假
*/
public boolean isEmpty() {
return queueSize == 0 ? true : false;
}
/**
* 查看队列中是否存在某元素
*
* @param o 用于查找参照的元素
* @return 当找到该元素时返回真,否则返回假
*/
public boolean contains(Object o) {
for (int i = 0; i < size(); i++) {
if (myQueue[i].equals(o)) {
return true;
}
}
return false;
}
/**
* 添加一个元素到队列尾部
*
* @param o 要加入队列的元素
* @return 添加成功返回真,否则返回假
*/
public boolean add(Object o) {
if (queueSize < myQueue.length) {
//取模:当到达数组的末尾,从头开始
qeueTail = qeueTail % myQueue.length;
myQueue[qeueTail++] = o;
//队列大小增加
queueSize++;
} else {
return false;
}
return true;
}
/**
* 清除所有元素
*/
public void clear() {
queueHead = queueSize = qeueTail = 0;
}
/**
* 移除队列中首个入队的元素
*
* @return 返回被移除的元素
*/
public Object remove() {
if (queueSize > 0) {
queueSize--;
queueHead = queueHead % myQueue.length;
return myQueue[queueHead++];
}
return null;
}
/**
* 查询队列首个元素的内容
*
* @return 返回队列首元素
*/
public Object peek() {
if (queueSize != 0) {
return myQueue[queueHead];
}
return null;
}
/**
* 根据角标返回队列的元素
*
* @param i 队列位置
* @return 返回队列中第i个元素
*/
public Object get(int i) {
i = (queueHead + i) % myQueue.length;
return myQueue[i];
}
}
运行结果
添加后,size = 10
-------------------------------
0 1 2 3 4 5 6 7 8 9
-------------------------------
移除后,size = 0