八大数据结构——队列(六)
常用的主要有八大类型:1.数组(Array)2.栈(Stack)3.链表(Linked List)4.图(Graph)5.散列表(哈希表)(Hash)6.队列(Queue)7.树(Tree)8.堆(Heap)。
队列定义(百度解释): 队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。
队列,顾名思义,就是和生活中排队一样,两边用栅栏围起来了,只有一条直线通道,老老实实排队,而且是很和谐的,绝对不给插队。排队的人必须办完事,不会不排,扭头走掉。就是一头只许进,另一头只许出。
特性:
数据先进先出。
适用场景: 需要实现先进先出算法的,数据需要保持进入的前后顺序的,比如一些任务队列。
java代码实现
下面通过Java来实现一个队列,基于jdk1.8。我们这里使用数组实现。
1.定义要用的属性。一个数组用来存储数据,一个指针front用来存储当前数据的头部位置,一个rear指针用来存储数据的尾部位置,一个size指针记录已存储数据个数,最后一个默认大小。
private Type[] elements;//存储数据单元
private int front;//头指针
private int rear;//尾指针
private int size;//记录目前元素个数
private static final int Default_size = 10;//默认大小
2.构造方法和清空队列的方法,清空队列就是将三个指针都置为0,不用真正删除数据 。
public Queue() {//无大小参数的默认构造方法
elements = (Type[]) new Object[Default_size];
clear();
}
public Queue(int size) {//传入大小参数的构造方法
elements = (Type[]) new Object[size];
clear();
}
public void clear() {//清空数组,实际是把指针调到初始位置,之前数据在未被覆盖前依然存在
front = 0;
rear = 0;
size = 0;
}
3.关于如何使用三个指针来记录队列,看示意图。
我们使用取余操作,可以实现对指针在数组上循环移动,就如同图中,将数组前后两端连起来了(实际不是连起来的),一开始队头和队尾指针都在0,然后入队,队尾指针就往下走,出队,队头指针也往下走。当队头和队尾指针相遇,且size等于数组长度,说明队列容量已经满了。
public boolean add(Type val) {//添加元素进队尾
if (size == elements.length) {
return false;
}
elements[rear] = val;
rear = (rear + 1) % elements.length;
size++;
return true;
}
public Type peek() {//查看队头元素,但不拿出
if (size == 0)
return null;
return elements[front];
}
public Type remove() {//移除并返回队头元素
if (size == 0)
throw new NoSuchElementException();
Type t = elements[front];
front = (front + 1) % elements.length;
size--;
return t;
}
完整代码
import java.util.NoSuchElementException;
//实现一个队列
public class Queue<Type> {
private Type[] elements;//存储数据单元
private int front;//头指针
private int rear;//尾指针
private int size;//记录目前元素个数
private static final int Default_size = 10;//默认大小
public Queue() {//无大小参数的默认构造方法
elements = (Type[]) new Object[Default_size];
clear();
}
public Queue(int size) {//传入大小参数的构造方法
elements = (Type[]) new Object[size];
clear();
}
public void clear() {//清空数组,实际是把指针调到初始位置,之前数据在未被覆盖前依然存在
front = 0;
rear = 0;
size = 0;
}
public boolean add(Type val) {//添加元素进队尾
if (size == elements.length) {
return false;
}
elements[rear] = val;
rear = (rear + 1) % elements.length;
size++;
return true;
}
public Type peek() {//查看队头元素,但不拿出
if (size == 0)
return null;
return elements[front];
}
public Type remove() {//移除并返回队头元素
if (size == 0)
throw new NoSuchElementException();
Type t = elements[front];
front = (front + 1) % elements.length;
size--;
return t;
}
}