mirror of
https://github.com/krahets/hello-algo.git
synced 2026-07-03 02:54:22 +00:00
build
This commit is contained in:
@@ -6,7 +6,7 @@ comments: true
|
||||
|
||||
<u>Очередь (queue)</u> - это линейная структура данных, подчиняющаяся правилу "первым пришел - первым вышел". Как видно из названия, очередь моделирует обычную ситуацию ожидания: новые люди непрерывно присоединяются к хвосту очереди, а стоящие в начале по одному уходят.
|
||||
|
||||
Как показано на рисунке 5-4, начало очереди называется "головой очереди", а конец - "хвостом очереди"; операцию добавления элемента в хвост называют "enqueue", а операцию удаления элемента из головы - "dequeue".
|
||||
Как показано на рисунке 5-4, начало очереди называется головой очереди, а конец - хвостом очереди; операцию добавления элемента в хвост называют `enqueue`, а операцию удаления элемента из головы - `dequeue`.
|
||||
|
||||
{ class="animation-figure" }
|
||||
|
||||
@@ -28,7 +28,7 @@ comments: true
|
||||
|
||||
</div>
|
||||
|
||||
Мы можем напрямую использовать готовые классы очереди, предоставляемые языками программирования:
|
||||
Обычно достаточно использовать готовые классы очереди, предоставляемые языками программирования:
|
||||
|
||||
=== "Python"
|
||||
|
||||
@@ -376,15 +376,15 @@ comments: true
|
||||
|
||||
### 1. Реализация на основе связного списка
|
||||
|
||||
Как показано на рисунке 5-5, мы можем рассматривать "головной узел" и "хвостовой узел" связного списка как "голову очереди" и "хвост очереди" соответственно, договорившись, что добавлять узлы можно только в хвост, а удалять - только из головы.
|
||||
Как показано на рисунке 5-5, мы можем рассматривать головной узел и хвостовой узел связного списка как голову очереди и хвост очереди соответственно, договорившись, что добавлять узлы можно только в хвост, а удалять - только из головы.
|
||||
|
||||
=== "LinkedListQueue"
|
||||
=== "<1>"
|
||||
{ class="animation-figure" }
|
||||
|
||||
=== "push()"
|
||||
=== "<2>"
|
||||
{ class="animation-figure" }
|
||||
|
||||
=== "pop()"
|
||||
=== "<3>"
|
||||
{ class="animation-figure" }
|
||||
|
||||
<p align="center"> Рисунок 5-5 Операции enqueue и dequeue в реализации очереди на связном списке </p>
|
||||
@@ -1317,29 +1317,29 @@ comments: true
|
||||
|
||||
### 2. Реализация на основе массива
|
||||
|
||||
Удаление первого элемента из массива имеет временную сложность $O(n)$ , из-за чего операция dequeue оказывается неэффективной. Однако этого можно избежать с помощью следующего приема.
|
||||
Удаление первого элемента из массива имеет временную сложность $O(n)$ , из-за чего операция `dequeue` оказывается неэффективной. Однако этого можно избежать с помощью следующего приема.
|
||||
|
||||
Мы можем использовать переменную `front` , указывающую на индекс элемента в голове очереди, и поддерживать переменную `size` , которая хранит длину очереди. Определим `rear = front + size` ; эта формула дает позицию `rear`, указывающую на ячейку сразу после хвоста очереди.
|
||||
|
||||
Исходя из этого, **эффективный диапазон элементов массива равен `[front, rear - 1]`**, а различные операции реализуются, как показано на рисунке 5-6.
|
||||
|
||||
- Операция enqueue: записать входной элемент по индексу `rear` и увеличить `size` на 1.
|
||||
- Операция dequeue: просто увеличить `front` на 1 и уменьшить `size` на 1.
|
||||
- Операция `enqueue`: записать входной элемент по индексу `rear` и увеличить `size` на 1.
|
||||
- Операция `dequeue`: просто увеличить `front` на 1 и уменьшить `size` на 1.
|
||||
|
||||
Можно увидеть, что и enqueue, и dequeue требуют всего одной операции, а значит обе имеют временную сложность $O(1)$ .
|
||||
Можно увидеть, что и `enqueue` , и `dequeue` требуют всего одной операции, а значит обе имеют временную сложность $O(1)$ .
|
||||
|
||||
=== "ArrayQueue"
|
||||
=== "<1>"
|
||||
{ class="animation-figure" }
|
||||
|
||||
=== "push()"
|
||||
=== "<2>"
|
||||
{ class="animation-figure" }
|
||||
|
||||
=== "pop()"
|
||||
=== "<3>"
|
||||
{ class="animation-figure" }
|
||||
|
||||
<p align="center"> Рисунок 5-6 Операции enqueue и dequeue в реализации очереди на массиве </p>
|
||||
|
||||
Ты можешь заметить еще одну проблему: при непрерывных операциях enqueue и dequeue значения `front` и `rear` оба движутся вправо, и **когда они доходят до конца массива, дальше сдвигаться уже нельзя**. Чтобы решить эту проблему, можно рассматривать массив как "кольцевой массив", у которого начало и конец соединены.
|
||||
Ты можешь заметить еще одну проблему: при непрерывных операциях `enqueue` и `dequeue` значения `front` и `rear` оба движутся вправо, и **когда они доходят до конца массива, дальше сдвигаться уже нельзя**. Чтобы решить эту проблему, можно рассматривать массив как кольцевой массив, у которого начало и конец соединены.
|
||||
|
||||
Для кольцевого массива нужно сделать так, чтобы `front` или `rear`, перешагнув конец массива, сразу возвращались к его началу и продолжали движение. Такую периодичность удобно реализовать с помощью операции взятия остатка, как показано в коде ниже:
|
||||
|
||||
@@ -2071,7 +2071,7 @@ comments: true
|
||||
typedef struct {
|
||||
int *nums; // Массив для хранения элементов очереди
|
||||
int front; // Указатель head, указывающий на первый элемент очереди
|
||||
int queSize; // Указатель хвоста, указывающий на позицию после хвоста
|
||||
int queSize; // Текущее количество элементов в очереди
|
||||
int queCapacity; // Вместимость очереди
|
||||
} ArrayQueue;
|
||||
|
||||
@@ -2296,5 +2296,5 @@ comments: true
|
||||
|
||||
## 5.2.3 Типичные применения очереди
|
||||
|
||||
- **Заказы на Taobao**. После оформления заказа покупателем заказ попадает в очередь, а затем система обрабатывает заказы по порядку. Во время крупных распродаж, таких как Double 11, за короткое время возникает огромный поток заказов, и высокая конкурентная нагрузка становится ключевой инженерной проблемой.
|
||||
- **Очереди заказов**. После оформления заказа покупателем заказ попадает в очередь, а затем система обрабатывает заказы по порядку. Во время крупных распродаж за короткое время возникает огромный поток заказов, и высокая конкурентная нагрузка становится ключевой инженерной проблемой.
|
||||
- **Различные отложенные задачи**. Любой сценарий, где нужно реализовать принцип "кто раньше пришел, тот раньше обслуживается", например очередь заданий принтера или очередь блюд на кухне ресторана, хорошо моделируется очередью, которая эффективно поддерживает нужный порядок обработки.
|
||||
|
||||
Reference in New Issue
Block a user