mirror of
https://github.com/krahets/hello-algo.git
synced 2026-02-13 15:45:41 +08:00
build
This commit is contained in:
@@ -4,9 +4,9 @@ comments: true
|
||||
|
||||
# 5.2 队列
|
||||
|
||||
「队列 queue」是一种遵循先入先出规则的线性数据结构。顾名思义,队列模拟了排队现象,即新来的人不断加入队列的尾部,而位于队列头部的人逐个离开。
|
||||
「队列 queue」是一种遵循先入先出规则的线性数据结构。顾名思义,队列模拟了排队现象,即新来的人不断加入队列尾部,而位于队列头部的人逐个离开。
|
||||
|
||||
如图 5-4 所示,我们将队列的头部称为“队首”,尾部称为“队尾”,将把元素加入队尾的操作称为“入队”,删除队首元素的操作称为“出队”。
|
||||
如图 5-4 所示,我们将队列头部称为“队首”,尾部称为“队尾”,将把元素加入队尾的操作称为“入队”,删除队首元素的操作称为“出队”。
|
||||
|
||||
{ class="animation-figure" }
|
||||
|
||||
@@ -28,15 +28,17 @@ comments: true
|
||||
|
||||
</div>
|
||||
|
||||
我们可以直接使用编程语言中现成的队列类。
|
||||
我们可以直接使用编程语言中现成的队列类:
|
||||
|
||||
=== "Python"
|
||||
|
||||
```python title="queue.py"
|
||||
from collections import deque
|
||||
|
||||
# 初始化队列
|
||||
# 在 Python 中,我们一般将双向队列类 deque 看作队列使用
|
||||
# 虽然 queue.Queue() 是纯正的队列类,但不太好用,因此不建议
|
||||
que: deque[int] = collections.deque()
|
||||
# 在 Python 中,我们一般将双向队列类 deque 当作队列使用
|
||||
# 虽然 queue.Queue() 是纯正的队列类,但不太好用,因此不推荐
|
||||
que: deque[int] = deque()
|
||||
|
||||
# 元素入队
|
||||
que.append(1)
|
||||
@@ -318,7 +320,7 @@ comments: true
|
||||
|
||||
## 5.2.2 队列实现
|
||||
|
||||
为了实现队列,我们需要一种数据结构,可以在一端添加元素,并在另一端删除元素。因此,链表和数组都可以用来实现队列。
|
||||
为了实现队列,我们需要一种数据结构,可以在一端添加元素,并在另一端删除元素。链表和数组都符合要求。
|
||||
|
||||
### 1. 基于链表的实现
|
||||
|
||||
@@ -335,7 +337,7 @@ comments: true
|
||||
|
||||
<p align="center"> 图 5-5 基于链表实现队列的入队出队操作 </p>
|
||||
|
||||
以下是用链表实现队列的代码。
|
||||
以下是用链表实现队列的代码:
|
||||
|
||||
=== "Python"
|
||||
|
||||
@@ -1205,7 +1207,7 @@ comments: true
|
||||
|
||||
### 2. 基于数组的实现
|
||||
|
||||
由于数组删除首元素的时间复杂度为 $O(n)$ ,这会导致出队操作效率较低。然而,我们可以采用以下巧妙方法来避免这个问题。
|
||||
在数组中删除首元素的时间复杂度为 $O(n)$ ,这会导致出队操作效率较低。然而,我们可以采用以下巧妙方法来避免这个问题。
|
||||
|
||||
我们可以使用一个变量 `front` 指向队首元素的索引,并维护一个变量 `size` 用于记录队列长度。定义 `rear = front + size` ,这个公式计算出的 `rear` 指向队尾元素之后的下一个位置。
|
||||
|
||||
@@ -1227,9 +1229,9 @@ comments: true
|
||||
|
||||
<p align="center"> 图 5-6 基于数组实现队列的入队出队操作 </p>
|
||||
|
||||
你可能会发现一个问题:在不断进行入队和出队的过程中,`front` 和 `rear` 都在向右移动,**当它们到达数组尾部时就无法继续移动了**。为解决此问题,我们可以将数组视为首尾相接的“环形数组”。
|
||||
你可能会发现一个问题:在不断进行入队和出队的过程中,`front` 和 `rear` 都在向右移动,**当它们到达数组尾部时就无法继续移动了**。为了解决此问题,我们可以将数组视为首尾相接的“环形数组”。
|
||||
|
||||
对于环形数组,我们需要让 `front` 或 `rear` 在越过数组尾部时,直接回到数组头部继续遍历。这种周期性规律可以通过“取余操作”来实现,代码如下所示。
|
||||
对于环形数组,我们需要让 `front` 或 `rear` 在越过数组尾部时,直接回到数组头部继续遍历。这种周期性规律可以通过“取余操作”来实现,代码如下所示:
|
||||
|
||||
=== "Python"
|
||||
|
||||
@@ -2112,11 +2114,11 @@ comments: true
|
||||
}
|
||||
```
|
||||
|
||||
以上实现的队列仍然具有局限性,即其长度不可变。然而,这个问题不难解决,我们可以将数组替换为动态数组,从而引入扩容机制。有兴趣的同学可以尝试自行实现。
|
||||
以上实现的队列仍然具有局限性:其长度不可变。然而,这个问题不难解决,我们可以将数组替换为动态数组,从而引入扩容机制。有兴趣的读者可以尝试自行实现。
|
||||
|
||||
两种实现的对比结论与栈一致,在此不再赘述。
|
||||
|
||||
## 5.2.3 队列典型应用
|
||||
|
||||
- **淘宝订单**。购物者下单后,订单将加入队列中,系统随后会根据顺序依次处理队列中的订单。在双十一期间,短时间内会产生海量订单,高并发成为工程师们需要重点攻克的问题。
|
||||
- **各类待办事项**。任何需要实现“先来后到”功能的场景,例如打印机的任务队列、餐厅的出餐队列等。队列在这些场景中可以有效地维护处理顺序。
|
||||
- **淘宝订单**。购物者下单后,订单将加入队列中,系统随后会根据顺序处理队列中的订单。在双十一期间,短时间内会产生海量订单,高并发成为工程师们需要重点攻克的问题。
|
||||
- **各类待办事项**。任何需要实现“先来后到”功能的场景,例如打印机的任务队列、餐厅的出餐队列等,队列在这些场景中可以有效地维护处理顺序。
|
||||
|
||||
Reference in New Issue
Block a user