队列特征
- 队列是一种特殊的线性表,可以用数组或链表来表示。
- 遵循先入先出的原则。
- 队列的插入操作位于队尾,队列的删除操作位于队首。
队列中的溢出
- “下溢”现象:当队列为 空时,做出队运算时产生的溢出现象。
- “真上溢”现象:当队列满时,做入队操作产生空间溢出的现象。
- “假上溢”现象:由于入队和出队操作中,头尾指针都只向上移动,从而导致被删元素空间无法使用,此时若尾指针超过队列空间上界,则无法进行插入操作。
循环队列
为了解决“假上溢”问题,能够重复利用队列空间,因此对队列进行改进,当队列的尾指针或头指针上移时超出了分配给队列的空间,则将超出空间的头指针或尾指针重新放到队列的起始位置。
循环队列的数组实现:
public class ArrayQueueDemo {
public static void main(String[] args) {
// 实际分配4个空间,但仅仅只有3个空间能够使用,
// 约定一个空间作为判断队列是否已满的标志
ArrayQueue queue = new ArrayQueue(4);
queue.add(0);
queue.add(1);
queue.add(2);
queue.add(3);
queue.printQueue();
// 队列已满,不能加入
queue.add(4);
queue.printQueue();
// 获取元素
System.out.println("获取元素:" + queue.get());// 0
System.out.println("获取元素:" + queue.get());// 1
// 取出元素后,重新打印队列
queue.printQueue();
// 再次添加元素
queue.add(5);
queue.add(6);
queue.printQueue();
}
}
/**
* 实现环形队列
*/
class ArrayQueue {
private int maxSize;
private int head;
private int end;
private int[] arr;
public ArrayQueue(int maxSize) {
this.maxSize = maxSize;
arr = new int[maxSize];
head = 0;
end = 0;
}
/**
* 判断是否 为空
* @return
*/
public boolean isEmpty() {
return head == end;
}
/**
* 判断是否满
* @return
*/
public boolean isFull() {
return (end + 1) % maxSize == head;
}
/**
* 加入新元素
* @param element
*/
public void add(int element) {
if(isFull()) {
System.out.println("队列已满,不能加入元素");
return;
}
arr[end] = element;
end = (end + 1) % maxSize;
}
/**
* 获取队列元素
* @return
*/
public int get() {
if(isEmpty()) {
System.out.println("队列为空");
throw new RuntimeException("队列为空,无法取出");
}
int value = arr[head];
head = (head + 1) % maxSize;
return value;
}
/**
* 打印队列
*/
public void printQueue() {
System.out.println("----------队列元素-------------");
for(int i = head; i < head + getSize(); i++) {
System.out.printf("arr[%d]=%d\t", i % maxSize, arr[i % maxSize]);
}
System.out.println();
System.out.println("------------------------------");
}
/**
* 获取有效元素个数
* @return
*/
public int getSize() {
return (end + maxSize - head) % maxSize;
}
}