队列
队列介绍
- 队列是一个有序列表,可以通过数组或者链表进行实现;
- 队列遵循先进先出原则,与现实生活中的排队买东西类似;
队列数组实现思路
由于队列是有序列表,数组也为有序列表,数组存入的顺序即为队列入队顺序,数组大小即为队列最大容量maxSize。
因为队列遵循先进先出,因此需要两个变量front与rear分别来记录队头与队尾的位置,front指向队列头部前一个位
置,而rear指向队列尾部元素,即最后一个元素。 rear随着数据进入队列而变动,每存入一个数据rear++,而front
随着数据从队列中取出而变动,每取一个数据front++。
一般认为,当front == rear时,队列为空;当rear == maxSize - 1时,队列已满。
代码实现
package queue.arrayqueue;
/**
* @author Eleven
* @version V1.0
* @package: queue.arrayqueue
* @date 2021-10-24 21:36
*/
public class ArrayQueueDemo {
private int maxSize;
private int front;
private int rear;
private int[] arr;
private static final int DEFAUL_SIZE = 16;
public ArrayQueueDemo() {
this.front = -1;
this.rear = -1;
this.maxSize = DEFAUL_SIZE;
arr = new int[DEFAUL_SIZE];
}
public ArrayQueueDemo(int maxSize) {
this.front = -1;
this.rear = -1;
this.maxSize = maxSize;
arr = new int[maxSize];
}
//判断队列是否已满
public boolean isFull() {
return this.rear == maxSize - 1;
}
public boolean isEmpty() {
return this.front == this.rear;
}
//进入队列
public void put(int num) {
if (isFull()) {
throw new RuntimeException("队列已满");
}
arr[++rear] = num;
}
//从队列中取出
public int get() {
if (isEmpty()) {
throw new RuntimeException("队列为空");
}
return arr[++front];
}
//查看队列
public void show() {
if (isEmpty()) {
throw new RuntimeException("队列为空");
}
for (int i = 0; i < arr.length; i++) {
System.out.printf("arr[%d]=%d\n", i, arr[i]);
}
}
//查看队头数据
public void peekHead(){
if (isEmpty()) {
throw new RuntimeException("队列为空");
}
System.out.println("队头数据为:" + arr[front + 1]);
}
//查看队列大小
public int getSize(){
return maxSize;
}
}
测试代码
package queue.arrayqueue;
import org.junit.Before;
import org.junit.Test;
import java.util.Scanner;
/**
* @author Eleven
* @version V1.0
* @package: queue.arrayqueue
* @date 2021-10-24 22:13
*/
public class ArrayQueueTest {
public static void main(String[] args) {
ArrayQueueDemo aqd = new ArrayQueueDemo(2);
Scanner scanner = new Scanner(System.in);
while (true){
System.out.println("1、查看队列 ");
System.out.println("2、进入队列 ");
System.out.println("3、取出队列 ");
System.out.println("4、查看队列头部数据 ");
System.out.println("5、查看队列大小 ");
System.out.println("6、退出 ");
System.out.println("请输入选择:");
char c = scanner.next().charAt(0);
switch (c){
case '1':
try {
aqd.show();
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case '2':
try {
System.out.println("请输入加入数据");zh
int i = Integer.parseInt(scanner.next());
aqd.put(i);
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case '3':
try {
aqd.get();
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case '4':
try {
aqd.peekHead();
} catch (Exception e) {
System.out.println(e.getMessage());
}
break;
case '5':
System.out.println("队列大小为:" + aqd.getSize());
break;
case '6':
System.out.println("成功退出!");
return;
}
}
}
}
环形队列
环形队列介绍
普通数组队列,当rear到达数组尾部后,就无法在存入数据,无论前方的数据是否已经被取走,导致队列是一次性的
对普通数组队列进行优化,充分利用数组,因此将数组看作是一个环形的。(通过取模来实现)。
环形队列实现思路
与上述队列不同,环形队列的front指向队列头部元素,即队列第一个元素,而rear指向队尾的后一个位置,即最后一个元素后。
认为当(rear + 1) % maxSize == front 时,队列已满。当rear == front 时,队列为空 。
代码实现
package queue.circlequeue;
/**
* 自己编写一个环形队列
* @author Eleven
* @version V1.0
* @package: queue.circlequeue
* @date 2021-10-25 19:20
*/
public class CircleQueue {
//记录队列头部数据的索引
private int front;
//记录队列尾部索引,其指向尾部数据的下一个位置的索引
private int rear;
//队列数组大小,但是队列的最大容量为maxSize-1
private int maxSize;
//用于存放队列数据的数组
private int[] arr;
//队列数组的默认大小
private final int DEFAULT_SIZE = 16;
public CircleQueue() {
this.maxSize = DEFAULT_SIZE;
arr = new int[this.maxSize];
front = 0;
rear = 0;
}
public CircleQueue(int maxSize) {
this.maxSize = maxSize;
arr = new int[this.maxSize];
front = 0;
rear = 0;
}
/**
* 判断队列是否已满
* 创建时间:2021/10/25 19:49
* @author Eleven
* @return
*/
public boolean isFull() {
return (rear + 1) % maxSize == front;
}
/**
* 判断是否为空
* 创建时间:2021/10/25 19:49
* @author Eleven
* @return
*/
public boolean isEmpty() {
return rear == front;
}
/**
* 将数据加入队列
* 创建时间:2021/10/25 19:50
* @author Eleven
* @param num 要加入队列的数据
* @return
*/
public void put(int num) {
if (isFull()) throw new RuntimeException("队列已满!");
arr[rear] = num;
rear = (rear + 1) % maxSize;
}
/**
* 将数据从队列中取出
* 创建时间:2021/10/25 19:50
* @author Eleven
* @return
*/
public int get() {
if (isEmpty()) throw new RuntimeException("队列为空!");
int temp = arr[front];
front = (front + 1) % maxSize;
return temp;
}
/**
* 列出在队列中的所有数据
* 创建时间:2021/10/25 19:53
* @author Eleven
* @return
*/
public void show() {
if(isEmpty()) throw new RuntimeException("队列为空!");
for (int i = front; i <front+getSize(); i++) {
System.out.printf("a[%d]=%d\n", i%maxSize, arr[i%maxSize]);
}
}
/**
* 获取队列中的数据个数
* 创建时间:2021/10/25 19:54
* @author Eleven
* @param
* @return
*/
public int getSize() {
return (rear + maxSize - front) % maxSize;
}
/**
* 查看头部数据
* 创建时间:2021/10/25 20:12
* @author Eleven
* @return
*/
public int peekHead(){
if(isEmpty()) throw new RuntimeException("队列为空!");
return arr[front];
}
}