「这是我参与11月更文挑战的第4天,活动详情查看:2021最后一次更文挑战」
总结: 队列是一种常用的数据结构,是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。
前言
前端算法系列是我对算法学习的一个记录, 主要从常见算法
、数据结构
、算法思维
、常用技巧
几个方面剖析学习算法知识, 通过LeetCode平台实现刻意练习
, 通过掘金和B站的输出来实践费曼学习法
, 我会在后续不断更新优质内容并同步更新到掘金、B站和Github, 以记录学习算法的完整过程, 欢迎大家多多交流
、点赞
、收藏
, 让我们共同进步, daydayup👊
目录地址:目录篇
相关代码地址: Github
相关视频地址: 哔哩哔哩-百日算法系列
一、什么是队列
队列可能是我们日常生活中见到最多的一种数据结构, 例如我们每天进地铁时需要排队过安检、中午吃饭时需要排队打饭等, 都是队列在生活中的体现, 作为一种 线性表结构
我们通常将队列
和栈
做对比, 相比与栈的先入后出
, 队列则秉持先入先出
的原则.
我们把从队尾插入数据的过程叫 入队
我们把从队首删除数据的过程叫 出队
二、队列的特性
对比栈的特性, 队列有如下特下:
- 两端操作
- 先入先出原则
无它, 记住先入先出就好.
三、队列的应用
关于队列的应用, 我们最熟悉的莫过于浏览器中的消息队列
, 个人理解其实队列最大的作用就在于限流和缓冲
, 它使得我们可以将一些现在来不及处理
的事情按照顺序的存储起来, 在我们解决了当下的事情之后, 在未来按计划处理
剩余的事情.
- 线程池的任务队列
当一个进程之后涉及到频繁的线程创建和销毁时, 因为线程的创建代价很大, 为了让我们的线程不被频繁的创建和删除,所以我们提出线程池的概念, 而线程池中的线程是有数量限制的, 当线程池的任务不能处理大量的并发任务时, 我们可以创建一个队列用来缓冲
.
- CPU的超线程技术
- 线程池的任务队列
- 任务调度器
- 迷宫问题
- 杨辉三角
- 斐波那契数列
- 二叉树的广度优先搜索(BFS)
(求补充...)
其实, 像栈和队列这样简单的数据结构, 越简单应用的范围就越广, 同时也越基础, 很多时候只是作为算法的一小部分来展现.
四、队列的前端实现
关于队列的基础实现通常情况下有两种, 一种是通过数组实现的顺序队列
, 还有一种是通过链表实现的链式队列
, 两种方法实现的差别主要是数组与链表之间的差别.
此外, 在简单队列的基础上, 我们还有循环队列
、双端队列
、单调队列
、优先队列
等应用于不同场景的实现方式, 但这并不是本文的主要内容, 将会在后续队列文章中再做解析.
// 数组实现
function Queue(k) {
let head = 0
let tail = 0
let items = new Array(k)
// 尾部追加元素
this.enqueue = function (item) {
if (this.isFull()) return -1
items[tail] = item
tail++
}
// 头部删除元素
this.dequeue = function () {
if (this.isEmpty()) return
head++
}
// 返回队列头部
this.head = function () {
return items[head]
}
// 返回队列尾部
this.tail = function () {
return items[tail]
}
// 队列的大小
this.size = function () {
return tail - size
}
// 是否空队列
this.isEmpty = function () {
return tail === head
}
// 是否满
this.isFull = function () {
return tail === items.length
}
// 清空队列
this.clear = function () {
items = new Array(k)
}
// 打印
this.print = function () {
console.log(items)
}
}
五、队列的算法练习
// leetcode: https://leetcode-cn.com/
LeetCode #621 任务调度器
LeetCode #622 设计循环队列
LeetCode #641 设计循环双端队列
LeetCode #1670 设计前中后队列
LeetCode #933 最近的请求次数
LeetCode #面试题1709 第K个数
LeetCode #859 亲密字符串
LeetCode #860 柠檬水找零
LeetCode #969 煎饼排序
LeetCode #86 分隔链表
LeetCode #138 带随机指针的链表