mirror of
https://github.com/krahets/hello-algo.git
synced 2026-06-16 15:18:37 +08:00
Review the ru version with Codex. (#1870)
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
<u>Очередь (queue)</u> - это линейная структура данных, подчиняющаяся правилу "первым пришел - первым вышел". Как видно из названия, очередь моделирует обычную ситуацию ожидания: новые люди непрерывно присоединяются к хвосту очереди, а стоящие в начале по одному уходят.
|
||||
|
||||
Как показано на рисунке ниже, начало очереди называется "головой очереди", а конец - "хвостом очереди"; операцию добавления элемента в хвост называют "enqueue", а операцию удаления элемента из головы - "dequeue".
|
||||
Как показано на рисунке ниже, начало очереди называется головой очереди, а конец - хвостом очереди; операцию добавления элемента в хвост называют `enqueue`, а операцию удаления элемента из головы - `dequeue`.
|
||||
|
||||

|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
| `pop()` | Извлечь элемент из головы очереди | $O(1)$ |
|
||||
| `peek()` | Просмотреть элемент в голове очереди | $O(1)$ |
|
||||
|
||||
Мы можем напрямую использовать готовые классы очереди, предоставляемые языками программирования:
|
||||
Обычно достаточно использовать готовые классы очереди, предоставляемые языками программирования:
|
||||
|
||||
=== "Python"
|
||||
|
||||
@@ -366,7 +366,7 @@
|
||||
|
||||
### Реализация на основе связного списка
|
||||
|
||||
Как показано на рисунке ниже, мы можем рассматривать "головной узел" и "хвостовой узел" связного списка как "голову очереди" и "хвост очереди" соответственно, договорившись, что добавлять узлы можно только в хвост, а удалять - только из головы.
|
||||
Как показано на рисунке ниже, мы можем рассматривать головной узел и хвостовой узел связного списка как голову очереди и хвост очереди соответственно, договорившись, что добавлять узлы можно только в хвост, а удалять - только из головы.
|
||||
|
||||
=== "LinkedListQueue"
|
||||

|
||||
@@ -385,16 +385,16 @@
|
||||
|
||||
### Реализация на основе массива
|
||||
|
||||
Удаление первого элемента из массива имеет временную сложность $O(n)$ , из-за чего операция dequeue оказывается неэффективной. Однако этого можно избежать с помощью следующего приема.
|
||||
Удаление первого элемента из массива имеет временную сложность $O(n)$ , из-за чего операция `dequeue` оказывается неэффективной. Однако этого можно избежать с помощью следующего приема.
|
||||
|
||||
Мы можем использовать переменную `front` , указывающую на индекс элемента в голове очереди, и поддерживать переменную `size` , которая хранит длину очереди. Определим `rear = front + size` ; эта формула дает позицию `rear`, указывающую на ячейку сразу после хвоста очереди.
|
||||
|
||||
Исходя из этого, **эффективный диапазон элементов массива равен `[front, rear - 1]`**, а различные операции реализуются, как показано на рисунке ниже.
|
||||
|
||||
- Операция 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"
|
||||

|
||||
@@ -405,7 +405,7 @@
|
||||
=== "pop()"
|
||||

|
||||
|
||||
Ты можешь заметить еще одну проблему: при непрерывных операциях enqueue и dequeue значения `front` и `rear` оба движутся вправо, и **когда они доходят до конца массива, дальше сдвигаться уже нельзя**. Чтобы решить эту проблему, можно рассматривать массив как "кольцевой массив", у которого начало и конец соединены.
|
||||
Ты можешь заметить еще одну проблему: при непрерывных операциях `enqueue` и `dequeue` значения `front` и `rear` оба движутся вправо, и **когда они доходят до конца массива, дальше сдвигаться уже нельзя**. Чтобы решить эту проблему, можно рассматривать массив как кольцевой массив, у которого начало и конец соединены.
|
||||
|
||||
Для кольцевого массива нужно сделать так, чтобы `front` или `rear`, перешагнув конец массива, сразу возвращались к его началу и продолжали движение. Такую периодичность удобно реализовать с помощью операции взятия остатка, как показано в коде ниже:
|
||||
|
||||
@@ -419,5 +419,5 @@
|
||||
|
||||
## Типичные применения очереди
|
||||
|
||||
- **Заказы на Taobao**. После оформления заказа покупателем заказ попадает в очередь, а затем система обрабатывает заказы по порядку. Во время крупных распродаж, таких как Double 11, за короткое время возникает огромный поток заказов, и высокая конкурентная нагрузка становится ключевой инженерной проблемой.
|
||||
- **Очереди заказов**. После оформления заказа покупателем заказ попадает в очередь, а затем система обрабатывает заказы по порядку. Во время крупных распродаж за короткое время возникает огромный поток заказов, и высокая конкурентная нагрузка становится ключевой инженерной проблемой.
|
||||
- **Различные отложенные задачи**. Любой сценарий, где нужно реализовать принцип "кто раньше пришел, тот раньше обслуживается", например очередь заданий принтера или очередь блюд на кухне ресторана, хорошо моделируется очередью, которая эффективно поддерживает нужный порядок обработки.
|
||||
|
||||
Reference in New Issue
Block a user