Translate all code to English (#1836)

* Review the EN heading format.

* Fix pythontutor headings.

* Fix pythontutor headings.

* bug fixes

* Fix headings in **/summary.md

* Revisit the CN-to-EN translation for Python code using Claude-4.5

* Revisit the CN-to-EN translation for Java code using Claude-4.5

* Revisit the CN-to-EN translation for Cpp code using Claude-4.5.

* Fix the dictionary.

* Fix cpp code translation for the multipart strings.

* Translate Go code to English.

* Update workflows to test EN code.

* Add EN translation for C.

* Add EN translation for CSharp.

* Add EN translation for Swift.

* Trigger the CI check.

* Revert.

* Update en/hash_map.md

* Add the EN version of Dart code.

* Add the EN version of Kotlin code.

* Add missing code files.

* Add the EN version of JavaScript code.

* Add the EN version of TypeScript code.

* Fix the workflows.

* Add the EN version of Ruby code.

* Add the EN version of Rust code.

* Update the CI check for the English version  code.

* Update Python CI check.

* Fix cmakelists for en/C code.

* Fix Ruby comments
This commit is contained in:
Yudong Jin
2025-12-31 07:44:52 +08:00
committed by GitHub
parent 45e1295241
commit 2778a6f9c7
1284 changed files with 71557 additions and 3275 deletions

View File

@@ -1,4 +1,4 @@
# Bubble sort
# Bubble Sort
<u>Bubble sort (bubble sort)</u> achieves sorting by continuously comparing and swapping adjacent elements. This process is like bubbles rising from the bottom to the top, hence the name bubble sort.
@@ -25,7 +25,7 @@ As shown in the figure below, the bubbling process can be simulated using elemen
=== "<7>"
![bubble_operation_step7](bubble_sort.assets/bubble_operation_step7.png)
## Algorithm flow
## Algorithm Flow
Assume the array has length $n$. The steps of bubble sort are shown in the figure below.
@@ -42,7 +42,7 @@ Example code is as follows:
[file]{bubble_sort}-[class]{}-[func]{bubble_sort}
```
## Efficiency optimization
## Efficiency Optimization
We notice that if no swap operations are performed during a certain round of "bubbling", it means the array has already completed sorting and can directly return the result. Therefore, we can add a flag `flag` to monitor this situation and return immediately once it occurs.
@@ -52,7 +52,7 @@ After optimization, the worst-case time complexity and average time complexity o
[file]{bubble_sort}-[class]{}-[func]{bubble_sort_with_flag}
```
## Algorithm characteristics
## Algorithm Characteristics
- **Time complexity of $O(n^2)$, adaptive sorting**: The array lengths traversed in each round of "bubbling" are $n - 1$, $n - 2$, $\dots$, $2$, $1$, totaling $(n - 1) n / 2$. After introducing the `flag` optimization, the best-case time complexity can reach $O(n)$.
- **Space complexity of $O(1)$, in-place sorting**: Pointers $i$ and $j$ use a constant amount of extra space.

View File

@@ -1,10 +1,10 @@
# Bucket sort
# Bucket Sort
The several sorting algorithms mentioned earlier all belong to "comparison-based sorting algorithms", which achieve sorting by comparing the size of elements. The time complexity of such sorting algorithms cannot exceed $O(n \log n)$. Next, we will explore several "non-comparison sorting algorithms", whose time complexity can reach linear order.
<u>Bucket sort (bucket sort)</u> is a typical application of the divide-and-conquer strategy. It works by setting up buckets with size order, each bucket corresponding to a data range, evenly distributing data to each bucket; then, sorting within each bucket separately; finally, merging all data in the order of the buckets.
## Algorithm flow
## Algorithm Flow
Consider an array of length $n$, whose elements are floating-point numbers in the range $[0, 1)$. The flow of bucket sort is shown in the figure below.
@@ -20,7 +20,7 @@ The code is as follows:
[file]{bucket_sort}-[class]{}-[func]{bucket_sort}
```
## Algorithm characteristics
## Algorithm Characteristics
Bucket sort is suitable for processing very large data volumes. For example, if the input data contains 1 million elements and system memory cannot load all the data at once, the data can be divided into 1000 buckets, each bucket sorted separately, and then the results merged.
@@ -28,7 +28,7 @@ Bucket sort is suitable for processing very large data volumes. For example, if
- **Space complexity of $O(n + k)$, non-in-place sorting**: Additional space is required for $k$ buckets and a total of $n$ elements.
- Whether bucket sort is stable depends on whether the algorithm for sorting elements within buckets is stable.
## How to achieve even distribution
## How to Achieve Even Distribution
Theoretically, bucket sort can achieve $O(n)$ time complexity. **The key is to evenly distribute elements to each bucket**, because real data is often not evenly distributed. For example, if we want to evenly distribute all products on Taobao into 10 buckets by price range, there may be very many products below 100 yuan and very few above 1000 yuan. If the price intervals are evenly divided into 10, the difference in the number of products in each bucket will be very large.

View File

@@ -1,8 +1,8 @@
# Counting sort
# Counting Sort
<u>Counting sort (counting sort)</u> achieves sorting by counting the number of elements, typically applied to integer arrays.
## Simple implementation
## Simple Implementation
Let's start with a simple example. Given an array `nums` of length $n$, where the elements are all "non-negative integers", the overall flow of counting sort is shown in the figure below.
@@ -22,7 +22,7 @@ The code is as follows:
From the perspective of bucket sort, we can regard each index of the counting array `counter` in counting sort as a bucket, and the process of counting quantities as distributing each element to the corresponding bucket. Essentially, counting sort is a special case of bucket sort for integer data.
## Complete implementation
## Complete Implementation
Observant readers may have noticed that **if the input data is objects, step `3.` above becomes invalid**. Suppose the input data is product objects, and we want to sort the products by price (a member variable of the class), but the above algorithm can only give the sorting result of prices.
@@ -69,7 +69,7 @@ The implementation code of counting sort is as follows:
[file]{counting_sort}-[class]{}-[func]{counting_sort}
```
## Algorithm characteristics
## Algorithm Characteristics
- **Time complexity of $O(n + m)$, non-adaptive sorting**: Involves traversing `nums` and traversing `counter`, both using linear time. Generally, $n \gg m$, and time complexity tends toward $O(n)$.
- **Space complexity of $O(n + m)$, non-in-place sorting**: Uses arrays `res` and `counter` of lengths $n$ and $m$ respectively.

View File

@@ -1,4 +1,4 @@
# Heap sort
# Heap Sort
!!! tip
@@ -11,7 +11,7 @@
Although the above method is feasible, it requires an additional array to save the popped elements, which is quite wasteful of space. In practice, we usually use a more elegant implementation method.
## Algorithm flow
## Algorithm Flow
Assume the array length is $n$. The flow of heap sort is shown in the figure below.
@@ -66,7 +66,7 @@ In the code implementation, we use the same top-to-bottom heapify function `sift
[file]{heap_sort}-[class]{}-[func]{heap_sort}
```
## Algorithm characteristics
## Algorithm Characteristics
- **Time complexity of $O(n \log n)$, non-adaptive sorting**: The build heap operation uses $O(n)$ time. Extracting the largest element from the heap has a time complexity of $O(\log n)$, looping a total of $n - 1$ rounds.
- **Space complexity of $O(1)$, in-place sorting**: A few pointer variables use $O(1)$ space. Element swapping and heapify operations are both performed on the original array.

View File

@@ -1,4 +1,4 @@
# Insertion sort
# Insertion Sort
<u>Insertion sort (insertion sort)</u> is a simple sorting algorithm that works very similarly to the process of manually organizing a deck of cards.
@@ -8,7 +8,7 @@ The figure below shows the operation flow of inserting an element into the array
![Single insertion operation](insertion_sort.assets/insertion_operation.png)
## Algorithm flow
## Algorithm Flow
The overall flow of insertion sort is shown in the figure below.
@@ -25,13 +25,13 @@ Example code is as follows:
[file]{insertion_sort}-[class]{}-[func]{insertion_sort}
```
## Algorithm characteristics
## Algorithm Characteristics
- **Time complexity of $O(n^2)$, adaptive sorting**: In the worst case, each insertion operation requires loops of $n - 1$, $n-2$, $\dots$, $2$, $1$, summing to $(n - 1) n / 2$, so the time complexity is $O(n^2)$. When encountering ordered data, the insertion operation will terminate early. When the input array is completely ordered, insertion sort achieves the best-case time complexity of $O(n)$.
- **Space complexity of $O(1)$, in-place sorting**: Pointers $i$ and $j$ use a constant amount of extra space.
- **Stable sorting**: During the insertion operation process, we insert elements to the right of equal elements, without changing their order.
## Advantages of insertion sort
## Advantages of Insertion Sort
The time complexity of insertion sort is $O(n^2)$, while the time complexity of quick sort, which we will learn about next, is $O(n \log n)$. Although insertion sort has a higher time complexity, **insertion sort is usually faster for smaller data volumes**.

View File

@@ -1,4 +1,4 @@
# Merge sort
# Merge Sort
<u>Merge sort (merge sort)</u> is a sorting algorithm based on the divide-and-conquer strategy, which includes the "divide" and "merge" phases shown in the figure below.
@@ -7,7 +7,7 @@
![Divide and merge phases of merge sort](merge_sort.assets/merge_sort_overview.png)
## Algorithm flow
## Algorithm Flow
As shown in the figure below, the "divide phase" recursively splits the array from the midpoint into two sub-arrays from top to bottom.
@@ -57,13 +57,13 @@ The implementation of merge sort is shown in the code below. Note that the inter
[file]{merge_sort}-[class]{}-[func]{merge_sort}
```
## Algorithm characteristics
## Algorithm Characteristics
- **Time complexity of $O(n \log n)$, non-adaptive sorting**: The division produces a recursion tree of height $\log n$, and the total number of merge operations at each level is $n$, so the overall time complexity is $O(n \log n)$.
- **Space complexity of $O(n)$, non-in-place sorting**: The recursion depth is $\log n$, using $O(\log n)$ size of stack frame space. The merge operation requires the aid of an auxiliary array, using $O(n)$ size of additional space.
- **Stable sorting**: In the merge process, the order of equal elements remains unchanged.
## Linked list sorting
## Linked List Sorting
For linked lists, merge sort has significant advantages over other sorting algorithms, **and can optimize the space complexity of linked list sorting tasks to $O(1)$**.

View File

@@ -1,4 +1,4 @@
# Quick sort
# Quick Sort
<u>Quick sort (quick sort)</u> is a sorting algorithm based on the divide-and-conquer strategy, which operates efficiently and is widely applied.
@@ -45,7 +45,7 @@ After sentinel partitioning is complete, the original array is divided into thre
[file]{quick_sort}-[class]{quick_sort}-[func]{partition}
```
## Algorithm flow
## Algorithm Flow
The overall flow of quick sort is shown in the figure below.
@@ -59,13 +59,13 @@ The overall flow of quick sort is shown in the figure below.
[file]{quick_sort}-[class]{quick_sort}-[func]{quick_sort}
```
## Algorithm characteristics
## Algorithm Characteristics
- **Time complexity of $O(n \log n)$, non-adaptive sorting**: In the average case, the number of recursive levels of sentinel partitioning is $\log n$, and the total number of loops at each level is $n$, using $O(n \log n)$ time overall. In the worst case, each round of sentinel partitioning divides an array of length $n$ into two sub-arrays of length $0$ and $n - 1$, at which point the number of recursive levels reaches $n$, the number of loops at each level is $n$, and the total time used is $O(n^2)$.
- **Space complexity of $O(n)$, in-place sorting**: In the case where the input array is completely reversed, the worst recursive depth reaches $n$, using $O(n)$ stack frame space. The sorting operation is performed on the original array without the aid of an additional array.
- **Non-stable sorting**: In the last step of sentinel partitioning, the pivot may be swapped to the right of equal elements.
## Why is quick sort fast
## Why Is Quick Sort Fast
From the name, we can see that quick sort should have certain advantages in terms of efficiency. Although the average time complexity of quick sort is the same as "merge sort" and "heap sort", quick sort is usually more efficient, mainly for the following reasons.
@@ -73,7 +73,7 @@ From the name, we can see that quick sort should have certain advantages in term
- **High cache utilization**: When performing sentinel partitioning operations, the system can load the entire sub-array into the cache, so element access efficiency is relatively high. Algorithms like "heap sort" require jump-style access to elements, thus lacking this characteristic.
- **Small constant coefficient of complexity**: Among the three algorithms mentioned above, quick sort has the smallest total number of operations such as comparisons, assignments, and swaps. This is similar to the reason why "insertion sort" is faster than "bubble sort".
## Pivot optimization
## Pivot Optimization
**Quick sort may have reduced time efficiency for certain inputs**. Take an extreme example: suppose the input array is completely reversed. Since we select the leftmost element as the pivot, after sentinel partitioning is complete, the pivot is swapped to the rightmost end of the array, causing the left sub-array length to be $n - 1$ and the right sub-array length to be $0$. If we recurse down like this, each round of sentinel partitioning will have a sub-array length of $0$, the divide-and-conquer strategy fails, and quick sort degrades to a form approximate to "bubble sort".
@@ -89,7 +89,7 @@ Example code is as follows:
[file]{quick_sort}-[class]{quick_sort_median}-[func]{partition}
```
## Recursive depth optimization
## Recursive Depth Optimization
**For certain inputs, quick sort may occupy more space**. Taking a completely ordered input array as an example, let the length of the sub-array in recursion be $m$. Each round of sentinel partitioning will produce a left sub-array of length $0$ and a right sub-array of length $m - 1$, which means that the problem scale reduced per recursive call is very small (only one element is reduced), and the height of the recursion tree will reach $n - 1$, at which point $O(n)$ size of stack frame space is required.

View File

@@ -1,10 +1,10 @@
# Radix sort
# Radix Sort
The previous section introduced counting sort, which is suitable for situations where the data volume $n$ is large but the data range $m$ is small. Suppose we need to sort $n = 10^6$ student IDs, and the student ID is an 8-digit number, which means the data range $m = 10^8$ is very large. Using counting sort would require allocating a large amount of memory space, whereas radix sort can avoid this situation.
<u>Radix sort (radix sort)</u> has a core idea consistent with counting sort, which also achieves sorting by counting quantities. Building on this, radix sort utilizes the progressive relationship between the digits of numbers, sorting each digit in turn to obtain the final sorting result.
## Algorithm flow
## Algorithm Flow
Taking student ID data as an example, assume the lowest digit is the $1$st digit and the highest digit is the $8$th digit. The flow of radix sort is shown in the figure below.
@@ -32,7 +32,7 @@ Additionally, we need to slightly modify the counting sort code to make it sort
In successive sorting rounds, the result of a later round will override the result of an earlier round. For example, if the first round result is $a < b$, while the second round result is $a > b$, then the second round's result will replace the first round's result. Since higher-order digits have higher priority than lower-order digits, we should sort the lower digits first and then sort the higher digits.
## Algorithm characteristics
## Algorithm Characteristics
Compared to counting sort, radix sort is suitable for larger numerical ranges, **but the prerequisite is that the data must be representable in a fixed number of digits, and the number of digits should not be too large**. For example, floating-point numbers are not suitable for radix sort because their number of digits $k$ may be too large, potentially leading to time complexity $O(nk) \gg O(n^2)$.

View File

@@ -1,4 +1,4 @@
# Selection sort
# Selection Sort
<u>Selection sort (selection sort)</u> works very simply: it opens a loop, and in each round, selects the smallest element from the unsorted interval and places it at the end of the sorted interval.
@@ -49,7 +49,7 @@ In the code, we use $k$ to record the smallest element within the unsorted inter
[file]{selection_sort}-[class]{}-[func]{selection_sort}
```
## Algorithm characteristics
## Algorithm Characteristics
- **Time complexity of $O(n^2)$, non-adaptive sorting**: The outer loop has $n - 1$ rounds in total. The length of the unsorted interval in the first round is $n$, and the length of the unsorted interval in the last round is $2$. That is, each round of the outer loop contains $n$, $n - 1$, $\dots$, $3$, $2$ inner loop iterations, summing to $\frac{(n - 1)(n + 2)}{2}$.
- **Space complexity of $O(1)$, in-place sorting**: Pointers $i$ and $j$ use a constant amount of extra space.

View File

@@ -1,4 +1,4 @@
# Sorting algorithm
# Sorting Algorithm
<u>Sorting algorithm (sorting algorithm)</u> is used to arrange a group of data in a specific order. Sorting algorithms have extensive applications because ordered data can usually be searched, analyzed, and processed more efficiently.
@@ -6,7 +6,7 @@ As shown in the figure below, data types in sorting algorithms can be integers,
![Data type and criterion examples](sorting_algorithm.assets/sorting_examples.png)
## Evaluation dimensions
## Evaluation Dimensions
**Execution efficiency**: We expect the time complexity of sorting algorithms to be as low as possible, with a smaller total number of operations (reducing the constant factor in time complexity). For large data volumes, execution efficiency is particularly important.
@@ -17,7 +17,7 @@ As shown in the figure below, data types in sorting algorithms can be integers,
Stable sorting is a necessary condition for multi-level sorting scenarios. Suppose we have a table storing student information, where column 1 and column 2 are name and age, respectively. In this case, <u>unstable sorting</u> may cause the ordered nature of the input data to be lost:
```shell
# Input data is sorted by name
# Input Data Is Sorted by Name
# (name, age)
('A', 19)
('B', 18)
@@ -25,9 +25,9 @@ Stable sorting is a necessary condition for multi-level sorting scenarios. Suppo
('D', 19)
('E', 23)
# Assuming we use an unstable sorting algorithm to sort the list by age,
# in the result, the relative positions of ('D', 19) and ('A', 19) are changed,
# and the property that the input data is sorted by name is lost
# Assuming We Use an Unstable Sorting Algorithm to Sort the List by Age,
# In the Result, the Relative Positions of ('D', 19) and ('A', 19) Are Changed,
# And the Property That the Input Data Is Sorted by Name Is Lost
('B', 18)
('D', 19)
('A', 19)
@@ -39,7 +39,7 @@ Stable sorting is a necessary condition for multi-level sorting scenarios. Suppo
**Comparison-based or not**: <u>Comparison-based sorting</u> relies on comparison operators ($<$, $=$, $>$) to determine the relative order of elements, thereby sorting the entire array, with a theoretical optimal time complexity of $O(n \log n)$. <u>Non-comparison sorting</u> does not use comparison operators and can achieve a time complexity of $O(n)$, but its versatility is relatively limited.
## Ideal sorting algorithm
## Ideal Sorting Algorithm
**Fast execution, in-place, stable, adaptive, good versatility**. Clearly, no sorting algorithm has been discovered to date that combines all of these characteristics. Therefore, when selecting a sorting algorithm, it is necessary to decide based on the specific characteristics of the data and the requirements of the problem.

View File

@@ -1,6 +1,6 @@
# Summary
### Key review
### Key Review
- Bubble sort achieves sorting by swapping adjacent elements. By adding a flag to enable early return, we can optimize the best-case time complexity of bubble sort to $O(n)$.
- Insertion sort completes sorting by inserting elements from the unsorted interval into the correct position in the sorted interval each round. Although the time complexity of insertion sort is $O(n^2)$, it is very popular in small data volume sorting tasks because it involves relatively few unit operations.