队列
队列(Queue)是一种线性数据结构,具有先进先出的特点。在队列中,元素被加入到末尾,并从前端移除。
基础知识
1.队列是一种线性表,它只允许在一端插入元素,在另一端删除元素。
2.队列遵循先进先出的原则,即先插入的元素先被删除。
3.队列可以用数组或链表来实现,数组实现的队列称为顺序队列,链表实现的队列称为链式队列。
4.顺序队列需要维护两个指针,分别指向队头和队尾,每次插入或删除元素时,需要移动指针。
5.循环队列需要维护两个指针,分别指向队头和队尾,每次插入或删除元素时,需要移动指针,并取模运算。
6.循环队列需要保留一个空位,以区分队空和队满的情况。
代码实现队列
public class Queue<T> {
private Node<T> head; // 队头
private Node<T> tail; // 队尾
private int size; // 队列元素个数
// 定义节点类
private class Node<T> {
T data; // 数据域
Node<T> next; // 指针域
public Node(T data, Node<T> next) {
this.data = data;
this.next = next;
}
}
// 构造函数,初始化队列
public Queue() {
head = null;
tail = null;
size = 0;
}
// 入队
public void enqueue(T element) {
Node<T> newNode = new Node<T>(element, null);
if (tail == null) {
head = newNode;
tail = newNode;
} else {
tail.next = newNode;
tail = newNode;
}
size++;
}
// 出队
public T dequeue() {
if (head == null) {
return null;
}
T result = head.data;
head = head.next;
if (head == null) {
tail = null;
}
size--;
return result;
}
// 获取队首元素
public T front() {
if (head == null) {
return null;
}
return head.data;
}
// 获取队列大小
public int size() {
return size;
}
// 判断队列是否为空
public boolean isEmpty() {
return size == 0;
}
}
代码逻辑分析
(1)首先定义一个泛型类Queue,表示队列中的元素可以是任意类型T。
(2)然后定义了一个内部类Node,表示队列中的节点,每个节点包含一个数据域和一个指针域。
(3)接着定义了三个私有属性:head表示队头,tail表示队尾,size表示队列元素个数。
(4)然后定义了一个构造函数,用来初始化队列,将head、tail和size都设为null或0。
(5)接着定义了一个入队方法enqueue(T element),用来向队尾插入一个元素,具体步骤:
1)创建一个新的节点newNode,将element作为数据域,null作为指针域。
2)判断tail是否为空,如果为空,说明队列为空,那么将head和tail都指向newNode。
3)如果不为空,说明队列不为空,那么将tail的指针域指向newNode,然后将tail更新为newNode。
4)最后,将size加一。
(6)接着定义了一个出队方法dequeue(),用来从队头删除并返回一个元素,具体步骤:
1)判断head是否为空,如果为空,说明队列为空,那么返回null。
2)如果不为空,说明队列不为空,那么将head的数据域赋值给result。
3)然后将head更新为head的指针域。
4)如果head为空,说明队列只有一个元素被删除了,那么将tail也设为null。
5)最后,将size减一,并返回result。
(7)接着定义了一个获取队首元素方法front(),用来从队头返回但不删除一个元素,具体步骤:
1)判断head是否为空,如果为空,说明队列为空,那么返回null。
2)如果不为空,说明队列不为空,那么返回head的数据域。
(8)接着定义了一个获取队列大小方法size(),用来返回size属性的值。
(9)最后定义了一个判断队列是否为空方法isEmpty(),用来判断size属性是否等于0。