《数据结构与算法之美》——队列
什么是队列
- 队列是一种线性表数据结构,和栈类似
- 它操作受限,表现为先进先出,后进后出
- 它有头指针和尾指针之分,删除元素从head操作,添加元素从tail操作
文章图片
image.png 常见的队列
队列的花样比较多,这源于它的灵活性和众多的应用场景。
比如当初在学习数据结构这门课的时候,肯定听说过循环队列。
了解Java并发的时候,肯定知道并发队列
顺序队列和链式队列
和前面的栈数据结构一样,使用数组实现的队列就是顺序队列,使用链表实现的队列就是链式队列。
使用数组结构实现的队列
package com.jackie.algo.geek.time.chapter9_queue;
/**
* @Author: Jackie
* @date 2018/12/15
*
* 基于数组数据结构的队列实现
*/
public class ArrayQueue {
// 数组items
private String[] items;
// 数组大小
private int n = 0;
// 数组头下标
private int head = 0;
// 数组尾下标
private int tail = 0;
public ArrayQueue(int capacity) {
items = new String[capacity];
n = capacity;
}
/**
* 入队
*/
public boolean enqueue(String ele) {
// 队列满了
if (tail == n) {
return false;
}
items[tail++] = ele;
return true;
}
/**
* 出队
*/
public String dequeue() {
if (head == tail) {
return null;
}
return items[head++];
}
/**
* 打印所有队列元素
*/
public void printAll() {
for (int i = head;
i < tail;
i++) {
System.out.print(items[i] + " ");
}
System.out.println();
}
}
使用链表结构实现的队列
package com.jackie.algo.geek.time.chapter9_queue;
/**
* @Author: Jackie
* @date 2018/12/15
*
* 基于链表数据结构的队列实现
* 注意:和基于数据实现的队列{@link ArrayQueue}不同,这里没有n这个参数,
* 因为基于链表实现是无界的,基于数据实现需要定于数组的大小
*/
public class LinkedQueue {
// 头指针
private Node head = null;
// 尾指针
private Node tail = null;
/**
* 入队
*/
public void enqueue(String ele) {
if (head == null) {
Node node = new Node(ele, null);
head = node;
tail = node;
} else {
tail.next = new Node(ele, null);
tail = tail.next;
}
}
/**
* 出队
*/
public String dequeue() {
if (head == null) {
return null;
}
String ret = head.data;
head = head.next;
// 如果出队后,头指针head为null,则同时置tail为null
if (head == null) {
tail = null;
}
return ret;
}
public void printAll() {
Node p = head;
if (p != null) {
System.out.print(p.data + " ");
p = p.next;
}
System.out.println();
}
private static class Node {
private String data;
private Node next;
public Node(String data, Node next) {
this.data = https://www.it610.com/article/data;
this.next = next;
}
public String getData() {
return data;
}
}
}
具体代码,参见GitHub项目rome
顺序队列和链式队列的不同点
- 顺序队列使用数组实现,所以有数组大小的限制,在数据结构中有对应的属性
n
- 顺序队列队空条件为:head == tail;
队满条件为:tail == n。
- 链式队列队空条件为:head == null;
队满条件要取决于队列的长度
文章图片
image.png 这样下去,会造成更多的内存浪费,无法存储更多的数据。所以,需要进行数据搬移,具体过程如下
文章图片
image.png 代码实现也比较简单,具体如下
// 入队操作,将 item 放入队尾
public boolean enqueue(String item) {
// tail == n 表示队列末尾没有空间了
if (tail == n) {
// tail ==n && head==0,表示整个队列都占满了
if (head == 0) return false;
// 数据搬移
for (int i = head;
i < tail;
++i) {
items[i-head] = items[i];
}
// 搬移完之后重新更新 head 和 tail
tail -= head;
head = 0;
}
items[tail] = item;
++tail;
return true;
}
循环队列
针对上面提到的tail == n无法入队的情况,除了数据搬移,还可以使用这里的循环队列来解决。
循环队列是将上面提到的队列首尾相接形成的环形队列。
不同于顺序队列的队空条件head==tail和队满条件tail==n。
【《数据结构与算法之美》——队列】循环队列的队空条件依然是head==tail,队满的条件为:(tail+1)%n = head
推荐阅读
- 慢慢的美丽
- 《真与假的困惑》???|《真与假的困惑》??? ——致良知是一种伟大的力量
- 《跨界歌手》:亲情永远比爱情更有泪点
- 诗歌:|诗歌: 《让我们举起世界杯,干了!》
- 期刊|期刊 | 国内核心期刊之(北大核心)
- 《魔法科高中的劣等生》第26卷(Invasion篇)发售
- 人间词话的智慧
- 《一代诗人》37期,生活,江南j,拨动心潭的一泓秋水
- 广角叙述|广角叙述 展众生群像——试析鲁迅《示众》的展示艺术
- 书评——《小行星》