一、什么是队列:
一种先进先出的数据结构(FIFO结构)。新元素添加在队尾(push),删除操作删掉第一个元素(pop)
二、队列的实现方式:
队列的实现方式数组实现、链表实现
三、常见的队列:
常用队列循环队列、阻塞队列、并发队列
四、怎么实现一个无BUG的队列思考
思考1:head(头元素)和tail(尾元素)的初始值
思考2:队列什么情况算下算是满了,(tail + 1) % capacity == head
思考3:队列什么情况下算是空的
思考4:特殊情况,数组为空,数组为1,数组无限大等情况
能想清楚边界问题和特殊情况就能更好的编写代码
五、数组实现队列
数组是连续的内存地址,所以需要数组整理
package com.sp.queue;
import com.alibaba.fastjson.JSON;
/**
* 数组实现队列
*
* @param <T>
*/
public class ArrayQueue<T> {
//队列长度
int length = 0;
//头元素 坐标
int head = 0;
//尾元素 坐标
int tail = 0;
Object[] queueArray = null;
public ArrayQueue(int length) {
if (length < 0) {
throw new IndexOutOfBoundsException("长度不能小于0");
}
this.length = length;
queueArray = new Object[length];
}
/**
* 尾部添加元素,同时元素自动整理排序
*
* @param t
* @return
*/
public boolean push(T t) {
if (tail == length) {
if (head == 0) {
return false;
}
for (int i = head; i < tail; i++) {
queueArray[i - head] = queueArray[i];
}
tail = tail - head;
head = 0;
}
queueArray[tail++] = t;
return true;
}
/**
* 头部删除元素
*
* @return
*/
public boolean pop() {
if (head >= tail) {
return false;
}
queueArray[head] = null;
head++;
return true;
}
@Override
public String toString() {
return JSON.toJSONString(queueArray);
}
public static void main(String[] args) {
ArrayQueue<Integer> queue = new ArrayQueue<>(5);
queue.push(1);
queue.push(2);
queue.push(3);
System.out.println(queue);
queue.pop();
System.out.println(queue);
queue.pop();
System.out.println(queue);
queue.push(4);
System.out.println(queue);
queue.push(5);
System.out.println(queue);
queue.push(6);
System.out.println(queue);
queue.push(7);
System.out.println(queue);
queue.pop();
System.out.println(queue);
queue.pop();
System.out.println(queue);
queue.pop();
System.out.println(queue);
queue.pop();
System.out.println(queue);
queue.pop();
System.out.println(queue);
queue.pop();
System.out.println(queue);
}
/*//测试 无重新排序的 队列
public static void main(String[] args) {
ArrayQueue<Integer> queue = new ArrayQueue<>(5);
queue.push(1);
queue.push(2);
queue.push(3);
System.out.println(queue);
queue.pop();
System.out.println(queue);
queue.pop();
System.out.println(queue);
}*/
}
六、 链表实现的队列
链表不需要初始化长度,添加和删除方便
package com.sp.queue;
import com.alibaba.fastjson.JSON;
/**
* 链表实现的队列
*
* @param <T>
*/
public class CircularQueue<T> {
//队列长度
int length = 0;
//头元素 坐标
int head = 0;
//尾元素 坐标
int tail = 0;
Object[] queueArray = null;
public CircularQueue(int length) {
if (length < 0) {
throw new IndexOutOfBoundsException("长度不能小于0");
}
this.length = length;
queueArray = new Object[length];
}
public boolean push(T t) {
if ((tail + 1) % length == head) {
return false;
}
queueArray[tail % length] = t;
tail = (tail + 1) % length;
return true;
}
public boolean pop() {
if ((head + 1) % length == tail) {
return false;
}
queueArray[head] = null;
head = (head + 1) % length;
return true;
}
@Override
public String toString() {
return JSON.toJSONString(queueArray);
}
public static void main(String[] args) {
CircularQueue<Integer> queue = new CircularQueue<>(5);
queue.push(1);
queue.push(2);
queue.push(3);
System.out.println(queue);
queue.push(4);
queue.push(5);
queue.push(6);
System.out.println(queue);
queue.pop();
System.out.println(queue);
queue.push(7);
System.out.println(queue);
queue.pop();
System.out.println(queue);
queue.push(8);
System.out.println(queue);
queue.push(9);
System.out.println(queue);
queue.pop();
System.out.println(queue);
queue.push(10);
System.out.println(queue);
}
}
七、使用数组实现循环队列
循环队列就不需要整理数组的空值了,如同一个环形添加
public class MyCircularQueue {
//创建循环队列的数组
private Integer[] queue;
//头元素
private int head = 0;
//尾元素
private int tail = 0;
//队列容量
private int capacity;
/**
* Initialize your data structure here. Set the size of the queue to be k.
*/
public MyCircularQueue(int k) {
queue = new Integer[k];
capacity = k;
}
/**
* Insert an element into the circular queue. Return true if the operation is successful.
*/
public boolean enQueue(int value) {
if (queue[head] == null) {
queue[tail = head] = value;
System.out.println("添加成功 true head = " + head + ", tail = " + tail + ", queue:" + JSON.toJSONString(queue));
return true;
}
if (isFull()) {
System.out.println("队列已满");
return false;
}
queue[tail = (tail + 1) % capacity] = value;
System.out.println("添加成功 true head = " + head + ", tail = " + tail + ", queue:" + JSON.toJSONString(queue));
return true;
}
/**
* Delete an element from the circular queue. Return true if the operation is successful.
*/
public boolean deQueue() {
if (isEmpty()) {
System.out.println("队列为空");
return false;
}
queue[head] = null;
head = (head + 1) % capacity;
if (isEmpty()) {
tail = head;
}
System.out.println("删除成功 true head = " + head + ", tail = " + tail + ", queue:" + JSON.toJSONString(queue));
return true;
}
/**
* Get the front item from the queue.
*/
public int Front() {
return isEmpty() ? -1 : queue[head];
}
/**
* Get the last item from the queue.
*/
public int Rear() {
return isEmpty() ? -1 : queue[tail];
}
/**
* Checks whether the circular queue is empty or not.
*/
public boolean isEmpty() {
return queue[head] == null;
}
/**
* Checks whether the circular queue is full or not.
*/
public boolean isFull() {
return capacity == 1 ? queue[head] != null : (tail + 1) % capacity == head;
}
public static void main(String[] args) {
MyCircularQueue circularQueue = new MyCircularQueue(3); // 设置长度为3
circularQueue.enQueue(1); // 返回true
circularQueue.deQueue(); // 返回true
System.out.println(circularQueue.isFull());
circularQueue.enQueue(2); // 返回true
circularQueue.enQueue(3); // 返回true
}
// public static void main(String[] args) {
// MyCircularQueue circularQueue = new MyCircularQueue(3); // 设置长度为3
// System.out.println("是否为空!" + circularQueue.isEmpty());
// System.out.println("是否已满!" + circularQueue.isFull());
// circularQueue.enQueue(1); // 返回true
// circularQueue.deQueue(); // 返回true
// circularQueue.enQueue(2); // 返回true
// System.out.println(circularQueue.Rear()); // 返回2
// }
// public static void main(String[] args) {
// MyCircularQueue circularQueue = new MyCircularQueue(3); // 设置长度为3
// System.out.println("是否为空!" + circularQueue.isEmpty());
// System.out.println("是否已满!" + circularQueue.isFull());
// circularQueue.enQueue(1); // 返回true
// circularQueue.enQueue(2); // 返回true
// circularQueue.enQueue(3); // 返回true
// circularQueue.enQueue(4); // 返回false,队列已满
// System.out.println(circularQueue.Rear()); // 返回3
// System.out.println(circularQueue.isFull()); // 返回true
// circularQueue.deQueue(); // 返回true
// circularQueue.enQueue(4); // 返回true
// System.out.println(circularQueue.Rear()); // 返回4
//
// circularQueue.deQueue(); // 返回true
// circularQueue.deQueue(); // 返回true
// circularQueue.deQueue(); // 返回true
// circularQueue.deQueue(); // 返回true
// circularQueue.deQueue(); // 返回true
//
// }
}