目录
队列介绍
队列是一个有序列表,可以用数组或是链表来实现。
遵循先入先出的原则。即:先存入队列的数据,要先取出。后存入的要后取出
示意图:(使用数组模拟队列示意图)
数组模拟队列
队列本身是有序列表,若使用数组的结构来存储队列的数据,则队列数组的声明如下图, 其中 maxSize 是该队列的最大容量。
因为队列的输出、输入是分别从前后端来处理,因此需要两个变量 front及 rear分别记录队列前后端的下标,front 会随着数据输出而改变,而 rear则是随着数据输入而改变,如图所示:
思路分析
当我们将数据存入队列时称为”addQueue”,addQueue 的处理需要有两个步骤:思路分析 将尾指针往后移:rear+1 , 当front == rear 【空】 若尾指针 rear 小于队列的最大下标 maxSize-1,则将数据存入 rear所指的数组元素中,否则无法存入数据。 rear == maxSize - 1[队列满]
代码实现
package com.liuq.queue;
import java.util.Scanner;
/**
* Tips: 顺序队列
*
* @author Liuq
* @version 2019年08月01日
*/
public class ArrayQueueDemo {
public static void main(String[] args) {
//测试一把
//创建一个队列
com.liuq.queue.ArrayQueue queue = new com.liuq.queue.ArrayQueue(3);
char key = ' '; //接收用户输入
Scanner scanner = new Scanner(System.in);//
boolean loop = true;
//输出一个菜单
while (loop) {
System.out.println("s(show) : show queue");
System.out.println("e(exit) : exit program");
System.out.println("a(add) : add a data to queue");
System.out.println("g(get) : get a data from queue");
System.out.println("h(head) : show header data from queue ");
key = scanner.next().charAt(0);//接收一个字符
switch (key) {
case 's':
queue.showQueue();
break;
case 'a':
System.out.println("input a value ");
int value = scanner.nextInt();
queue.addQueue(value);
break;
case 'g': //取出数据
try {
int res = queue.getQueue();
System.out.printf("get a data is %d\n", res);
} catch (Exception e) {
// TODO: handle exception
System.out.println(e.getMessage());
}
break;
case 'h': //查看队列头的数据
try {
int res = queue.headQueue();
System.out.printf("queue head data is %d\n", res);
} catch (Exception e) {
// TODO: handle exception
System.out.println(e.getMessage());
}
break;
case 'e': //退出
scanner.close();
loop = false;
break;
default:
break;
}
}
System.out.println("exit ~~");
}
}
class ArrayQueue {
private int maxSize;
private int frontDel;
private int rearAdd;
private int[] arr;
public ArrayQueue(int maxSize){
this.maxSize=maxSize;
frontDel=-1;
rearAdd=-1;
arr=new int[maxSize];
}
public boolean isFull(){
return rearAdd==maxSize-1;
}
public boolean isEmpty(){
return rearAdd==frontDel;
}
public void addQueue(int value){
if(isFull()){
System.out.println("queue is full ");
return;
}
rearAdd++;
arr[rearAdd]=value;
}
public int getQueue(){
if(isEmpty()){
throw new RuntimeException(" queue is empty ,can not get data");
}
frontDel++;
int value=arr[frontDel];
arr[frontDel]=0;
return value;
}
public void showQueue(){
if(isEmpty()){
System.out.println("queue is empty ");
}
for(int i = 0; i < arr.length; i++) {
System.out.println("arr["+i+"]"+":"+arr[i]);
}
}
public int headQueue(){
if(isEmpty()){
throw new RuntimeException(" queue is empty ,can not get data");
}
return arr[frontDel+1];
}
}
存在问题
在普通顺序队列中,入队操作就是先将尾指针rear后移一个单元(rear++),然后将元素值赋给rear单元(data[rear]=X)。出队时.则是头指针front后移(front++)。像这样进行了一定数量入队和出队操作后,可能会出现这样的情况:尾指针rear已指到数组的最后一个元素.即rear==MAXLEN-1.此时若再执行入队操作,便会出现队满“溢出”。然而,由于在此之前可能也执行了若干次出队操作.因而数组的前面部分可能还有很多闲置的元素空间,即这种溢出并非是真的没有可用的存储空间,故称这种溢出现象为“假溢出”。显然,必须要解决这一似溢出的问题,否则顺序队列就没有太多使用价值