队列
1. 队列介绍
- 队列是一个有序列表,可以用数组或是链表来实现。
- 遵循先入先出的原则。即:先存入队列的数据,要先取出。后存入的要后取出。
2. 数组模拟队列
-
MaxSize
是该队列的最大容量。 -
front
和rear
分别记录队列前后端的下标,初始值为front = rear = -1
。 -
队空:
front == rear
。 -
队满:
rear == MaxSize - 1
。 -
入队:
- 将尾指针往后移:
rear + 1
; - 若尾指针
rear
小于队列的最大下标maxSize-1
,则将数据存入rear
所指的数组元素中,否则无法存入数据。
- 将尾指针往后移:
-
出队:
- 先判断队列是否为空,为空则无法取出数据;
- 将头指针往后移:
front + 1
; - 将数据从
front
所指的数组元素中取出。
3. 代码实现
import java.util.Scanner;
/**
* 测试队列
*/
public class TestArrayQueue {
public static void main(String[] args) {
ArrayQueue queue = new ArrayQueue(3);
Scanner in = new Scanner(System.in);
char key = ' ';
boolean loop = true;
while (loop) {
System.out.println("a(add):数据入队");
System.out.println("g(get):数据出队");
System.out.println("h(head):显示队头数据");
System.out.println("s(show):显示整个队列的数据");
System.out.println("e(exit):退出程序");
key = in.next().charAt(0);
switch (key) {
case 'a':
System.out.println("请输入数据:");
int num = in.nextInt();
queue.add(num);
break;
case 'g':
try {
System.out.println("取出的数据是:" + queue.get());
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case 'h':
System.out.print("队头元素是:");
queue.showHead();
System.out.println();
break;
case 's':
System.out.print("队列为:");
queue.show();
System.out.println();
break;
case 'e':
loop = false;
break;
}
}
System.out.println("程序退出!");
}
}
/**
* 数组队列类
*/
class ArrayQueue {
private int[] arrayQueue;
private int maxSize;
private int front; // 指向队首元素的前一个位置
private int rear; // 指向队尾元素
/**
* 初始化队列
* @param size 队列的最大容量
*/
public ArrayQueue(int size) {
arrayQueue = new int[size];
maxSize = size;
front = -1;
rear = -1;
}
/**
* 判断队是否为空
* @return true为空
*/
private boolean isEmpty() {
return front == rear;
}
/**
* 判断队是否为满
* @return true为满
*/
private boolean isFull() {
return rear == (maxSize - 1);
}
/**
* 数据入队
* @param num 要添加的数据
*/
public void add(int num) {
if (isFull()) {
System.out.println("队列满了,无法添加数据!");
return;
}
arrayQueue[++rear] = num;
}
/**
* 数据出队
* @return 返回出队的数据
*/
public int get() {
if (isEmpty()) {
throw new RuntimeException("队列为空,无法获取数据!");
}
return arrayQueue[++front];
}
/**
* 显示队头信息
*/
public void showHead() {
if (isEmpty()) {
System.out.println("队列为空,无法获取数据!");
return;
}
System.out.printf("%d", arrayQueue[front + 1]);
}
/**
* 显示整个队列信息
*/
public void show() {
if (isEmpty()) {
System.out.println("队列为空,无法获取数据!");
return;
}
for (int i = front + 1; i <= rear; i++) {
System.out.printf("%d\t", arrayQueue[i]);
}
}
}
4. 数组模拟循环队列
- 普通队列会出现假溢出现象,使用循环队列解决。
- 队满:
(rear + 1) % maxSize == front
。 - 队空:
rear == front
。 - 初始值:
front = rear = 0
。 - 元素个数:
(rear + MaxSize - front) % MaxSize
。
5. 代码实现
import java.util.Scanner;
/**
* 测试循环队列
*/
public class TestCircleArrayQueue {
public static void main(String[] args) {
CircleArrayQueue queue = new CircleArrayQueue(4);
Scanner in = new Scanner(System.in);
char key = ' ';
boolean loop = true;
while (loop) {
System.out.println("a(add):数据入队");
System.out.println("g(get):数据出队");
System.out.println("h(head):显示队头数据");
System.out.println("s(show):显示整个队列的数据");
System.out.println("e(exit):退出程序");
key = in.next().charAt(0);
switch (key) {
case 'a':
System.out.println("请输入数据:");
int num = in.nextInt();
queue.add(num);
break;
case 'g':
try {
System.out.println("取出的数据是:" + queue.get());
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case 'h':
System.out.print("队头元素是:");
queue.showHead();
System.out.println();
break;
case 's':
System.out.print("队列为:");
queue.show();
System.out.println();
break;
case 'e':
loop = false;
break;
}
}
System.out.println("程序退出!");
}
}
/**
* 循环队列类
*/
class CircleArrayQueue {
private int[] arrayQueue;
private int maxSize;
private int front; // 指向队首元素
private int rear; // 指向队尾元素的后一个位置
/**
* 初始化队列
* @param size 队列的最大容量
*/
public CircleArrayQueue(int size) {
arrayQueue = new int[size];
maxSize = size;
}
/**
* 判断队是否为空
* @return true为空
*/
private boolean isEmpty() {
return front == rear;
}
/**
* 判断队是否为满
* @return true为满
*/
private boolean isFull() {
return (rear + 1) % maxSize == front;
}
/**
* 数据入队
* @param num 要添加的数据
*/
public void add(int num) {
if (isFull()) {
System.out.println("队列满了,无法添加数据!");
return;
}
arrayQueue[rear] = num;
rear = (rear + 1) % maxSize;
}
/**
* 数据出队
* @return 返回出队的数据
*/
public int get() {
if (isEmpty()) {
throw new RuntimeException("队列为空,无法获取数据!");
}
int temp = arrayQueue[front];
front = (front + 1) % maxSize;
return temp;
}
/**
* 显示队头信息
*/
public void showHead() {
if (isEmpty()) {
System.out.println("队列为空,无法获取数据!");
return;
}
System.out.printf("%d", arrayQueue[front]);
}
public int getLength() {
return (rear - front + maxSize) % maxSize;
}
/**
* 显示整个队列信息
*/
public void show() {
if (isEmpty()) {
System.out.println("队列为空,无法获取数据!");
return;
}
for (int i = front; i < front + getLength(); i++) {
System.out.printf("%d\t", arrayQueue[i % maxSize]);
}
}
}