目录
一 . 什么是队列?
概念
队列 : 只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出FIFO(First In First Out) 入队列:进行插入操作的一端称为队尾(Tail/Rear) 出队列:进行删除操作的一端称为队头 (Head/Front).
如何实现一个队列?
实现队列有两种 :
1. 使用链表队列
分析 : 如果是单链表 : 使用尾插法的话那么入队的时间复杂度 : O(n),出队的时间复杂度 : O(1).
使用头插法的话入队的时间复杂度 : O(1) 出队的时间复杂度 : O(n).
如果是双向链表 : 入队和出队的时间复杂度 : O(1).
用单链表实现队列的话,可以给单链表尾部添加一个last变量,然后再去使用尾插的办法实现队列.
package demo1;
public class MyQueue {
static class Node{
public int val;
public Node next;
public Node(int val) {
this.val = val;
}
}
public Node head; //单链表头部
public Node last; //单链表尾部
//入队列
public boolean offer(int val) {
Node newNode = new Node(val);
if (isEmpty()) {
this.head = newNode;
this.last = newNode;
return true;
}
this.last.next = newNode;
this.last = newNode;
return true;
}
//出队列
public int poll() {
//如果队列为空的话 返回 -1
if (isEmpty()) {
return -1;
}
int val = this.head.val;
//判断只有一个节点的情况下
if (this.head == this.last) {
this.last = null;
}
this.head = this.head.next;
return val;
}
//获取队头元素
public int peek() {
//如果队列为空的话 返回一个 -1
if (isEmpty()) {
return -1;
}
return this.head.val;
}
//获取队列中有效元素个数
public int size() {
Node cur = this.head;
int count = 0;
while (cur != null) {
count++;
cur = cur.next;
}
return count;
}
//判断队列是否为空
public boolean isEmpty() {
return this.head == null;
}
}
2.. 使用数组来实现队列 (循环队列)
想要实现循环队列,我们就需要去解决几个问题 :
解决方法一 :
使用usedSize来记录有效数字个数!
package demo2;
import java.util.Arrays;
//循环队列
public class CircularQueue {
//用来记录数组的有效数字的个数
public int usedSize;
public int[] elem;
public int last;
public int first;
public CircularQueue(int[] arr) {
this.elem = new int[arr.length];
for (int i = 0; i < arr.length; i++) {
this.elem[i] = arr[i];
usedSize++;
}
this.first = 0;
this.last = usedSize % arr.length;
}
//入队列
public boolean offer(int val) {
if (isFull()) {
this.elem = Arrays.copyOf(this.elem,this.elem.length * 2);
this.last = usedSize;
}
this.elem[last] = val;
last = (last + 1) % this.elem.length;
usedSize++;
return true;
}
//出队列
public int poll() {
//如果数组为空 就返回一个 -1
if (isEmpty()) {
return -1;
}
int val = this.elem[first];
this.first = (this.first + 1) % this.elem.length;
usedSize--;
return val;
}
//获取队头元素
public int peek() {
//如果数组为空 就返回一个 -1
if (isEmpty()) {
return -1;
}
return this.elem[first];
}
public boolean isEmpty() {
return this.usedSize == 0;
}
//获取队列中有效元素个数
public int size() {
return usedSize;
}
//判断数组是否为满
public boolean isFull() {
return this.usedSize == this.elem.length;
}
}
解决方法二 :
class MyCircularQueue {
public int[] elem;
public int front;
public int rear;
public MyCircularQueue(int k) {
this.elem = new int[k+1];
}
//入列
public boolean enQueue(int value) {
//判断有没有满
if (isFull()) return false;
this.elem[rear] = value;
this.rear = (rear + 1) % elem.length;
return true;
}
//出列
public boolean deQueue() {
if (isEmpty()) return false;
this.front = (this.front + 1) % this.elem.length;
return true;
}
//获得队头元素
public int Front() {
if (isEmpty()) return -1;
return this.elem[this.front];
}
//获得队尾元素
public int Rear() {
if (isEmpty()) return -1;
if (rear == 0) {
return this.elem[elem.length-1];
} else {
return this.elem[rear-1];
}
}
public boolean isEmpty() {
if (front == rear) {
return true;
}
return false;
}
public boolean isFull() {
if ((this.rear+1) % this.elem.length == front) {
return true;
}
return false;
}
}
解决方法三 :
public class MyCircularQueue {
public int[] elem;
public int front;//队头下标
public int rear;//队尾下标
public boolean flag;
public MyCircularQueue(int k) {
this.elem = new int[k];
}
//入列
public boolean enQueue(int value) {
//判断有没有满
if (isFull()) return false;
this.elem[rear] = value;
this.rear = (rear + 1) % elem.length;
flag = true;
return true;
}
//出列
public boolean deQueue() {
if (isEmpty()) return false;
this.front = (this.front + 1) % this.elem.length;
flag = false;
return true;
}
//获得队头元素
public int Front() {
if (isEmpty()) return -1;
return this.elem[this.front];
}
//获得队尾元素
public int Rear() {
if (isEmpty()) return -1;
if (rear == 0) {
return this.elem[elem.length-1];
} else {
return this.elem[rear-1];
}
}
public boolean isEmpty() {
if (rear == front && !flag ) {
return true;
}
return false;
}
public boolean isFull() {
if (rear == front && flag) {
return true;
}
return false;
}
}
双端队列(Deque)
在java的集合类中提供了一种双端队列. Deque
public class Test {
public static void main(String[] args) {
//队列的三种创建方式
Queue<Integer> queue1 = new LinkedList<>();
Deque<Integer> queue2 = new LinkedList<>();
Deque<Integer> queue3 = new ArrayDeque<>();
//栈的三种创建方式
Stack<Integer> stack1 = new Stack<>();
Deque<Integer> stack2 = new LinkedList<>();
Deque<Integer> stack3 = new ArrayDeque<>();
}
}
队列到此就结束了.
希望可以帮到大家~~~~~~