Retranslate the complete English edition from Simplified Chinese (#2010)

* Retranslate the complete English edition from Simplified Chinese

* Polish three English explanations after reader-focused review
This commit is contained in:
Yudong Jin
2026-10-31 03:35:51 +08:00
committed by GitHub
parent ef46e2ed95
commit 14c314c08c
1502 changed files with 29459 additions and 23517 deletions

View File

@@ -1,33 +1,33 @@
# Queue
# Queues
A <u>queue</u> is a linear data structure that follows the First In, First Out (FIFO) rule. As the name suggests, it models people lining up: newcomers continuously join the rear of the queue, while the people at the front leave one by one.
A <u>queue</u> is a linear data structure that follows a first-in, first-out rule. It models a line of people: newcomers join at the back, while those at the front leave one by one.
As shown in the figure below, we call the front of the queue the "front" and the end the "rear." The operation of adding an element to the rear is called "enqueue," and the operation of removing the front element is called "dequeue."
As shown below, the two ends are called the “front” and the “rear.” Adding an element at the rear is called “enqueueing,” and removing an element from the front is called “dequeueing.”
![FIFO rule of queue](queue.assets/queue_operations.png)
![The first-in, first-out rule of a queue](queue.assets/queue_operations.png)
## Common Queue Operations
## Common queue operations
The common operations on a queue are shown in the table below. Note that method names may vary across programming languages. Here, we use the same naming convention as for stacks.
The table below lists common operations. Method names vary between programming languages; here we use the same names as for stacks.
<p align="center"> Table <id> &nbsp; Efficiency of Queue Operations </p>
<p align="center"> Table <id> &nbsp; Efficiency of queue operations </p>
| Method | Description | Time Complexity |
| -------- | ------------------------------------------ | --------------- |
| `push()` | Enqueue element, add element to rear | $O(1)$ |
| `pop()` | Dequeue front element | $O(1)$ |
| `peek()` | Access front element | $O(1)$ |
| Method | Description | Time complexity |
| -------- | ---------------------------- | ---------- |
| `push()` | Enqueue an element at the rear | $O(1)$ |
| `pop()` | Dequeue the front element | $O(1)$ |
| `peek()` | Access the front element | $O(1)$ |
We can directly use the queue classes provided by the programming language:
We can use a queue class already provided by the programming language:
=== "Python"
```python title="queue.py"
from collections import deque
# Initialize queue
# In Python, we generally use the deque class as a queue
# Although queue.Queue() is a pure queue class, it is not very user-friendly, so it is not recommended
# Initialize a queue
# In Python, we usually use the deque class as a queue
# Although queue.Queue() is a dedicated queue class, it is less convenient and is not recommended here
que: deque[int] = deque()
# Enqueue elements
@@ -37,23 +37,23 @@ We can directly use the queue classes provided by the programming language:
que.append(5)
que.append(4)
# Access front element
# Access the front element
front: int = que[0]
# Dequeue element
# Dequeue an element
pop: int = que.popleft()
# Get queue length
# Get the queue size
size: int = len(que)
# Check if queue is empty
# Check whether the queue is empty
is_empty: bool = len(que) == 0
```
=== "C++"
```cpp title="queue.cpp"
/* Initialize queue */
/* Initialize a queue */
queue<int> queue;
/* Enqueue elements */
@@ -63,23 +63,23 @@ We can directly use the queue classes provided by the programming language:
queue.push(5);
queue.push(4);
/* Access front element */
/* Access the front element */
int front = queue.front();
/* Dequeue element */
/* Dequeue an element */
queue.pop();
/* Get queue length */
/* Get the queue size */
int size = queue.size();
/* Check if queue is empty */
/* Check whether the queue is empty */
bool empty = queue.empty();
```
=== "Java"
```java title="queue.java"
/* Initialize queue */
/* Initialize a queue */
Queue<Integer> queue = new LinkedList<>();
/* Enqueue elements */
@@ -89,23 +89,23 @@ We can directly use the queue classes provided by the programming language:
queue.offer(5);
queue.offer(4);
/* Access front element */
/* Access the front element */
int peek = queue.peek();
/* Dequeue element */
/* Dequeue an element */
int pop = queue.poll();
/* Get queue length */
/* Get the queue size */
int size = queue.size();
/* Check if queue is empty */
/* Check whether the queue is empty */
boolean isEmpty = queue.isEmpty();
```
=== "C#"
```csharp title="queue.cs"
/* Initialize queue */
/* Initialize a queue */
Queue<int> queue = new();
/* Enqueue elements */
@@ -115,24 +115,24 @@ We can directly use the queue classes provided by the programming language:
queue.Enqueue(5);
queue.Enqueue(4);
/* Access front element */
/* Access the front element */
int peek = queue.Peek();
/* Dequeue element */
/* Dequeue an element */
int pop = queue.Dequeue();
/* Get queue length */
/* Get the queue size */
int size = queue.Count;
/* Check if queue is empty */
/* Check whether the queue is empty */
bool isEmpty = queue.Count == 0;
```
=== "Go"
```go title="queue_test.go"
/* Initialize queue */
// In Go, use list as a queue
/* Initialize a queue */
// In Go, use a list as a queue
queue := list.New()
/* Enqueue elements */
@@ -142,25 +142,25 @@ We can directly use the queue classes provided by the programming language:
queue.PushBack(5)
queue.PushBack(4)
/* Access front element */
/* Access the front element */
peek := queue.Front()
/* Dequeue element */
/* Dequeue an element */
pop := queue.Front()
queue.Remove(pop)
/* Get queue length */
/* Get the queue size */
size := queue.Len()
/* Check if queue is empty */
/* Check whether the queue is empty */
isEmpty := queue.Len() == 0
```
=== "Swift"
```swift title="queue.swift"
/* Initialize queue */
// Swift does not have a built-in queue class, can use Array as a queue
/* Initialize a queue */
// Swift has no built-in queue class; use an Array as a queue
var queue: [Int] = []
/* Enqueue elements */
@@ -170,25 +170,25 @@ We can directly use the queue classes provided by the programming language:
queue.append(5)
queue.append(4)
/* Access front element */
/* Access the front element */
let peek = queue.first!
/* Dequeue element */
// Since it's an array, removeFirst has O(n) complexity
/* Dequeue an element */
// Because this is an array, removeFirst takes O(n) time
let pop = queue.removeFirst()
/* Get queue length */
/* Get the queue size */
let size = queue.count
/* Check if queue is empty */
/* Check whether the queue is empty */
let isEmpty = queue.isEmpty
```
=== "JS"
```javascript title="queue.js"
/* Initialize queue */
// JavaScript does not have a built-in queue, can use Array as a queue
/* Initialize a queue */
// JavaScript has no built-in queue; use an Array as a queue
const queue = [];
/* Enqueue elements */
@@ -198,25 +198,25 @@ We can directly use the queue classes provided by the programming language:
queue.push(5);
queue.push(4);
/* Access front element */
/* Access the front element */
const peek = queue[0];
/* Dequeue element */
// The underlying structure is an array, so shift() has O(n) time complexity
/* Dequeue an element */
// The underlying structure is an array, so shift() takes O(n) time
const pop = queue.shift();
/* Get queue length */
/* Get the queue size */
const size = queue.length;
/* Check if queue is empty */
/* Check whether the queue is empty */
const empty = queue.length === 0;
```
=== "TS"
```typescript title="queue.ts"
/* Initialize queue */
// TypeScript does not have a built-in queue, can use Array as a queue
/* Initialize a queue */
// TypeScript has no built-in queue; use an Array as a queue
const queue: number[] = [];
/* Enqueue elements */
@@ -226,25 +226,25 @@ We can directly use the queue classes provided by the programming language:
queue.push(5);
queue.push(4);
/* Access front element */
/* Access the front element */
const peek = queue[0];
/* Dequeue element */
// The underlying structure is an array, so shift() has O(n) time complexity
/* Dequeue an element */
// The underlying structure is an array, so shift() takes O(n) time
const pop = queue.shift();
/* Get queue length */
/* Get the queue size */
const size = queue.length;
/* Check if queue is empty */
/* Check whether the queue is empty */
const empty = queue.length === 0;
```
=== "Dart"
```dart title="queue.dart"
/* Initialize queue */
// In Dart, the Queue class is a deque and can also be used as a queue
/* Initialize a queue */
// In Dart, Queue is a deque and can also be used as a queue
Queue<int> queue = Queue();
/* Enqueue elements */
@@ -254,24 +254,24 @@ We can directly use the queue classes provided by the programming language:
queue.add(5);
queue.add(4);
/* Access front element */
/* Access the front element */
int peek = queue.first;
/* Dequeue element */
/* Dequeue an element */
int pop = queue.removeFirst();
/* Get queue length */
/* Get the queue size */
int size = queue.length;
/* Check if queue is empty */
/* Check whether the queue is empty */
bool isEmpty = queue.isEmpty;
```
=== "Rust"
```rust title="queue.rs"
/* Initialize deque */
// In Rust, use deque as a regular queue
/* Initialize a deque */
// In Rust, use a deque as an ordinary queue
let mut deque: VecDeque<u32> = VecDeque::new();
/* Enqueue elements */
@@ -281,31 +281,31 @@ We can directly use the queue classes provided by the programming language:
deque.push_back(5);
deque.push_back(4);
/* Access front element */
/* Access the front element */
if let Some(front) = deque.front() {
}
/* Dequeue element */
/* Dequeue an element */
if let Some(pop) = deque.pop_front() {
}
/* Get queue length */
/* Get the queue size */
let size = deque.len();
/* Check if queue is empty */
/* Check whether the queue is empty */
let is_empty = deque.is_empty();
```
=== "C"
```c title="queue.c"
// C does not provide a built-in queue
// C provides no built-in queue
```
=== "Kotlin"
```kotlin title="queue.kt"
/* Initialize queue */
/* Initialize a queue */
val queue = LinkedList<Int>()
/* Enqueue elements */
@@ -315,24 +315,24 @@ We can directly use the queue classes provided by the programming language:
queue.offer(5)
queue.offer(4)
/* Access front element */
/* Access the front element */
val peek = queue.peek()
/* Dequeue element */
/* Dequeue an element */
val pop = queue.poll()
/* Get queue length */
/* Get the queue size */
val size = queue.size
/* Check if queue is empty */
/* Check whether the queue is empty */
val isEmpty = queue.isEmpty()
```
=== "Ruby"
```ruby title="queue.rb"
# Initialize queue
# Ruby's built-in queue (Thread::Queue) does not have peek and traversal methods, can use Array as a queue
# Initialize a queue
# Ruby's built-in Thread::Queue has no peek or traversal methods; use an Array as a queue
queue = []
# Enqueue elements
@@ -342,34 +342,34 @@ We can directly use the queue classes provided by the programming language:
queue.push(5)
queue.push(4)
# Access front element
# Access the front element of the queue
peek = queue.first
# Dequeue element
# Please note that since it's an array, Array#shift has O(n) time complexity
# Dequeue an element
# Note that this is an array, so Array#shift takes O(n) time
pop = queue.shift
# Get queue length
# Get the queue size
size = queue.length
# Check if queue is empty
# Check whether the queue is empty
is_empty = queue.empty?
```
??? pythontutor "Code Visualization"
??? pythontutor "Visualize execution"
https://pythontutor.com/render.html#code=from%20collections%20import%20deque%0A%0A%22%22%22Driver%20Code%22%22%22%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20%23%20%E5%88%9D%E5%A7%8B%E5%8C%96%E9%98%9F%E5%88%97%0A%20%20%20%20%23%20%E5%9C%A8%20Python%20%E4%B8%AD%EF%BC%8C%E6%88%91%E4%BB%AC%E4%B8%80%E8%88%AC%E5%B0%86%E5%8F%8C%E5%90%91%E9%98%9F%E5%88%97%E7%B1%BB%20deque%20%E7%9C%8B%E4%BD%9C%E9%98%9F%E5%88%97%E4%BD%BF%E7%94%A8%0A%20%20%20%20%23%20%E8%99%BD%E7%84%B6%20queue.Queue%28%29%20%E6%98%AF%E7%BA%AF%E6%AD%A3%E7%9A%84%E9%98%9F%E5%88%97%E7%B1%BB%EF%BC%8C%E4%BD%86%E4%B8%8D%E5%A4%AA%E5%A5%BD%E7%94%A8%0A%20%20%20%20que%20%3D%20deque%28%29%0A%0A%20%20%20%20%23%20%E5%85%83%E7%B4%A0%E5%85%A5%E9%98%9F%0A%20%20%20%20que.append%281%29%0A%20%20%20%20que.append%283%29%0A%20%20%20%20que.append%282%29%0A%20%20%20%20que.append%285%29%0A%20%20%20%20que.append%284%29%0A%20%20%20%20print%28%22%E9%98%9F%E5%88%97%20que%20%3D%22,%20que%29%0A%0A%20%20%20%20%23%20%E8%AE%BF%E9%97%AE%E9%98%9F%E9%A6%96%E5%85%83%E7%B4%A0%0A%20%20%20%20front%20%3D%20que%5B0%5D%0A%20%20%20%20print%28%22%E9%98%9F%E9%A6%96%E5%85%83%E7%B4%A0%20front%20%3D%22,%20front%29%0A%0A%20%20%20%20%23%20%E5%85%83%E7%B4%A0%E5%87%BA%E9%98%9F%0A%20%20%20%20pop%20%3D%20que.popleft%28%29%0A%20%20%20%20print%28%22%E5%87%BA%E9%98%9F%E5%85%83%E7%B4%A0%20pop%20%3D%22,%20pop%29%0A%20%20%20%20print%28%22%E5%87%BA%E9%98%9F%E5%90%8E%20que%20%3D%22,%20que%29%0A%0A%20%20%20%20%23%20%E8%8E%B7%E5%8F%96%E9%98%9F%E5%88%97%E7%9A%84%E9%95%BF%E5%BA%A6%0A%20%20%20%20size%20%3D%20len%28que%29%0A%20%20%20%20print%28%22%E9%98%9F%E5%88%97%E9%95%BF%E5%BA%A6%20size%20%3D%22,%20size%29%0A%0A%20%20%20%20%23%20%E5%88%A4%E6%96%AD%E9%98%9F%E5%88%97%E6%98%AF%E5%90%A6%E4%B8%BA%E7%A9%BA%0A%20%20%20%20is_empty%20%3D%20len%28que%29%20%3D%3D%200%0A%20%20%20%20print%28%22%E9%98%9F%E5%88%97%E6%98%AF%E5%90%A6%E4%B8%BA%E7%A9%BA%20%3D%22,%20is_empty%29&cumulative=false&curInstr=3&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=311&rawInputLstJSON=%5B%5D&textReferences=false
https://pythontutor.com/render.html#code=from%20collections%20import%20deque%0A%0A%22%22%22Driver%20Code%22%22%22%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20%23%20Initialize%20a%20queue%0A%20%20%20%20%23%20In%20Python%2C%20we%20usually%20use%20the%20deque%20class%20as%20a%20queue%0A%20%20%20%20%23%20Although%20queue.Queue%28%29%20is%20a%20dedicated%20queue%20class%2C%20it%20is%20less%20convenient%0A%20%20%20%20que%20%3D%20deque%28%29%0A%0A%20%20%20%20%23%20Enqueue%20elements%0A%20%20%20%20que.append%281%29%0A%20%20%20%20que.append%283%29%0A%20%20%20%20que.append%282%29%0A%20%20%20%20que.append%285%29%0A%20%20%20%20que.append%284%29%0A%20%20%20%20print%28%22Queue%3A%20que%20%3D%22%2C%20que%29%0A%0A%20%20%20%20%23%20Access%20the%20front%20element%0A%20%20%20%20front%20%3D%20que%5B0%5D%0A%20%20%20%20print%28%22Front%20element%3A%20front%20%3D%22%2C%20front%29%0A%0A%20%20%20%20%23%20Dequeue%20an%20element%0A%20%20%20%20pop%20%3D%20que.popleft%28%29%0A%20%20%20%20print%28%22Dequeued%20element%3A%20pop%20%3D%22%2C%20pop%29%0A%20%20%20%20print%28%22After%20dequeuing%3A%20que%20%3D%22%2C%20que%29%0A%0A%20%20%20%20%23%20Get%20the%20queue%20size%0A%20%20%20%20size%20%3D%20len%28que%29%0A%20%20%20%20print%28%22Queue%20size%3A%20size%20%3D%22%2C%20size%29%0A%0A%20%20%20%20%23%20Check%20whether%20the%20queue%20is%20empty%0A%20%20%20%20is_empty%20%3D%20len%28que%29%20%3D%3D%200%0A%20%20%20%20print%28%22Is%20the%20queue%20empty%20%3D%22%2C%20is_empty%29&cumulative=false&curInstr=3&heapPrimitives=nevernest&mode=display&origin=opt-frontend.js&py=311&rawInputLstJSON=%5B%5D&textReferences=false
## Queue Implementation
## Implementing a queue
To implement a queue, we need a data structure that allows adding elements at one end and removing elements at the other end. Both linked lists and arrays meet this requirement.
A queue needs a data structure that allows insertion at one end and deletion at the other. Both linked lists and arrays can meet this requirement.
### Linked List Implementation
### Implementation with a linked list
As shown in the figure below, we can treat the "head node" and "tail node" of a linked list as the "front" and "rear" of the queue, respectively, with the rule that nodes can only be added at the rear and removed from the front.
As shown below, treat the linked list's head and tail as the queue's front and rear. Nodes may be added only at the rear and removed only from the front.
=== "<1>"
![Enqueue and dequeue operations in linked list implementation of queue](queue.assets/linkedlist_queue_step1.png)
![Enqueue and dequeue in a linked-list queue](queue.assets/linkedlist_queue_step1.png)
=== "<2>"
![linkedlist_queue_push](queue.assets/linkedlist_queue_step2_push.png)
@@ -377,27 +377,27 @@ As shown in the figure below, we can treat the "head node" and "tail node" of a
=== "<3>"
![linkedlist_queue_pop](queue.assets/linkedlist_queue_step3_pop.png)
Below is the code for implementing a queue using a linked list:
Here is an implementation using a linked list:
```src
[file]{linkedlist_queue}-[class]{linked_list_queue}-[func]{}
```
### Array Implementation
### Implementation with an array
Deleting the first element in an array has a time complexity of $O(n)$, which would make the dequeue operation inefficient. However, we can use the following clever method to avoid this problem.
Removing the first element of an array takes $O(n)$ time, which would make dequeueing inefficient. A useful technique avoids this problem.
We can use a variable `front` to point to the index of the front element and maintain a variable `size` to record the queue length. We define `rear = front + size`, which calculates the position right after the rear element.
Use a variable `front` for the index of the front element and a variable `size` for the queue's length. Define `rear = front + size`, so `rear` points to the position immediately after the last element.
Based on this design, **the valid interval containing elements in the array is `[front, rear - 1]`**. The implementation methods for various operations are shown in the figure below:
With this design, **the occupied interval is `[front, rear - 1]`**. Operations work as shown below.
- Enqueue operation: Assign the input element to the `rear` index and increase `size` by 1.
- Dequeue operation: Simply increase `front` by 1 and decrease `size` by 1.
- Enqueue: assign the new element to index `rear` and increase `size` by 1.
- Dequeue: increase `front` by 1 and decrease `size` by 1.
As you can see, both enqueue and dequeue operations require only one operation, with a time complexity of $O(1)$.
Both operations require only a constant amount of work and take $O(1)$ time.
=== "<1>"
![Enqueue and dequeue operations in array implementation of queue](queue.assets/array_queue_step1.png)
![Enqueue and dequeue in an array-based queue](queue.assets/array_queue_step1.png)
=== "<2>"
![array_queue_push](queue.assets/array_queue_step2_push.png)
@@ -405,19 +405,19 @@ As you can see, both enqueue and dequeue operations require only one operation,
=== "<3>"
![array_queue_pop](queue.assets/array_queue_step3_pop.png)
You may notice a problem: as we continuously enqueue and dequeue, both `front` and `rear` move to the right. **When they reach the end of the array, they cannot continue moving**. To solve this problem, we can treat the array as a "circular array" with head and tail connected.
There is a problem: repeated enqueueing and dequeueing move both `front` and `rear` to the right, **and they cannot continue once they reach the end of the array**. To solve this, treat the array as circular, with its end connected to its beginning.
For a circular array, we need to let `front` or `rear` wrap around to the beginning of the array when they cross the end. This periodic pattern can be implemented using the "modulo operation," as shown in the code below:
When `front` or `rear` passes the array's end, wrap it back to the beginning. The remainder operation implements this cyclic behavior:
```src
[file]{array_queue}-[class]{array_queue}-[func]{}
```
The queue implemented above still has limitations: its length is immutable. However, this problem is not difficult to solve. We can replace the array with a dynamic array to introduce an expansion mechanism. Interested readers can try to implement this themselves.
This queue still has a limitation: its capacity is fixed. We can address it by replacing the array with a dynamic array and adding resizing. Interested readers can try implementing this themselves.
The comparison conclusions for the two implementations are consistent with those for stacks and will not be repeated here.
The comparison between these two implementations is the same as for stacks, so we will not repeat it here.
## Typical Applications of Queue
## Typical applications
- **Taobao orders**. After shoppers place orders, the orders are added to a queue, and the system subsequently processes the orders in the queue according to their sequence. During Double Eleven, massive orders are generated in a short time, and high concurrency becomes a key challenge that engineers need to tackle.
- **Various to-do tasks**. Any scenario that needs to implement "first come, first served" functionality, such as a printer's task queue or a restaurant's order queue, can effectively maintain the processing order using queues.
- **Taobao orders**. When a shopper places an order, it enters a queue, and the system processes orders in sequence. During the Singles' Day shopping festival, enormous numbers of orders arrive in a short time, making high concurrency a major engineering challenge.
- **Tasks awaiting processing**. Queues preserve processing order wherever first-come, first-served behavior is needed, such as printer jobs or restaurant orders.