队列作为基础的数据结构,是程序员员的入门课。也是所有程序员必须掌握的一种数据结构,队列在程序中广泛应用,因此我们应该对队列有深入的了解。队列最主要的性质就是FIFO(First In First Out)先进先出,也就是说最先入队的最先出队,类比我们生活中的排队。也是队列最大的特征。接下来我们通过代码来对队列这种数据结构进行深度解析。
首先下面我们用Java中的List来定义一个最简单的队列:
package com.search;
import java.util.ArrayList;
import java.util.List;
/**
* @author lichao
* @version 1.0.0
* @date 2019-02-18
*/
public class QueueByList {
/**
* 用于存储元素
*/
private List<Object> list;
/**
* 指向队头
*/
private int front;
/**
* 构造函数
*/
public QueueByList() {
this.list = new ArrayList<Object>();
this.front = 0;
}
/**
* 往队列中插入元素
*/
public boolean enqueue(Object o) {
list.add(o);
return true;
}
/**
* 删除元素
*/
public boolean dequeue() {
if (isEmpty() == true) {
return false;
}
front++;
return true;
}
/**
* 获取队头元素
*/
public Object getFront() {
return list.get(front);
}
/**
* 检查队列是否非空
*/
public boolean isEmpty() {
return front >= list.size();
}
}
这种实现非常的一种实现方式,但是在某些情况下,存在着效率低下和空间浪费。在底层基于数组列表的队列中,随着队列中的的元素被删除(出队)。队首的空间将会被浪费。例如一下场景:当数组已经满了,而队头的元素已经出队,那么数组前面的空间将被浪费。针对这种情况。我们使用队列的第二种结构:循环队列;
我们用数组来存储循环队列,为了方便判断队列是否为空。我们需要一个额外空间:接下来我们看代码:
package com.search;
import java.util.ArrayList;
import java.util.List;
/**
* @author lichao
* @version 1.0.0
* @date 2019-02-18
*/
class MyCircularQueue {
private Integer[] queue;
private int head, tail, length;
/**
* 构造可以存放k个元素的队列;
* 因为我们在判断队列为空时还是队列为满时需要一个额外的空间,
* 因此声明数组大小为k+1
*/
public MyCircularQueue(int k) {
queue = new Integer[k+1];
head = 0;
tail = 0;
length = k+1;
}
/**
* 如果队列不满,则入队
*/
public boolean enQueue(int value) {
if (isFull()) {
return false;
}
tail = (tail + 1) % length;
queue[tail] = value;
return true;
}
/**
* 如果队列不空,则出队
*/
public boolean deQueue() {
if (isEmpty()) {
return false;
}
head = (head + 1) % length;
return true;
}
/**
* 获取对头元素
*/
public int Front() {
if(isEmpty()){
return -1;
}
return queue[head+1];
}
/**
* 获取队尾元素
*/
public int Rear() {
if(isEmpty()){
return -1;
}
return queue[tail];
}
/**
* 检查循环队列是否为空
*/
public boolean isEmpty() {
if (head == tail) {
return true;
}
return false;
}
/**
* 检查循环队列是否满,这里实际数组还有一个空间,但对于可以存储k个元素的队列已经满了。
*/
public boolean isFull() {
if (head == (tail + 1) % length) {
return true;
}
return false;
}
}