本文章参考了以下作者的博客:
https://www.cnblogs.com/smyhvae/p/4793339.html
https://blog.youkuaiyun.com/qq_38410730/article/details/79587711
一、队列的定义:
1、术语:
队列(Queue):是一种只允许在表的一端进行插入或删除操作的线性表。队列的数据元素以及数据元素间的逻辑关系和线性表完全相同,其差别是线性表允许在任意位置插入和删除,而队列只允许在其一端进行插入操作在其另一端进行删除操作。
队首:队列中允许进行删除操作的一端
队尾:队列中允许进行插入操作的一端
空队列:没有元素的队列
入队列:将数据元素插入队尾
出队列:将对头元素删除并由函数返回
2、队列的特点:
“先进先出”,或者叫“后进后出”。
3、队列的抽象数据类型:
数据元素:可以是任意类型,用泛型表示
数据关系:数据元素之间是线性关系
数据操作:入队列、出队列、取队列头元素、判断队列是否为空、判断队列是否为满
我们定义抽象数据类型如下:
package codingTest2;
public interface IQueue<E> {
boolean enquence(E item);
E dequeue();//出队列操作
E peek();//取队列的头元素
int size();//队列的大小
boolean isEmpty();//判断队列是否为空
boolean isFull();//判断队列是否为满
}
二、顺序队列
1、定义:顺序队列通常采用一维数组存储队列中的元素,另外增加两个指针分别指示数组中存放的队首元素和队尾元素。其中指向队首元素的指针称为队头指针front,指向队尾元素的指针称为队尾指针rear。
2、特点
package codingTest2;
import java.lang.reflect.Array;
/*
*
* 参考了https://blog.youkuaiyun.com/qq_38410730/article/details/79587711的实现思路*/
public class arraysSequentialQueue<E> implements IQueue<E>{
private int maxSize;//设置队列的容量
private E[] data;//存储循环顺序队列中的元素
private int front;//指示最近一个己经离开队列的元素所占的位置
private int rear;//指示最近一个进行入队列的元素的位置
public arraysSequentialQueue(Class<E> type, int maxSize){
data = (E[])Array.newInstance(type, maxSize);
this.maxSize = maxSize;
front = rear = -1;
}
//入队列
@Override
public boolean enquence(E item) {
if(!isFull()) {
rear = (rear + 1) % maxSize;
data[rear] = item;
return true;
}else {
return false;
}
}
//出队列操作
@Override
public E dequeue() {
if(!isEmpty()) {
front = (front + 1) %maxSize;
return data[front];
}else {
return null;
}
}
//取队首元素
@Override
public E peek() {
if(!isEmpty()) {
return data[(front + 1) % maxSize];
}else {
return null;
}
}
//
@Override
public int size() {
return (rear - front + maxSize) % maxSize;
}
//判断队列是否为空
@Override
public boolean isEmpty() {
if(rear == front) {
return true;
}else {
return false;
}
}
//判断队列是否为满
@Override
public boolean isFull() {
if(rear == maxSize && front == -1 || (rear+1) % maxSize == front) {
return true;
}else {
return false;
}
}
}
三、链式队列
1、定义: 它实际上是一个同时带有队头指针和队尾指针的单链表。头指针指向队头节点,尾指针指向队尾节点,即单链表的最后一个节点。
2、特点
package codingTest2;
public class QueueNode<E> {
private E data;
private QueueNode<E> next;
public QueueNode() {}
public QueueNode(E data) {
this.data = data;
}
public QueueNode(E data, QueueNode<E> next) {
this.data = data;
this.next = next;
}
public E getData() {
return data;
}
public void setData(E data) {
this.data = data;
}
public QueueNode<E> getNext() {
return next;
}
public void setNext(QueueNode<E> next) {
this.next = next;
}
}
package codingTest2;
public class arraysLinkedQueue<E> implements IQueue<E>{
private int maxSize;
private int size;
private QueueNode<E> front;//队列头指示器
private QueueNode<E> rear;//队列尾指示器
//初始化队列
public arraysLinkedQueue() {
front = rear = null;
size = 0;
maxSize = 0;
}
//初始化限容的链队列
public arraysLinkedQueue(int maxSize) {
super();
this.maxSize = maxSize;
}
//数据入队
@Override
public boolean enquence(E item) {
QueueNode<E> newNode = new QueueNode<E>();
if(!isFull()) {
if(isEmpty()) {
front = newNode;
rear = newNode;
}else {
rear.setNext(newNode);;
rear = newNode;
}
++ size;
return true;
}else {
return false;
}
}
//
@Override
public E dequeue() {
if (isEmpty()) {
return null;
}
QueueNode<E> node = front;
front = front.getNext();
if (front == null) {
rear = null;
}
--size;
return node.getData();
}
//取队首元素
@Override
public E peek() {
if(!isEmpty()){
return front.getData();
}else{
return null;
}
}
//求队列的大小
@Override
public int size() {
return size;
}
//判断队列是否为空
@Override
public boolean isEmpty() {
if((front == rear) && (size == 0)) {
return true;
}else {
return false;
}
}
//判断队列是否为满
@Override
public boolean isFull() {
if(maxSize != 0 && size == maxSize) {
return true;
}else {
return false;
}
}
}