网站首页 > 文章精选 正文
与前面提到的数据结构相同,队列中的数据也呈线性排列。虽然与栈有些相似,但队列中添加和删除数据的操作分别是在两端进行的,就和队列这个名字一样,把它想象成排成一队的人更容易理解。在队列中,处理总是从第一名开始往后进行,而新来的人只能排在队尾。
队列是什么?
如上就是队列的概念图,现在队列中只有数据 Blue。往队列中添加数据时,数据被加在最上面。
然后,队列中添加了数据 Green。往队列中添加数据的操作叫作入队。
紧接着,数据 Red 也入队了。
从队列中取出(删除)数据时,是从最下面,也就是最早入队的数据开始的,即 Blue。从队列中删除数据的操作叫作出队。
如果再进行一次出队操作,取出的就是 Green 了。
像队列这种最先进去的数据最先被取来,即先进先出的结构,我们称为 First In First Out,简称 FIFO。
与栈类似,队列中可以操作数据的位置也有一定的限制。在栈中,数据的添加和删除都在同一端进行,而在队列中则分别是在两端进行的。队列也不能直接访问位于中间的数据,必须通过出队操作将目标数据变成首位后才能访问。
介绍完队列的基本知识后,接下来举一个例子,比如生活中常见的排队买票。
如何理解队列?
队列这个概念非常好理解,你可以把它想象成排队买票,先来的先买,后来的人只能站末尾,不允许插队,先进者先出,这就是典型的队列。
上一篇讲到栈只支持两个基本操作:入栈和出栈。队列跟栈非常相似,支持的操作也很有限,最基本的操作也是两个:入队,放一个数据到队列尾部;出队,从队列头部取一个元素。
所以,队列跟栈一样,也是一种操作受限的线性表数据结构,队列的概念很好理解,基本操作也很容易掌握。作为一种非常基础的数据结构,队列的应用也非常广泛,特别是一些具有某些额外特性的队列,比如循环队列、阻塞队列、并发队列。
队列的实现
看到这里,相信你已经对队列有了初步的理解,队列主要包含两个操作,入队和出队。光理解还不够,我们还要动手去实现队列,接下来让我们来看一看如何用代码实现一个队列。
跟栈一样,队列可以用数组来实现,也可以用链表来实现。用数组实现的栈叫作顺序栈,用链表实现的栈叫作链式栈。同样,用数组实现的队列叫作顺序队列,用链表实现的队列叫作链式队列。
首先来看下用数组实现的队列是怎么样的,其实现如下图所示:
那么我先用 Java 语言来实现下顺序队列,代码如下:
/**
* 基于数组实现的顺序队列
*
* @author wupx
* @date 2020/02/13
*/
public class ArrayQueue {
private String[] items;
/**
* 数组大小
*/
private int n = 0;
/**
* 队头下标
*/
private int head = 0;
/**
* 队尾下标
*/
private int tail = 0;
/**
* 申请一个大小为 capacity 的数组
*
* @param capacity
*/
public ArrayQueue(int capacity) {
items = new String[capacity];
n = capacity;
}
/**
* 入队
*
* @param item
* @return
*/
public boolean enqueue(String item) {
// 如果 tail == n 表示队列已经满了
if (tail == n) {
return false;
}
items[tail] = item;
++tail;
return true;
}
/**
* 出队
*
* @return
*/
public String dequeue() {
// 如果 head == tail 表示队列为空
if (head == tail) {
return null;
}
String ret = items[head];
++head;
return ret;
}
}
另外一种就是链式队列,它的实现如下图所示:
再用链表去实现队列,代码如下:
/**
* 基于链表实现的链式队列
*
* @author wupx
* @date 2020/02/13
*/
public class LinkedListQueue {
/**
* 队头
*/
private Node head = null;
/**
* 队尾
*/
private Node tail = null;
/**
* 入队
*
* @param value
*/
public void enqueue(String value) {
if (tail == null) {
Node newNode = new Node(value, null);
head = newNode;
tail = newNode;
} else {
tail.next = new Node(value, null);
tail = tail.next;
}
}
/**
* 出队
*
* @return
*/
public String dequeue() {
if (head == null) {
return null;
}
String value = head.data;
head = head.next;
if (head == null) {
tail = null;
}
return value;
}
public void printAll() {
Node p = head;
while (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 = data;
this.next = next;
}
public String getData() {
return data;
}
}
}
到此,我们就分别实现了基于数组和链表的队列,大家可以自己实现下。
队列还有很多扩展,比如循环队列、阻塞队列、并发队列等,将在以后的文章中进行介绍。
总结
这篇主要讲了一种跟栈很相似的数据结构-队列,也是一种线性逻辑结构。
队列遵循先进先出(FIFO)的原则,主要的两个操作是入队和出队。队列既可以用数组来实现,也可以用链表来实现。用数组实现的叫顺序队列,用链表实现的叫链式队列。
参考
《我的第一本算法书》
- 上一篇: 数据结构:栈和队列的应用场景
- 下一篇: Python | 数据结构 - 队列
猜你喜欢
- 2025-05-26 什么是数据类型?
- 2025-05-26 C语言进阶教程:链表(单向、双向、循环)的实现与操作
- 2025-05-26 栈的经典面试题之用两个栈实现一个队列
- 2025-05-26 C# 之门课程系列-11
- 2025-05-26 24道几乎必问的JVM面试题,我只会7道,你能答出几道?
- 2025-05-26 大厂必备技能:数据结构之栈
- 2025-05-26 C++面试笔记--循环链表,队列,栈,堆
- 2025-05-26 Java程序员必须掌握的数据结构
- 2025-05-26 程序员必备:数据结构+算法知识大纲-全面细致,架构师熬夜总结
- 2025-05-26 数组、链表、队列和栈,四大基础数据结构详解
- 最近发表
-
- 面试中常被问到的Hash表,你了解吗
- JAVA面试考点:一文搞懂一致性Hash的原理和实现
- 一次性搞清楚equals和hashCode(hashcode() 与equals()区别,简单说明)
- HashMap.Key的故事:Key为什么出现Hash碰撞及冲突呢?
- hash冲突的几种解决方案对比(hash冲突的解决方式)
- 游戏王LN 无头骑士(无头骑士cv)
- Linux ln、unlink命令用法(linux link命令详解)
- n和l分不清矫正发音方法,这三步就够了
- golang引用私有gitlab项目代码(golang引入当前包下的文件)
- Instamic:录音领域中的 GoPro,让你想录就录,随心所欲
- 标签列表
-
- newcoder (56)
- 字符串的长度是指 (45)
- drawcontours()参数说明 (60)
- unsignedshortint (59)
- postman并发请求 (47)
- python列表删除 (50)
- 左程云什么水平 (56)
- 计算机网络的拓扑结构是指() (45)
- 编程题 (64)
- postgresql默认端口 (66)
- 数据库的概念模型独立于 (48)
- 产生系统死锁的原因可能是由于 (51)
- 数据库中只存放视图的 (62)
- 在vi中退出不保存的命令是 (53)
- 哪个命令可以将普通用户转换成超级用户 (49)
- noscript标签的作用 (48)
- 联合利华网申 (49)
- swagger和postman (46)
- 结构化程序设计主要强调 (53)
- 172.1 (57)
- apipostwebsocket (47)
- 唯品会后台 (61)
- 简历助手 (56)
- offshow (61)
- mysql数据库面试题 (57)