概念
队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。队列中没有元素时,称为空队列。
使用数组表示队列
- 上图是队列中依次添加0 1 2三个元素
- front是队列的第一元素的前一个位置
- rear是队列中的最后一个元素的位置
- 当front=rear的时候队列为空
- 取出元素从队列头开始取,如下图取出0元素
使用数组实现上面的队列代码:
package com.liouxb.data.structure;
/**
* 队列
*
* @author liouwb
*/
public class QueueDemo {
public static void main(String[] args) {
}
}
/**
* 使用数组实现队列
*/
class ArrayQueue {
// 队列(集合)的最大长度
private int maxSize;
// 队列头
private int front;
// 队列尾
private int rear;
// 数据集合
private int[] arrQueue;
/**
* 构造函数
*/
public ArrayQueue(int maxSize) {
this.maxSize = maxSize;
this.arrQueue = new int[maxSize];
// 指向队列头数据的前一个位置
this.front = -1;
// 最后一个数据的位置
this.rear = -1;
}
/**
* 判断队列是否已满
*
* @return
*/
boolean isFull() {
return this.rear == this.maxSize - 1;
}
/**
* 判断队列是否为空
*
* @return
*/
boolean isEmpty() {
return this.rear == this.front;
}
/**
* 向队列中添加数据
*/
void addQueue(int param) {
// 1、判断队列是否满
if (isFull()) {
System.out.println("队列已满,请等待。。。");
}
// 尾部向后移
this.rear++;
arrQueue[rear] = param;
}
/**
* 从队列中获取数据
*/
int popQueue() {
if (isEmpty()) {
throw new RuntimeException("队列为空");
}
// 头部后移
this.front++;
return this.arrQueue[front];
}
/**
* 获取队列所有数据
*/
void showAllQueue() {
if (isEmpty()) {
System.out.println("队列为空");
return;
}
for (int i = 0; i < arrQueue.length; i++) {
System.out.println(arrQueue[i]);
}
}
}
环形队列
判断环形队列满的方式
- 使用一个变量size做标记,添加元素size+1,取出元素size-1
- 使用n-1个空间表示
- 使用标识位flag来表示最后一次的操作状态,fornt=rear,flag添加的话表示队列是满的,flag是取出操作的话则表示队列为空
使用数组实现环形队列代码
package com.liouxb.data.structure;
/**
* 环形队列
* 数组实现
*
* @author liouwb
*/
public class QueueCircleDemo {
public static void main(String[] args) {
}
}
/**
* 使用数组实现环形队列
*/
class CircleArrayQueue {
// 队列(集合)的最大长度
private int maxSize;
// 队列头
private int front;
// 队列尾
private int rear;
// 数据集合
private int[] arrQueue;
/**
* 构造函数
*/
public CircleArrayQueue(int maxSize) {
this.maxSize = maxSize;
this.arrQueue = new int[maxSize];
// 指向队列头数据的第一个元素的位置
this.front = 0;
// 最后一个元素的后一个位置
this.rear = 0;
}
/**
* 环形队列判断是否已满
*
* @return
*/
boolean isFull() {
return (this.rear + 1) / this.maxSize == this.front;
}
/**
* 判断队列是否为空
*
* @return
*/
boolean isEmpty() {
return this.rear == this.front;
}
/**
* 向队列中添加数据
*/
void addQueue(int param) {
// 1、判断队列是否满
if (isFull()) {
System.out.println("队列已满,请等待。。。");
}
arrQueue[rear] = param;
// 尾部向后移
this.rear = (rear + 1) % maxSize;
}
/**
* 从队列中获取数据
*/
int popQueue() {
if (isEmpty()) {
throw new RuntimeException("队列为空");
}
// 1、用一个临时变量保存要取的元素
// 2、front后移
// 3、返回临时变量
int temp = 0;
temp = this.arrQueue[front];
// 头部后移
this.front = (this.front + 1) / maxSize;
return temp;
}
/**
* 获取队列所有数据
*/
void showAllQueue() {
if (isEmpty()) {
System.out.println("队列为空");
return;
}
// 从front开始遍历:需要遍历有效数据个数
int count = count();
for (int i = front; i < front + count; i++) {
System.out.println(arrQueue[i]);
}
}
/**
* 获取环形队列有效元素个数
* (rear+maxSize-front)%maxSize
*
* @return
*/
private int count() {
return (rear + maxSize - front) % maxSize;
}
}