This commit is contained in:
krahets
2023-11-09 05:13:48 +08:00
parent 9701430089
commit 0105644232
83 changed files with 516 additions and 509 deletions

View File

@@ -9,25 +9,25 @@ comments: true
如图 11-4 所示,冒泡过程可以利用元素交换操作来模拟:从数组最左端开始向右遍历,依次比较相邻元素大小,如果“左元素 > 右元素”就交换它俩。遍历完成后,最大的元素会被移动到数组的最右端。
=== "<1>"
![利用元素交换操作模拟冒泡](bubble_sort.assets/bubble_operation_step1.png)
![利用元素交换操作模拟冒泡](bubble_sort.assets/bubble_operation_step1.png){ class="animation-figure" }
=== "<2>"
![bubble_operation_step2](bubble_sort.assets/bubble_operation_step2.png)
![bubble_operation_step2](bubble_sort.assets/bubble_operation_step2.png){ class="animation-figure" }
=== "<3>"
![bubble_operation_step3](bubble_sort.assets/bubble_operation_step3.png)
![bubble_operation_step3](bubble_sort.assets/bubble_operation_step3.png){ class="animation-figure" }
=== "<4>"
![bubble_operation_step4](bubble_sort.assets/bubble_operation_step4.png)
![bubble_operation_step4](bubble_sort.assets/bubble_operation_step4.png){ class="animation-figure" }
=== "<5>"
![bubble_operation_step5](bubble_sort.assets/bubble_operation_step5.png)
![bubble_operation_step5](bubble_sort.assets/bubble_operation_step5.png){ class="animation-figure" }
=== "<6>"
![bubble_operation_step6](bubble_sort.assets/bubble_operation_step6.png)
![bubble_operation_step6](bubble_sort.assets/bubble_operation_step6.png){ class="animation-figure" }
=== "<7>"
![bubble_operation_step7](bubble_sort.assets/bubble_operation_step7.png)
![bubble_operation_step7](bubble_sort.assets/bubble_operation_step7.png){ class="animation-figure" }
<p align="center"> 图 11-4 &nbsp; 利用元素交换操作模拟冒泡 </p>
@@ -40,7 +40,7 @@ comments: true
3. 以此类推,经过 $n - 1$ 轮“冒泡”后,**前 $n - 1$ 大的元素都被交换至正确位置**。
4. 仅剩的一个元素必定是最小元素,无须排序,因此数组排序完成。
![冒泡排序流程](bubble_sort.assets/bubble_sort_overview.png)
![冒泡排序流程](bubble_sort.assets/bubble_sort_overview.png){ class="animation-figure" }
<p align="center"> 图 11-5 &nbsp; 冒泡排序流程 </p>

View File

@@ -16,7 +16,7 @@ comments: true
2. 对每个桶分别执行排序(本文采用编程语言的内置排序函数)。
3. 按照桶的从小到大的顺序,合并结果。
![桶排序算法流程](bucket_sort.assets/bucket_sort_overview.png)
![桶排序算法流程](bucket_sort.assets/bucket_sort_overview.png){ class="animation-figure" }
<p align="center"> 图 11-13 &nbsp; 桶排序算法流程 </p>
@@ -409,7 +409,7 @@ comments: true
如图 11-14 所示,这种方法本质上是创建一个递归树,目标是让叶节点的值尽可能平均。当然,不一定要每轮将数据划分为 3 个桶,具体划分方式可根据数据特点灵活选择。
![递归划分桶](bucket_sort.assets/scatter_in_buckets_recursively.png)
![递归划分桶](bucket_sort.assets/scatter_in_buckets_recursively.png){ class="animation-figure" }
<p align="center"> 图 11-14 &nbsp; 递归划分桶 </p>
@@ -417,6 +417,6 @@ comments: true
如图 11-15 所示,我们假设商品价格服从正态分布,这样就可以合理地设定价格区间,从而将商品平均分配到各个桶中。
![根据概率分布划分桶](bucket_sort.assets/scatter_in_buckets_distribution.png)
![根据概率分布划分桶](bucket_sort.assets/scatter_in_buckets_distribution.png){ class="animation-figure" }
<p align="center"> 图 11-15 &nbsp; 根据概率分布划分桶 </p>

View File

@@ -14,7 +14,7 @@ comments: true
2. **借助 `counter` 统计 `nums` 中各数字的出现次数**,其中 `counter[num]` 对应数字 `num` 的出现次数。统计方法很简单,只需遍历 `nums`(设当前数字为 `num`),每轮将 `counter[num]` 增加 $1$ 即可。
3. **由于 `counter` 的各个索引天然有序,因此相当于所有数字已经被排序好了**。接下来,我们遍历 `counter` ,根据各数字的出现次数,将它们按从小到大的顺序填入 `nums` 即可。
![计数排序流程](counting_sort.assets/counting_sort_overview.png)
![计数排序流程](counting_sort.assets/counting_sort_overview.png){ class="animation-figure" }
<p align="center"> 图 11-16 &nbsp; 计数排序流程 </p>
@@ -339,28 +339,28 @@ $$
遍历完成后,数组 `res` 中就是排序好的结果,最后使用 `res` 覆盖原数组 `nums` 即可。图 11-17 展示了完整的计数排序流程。
=== "<1>"
![计数排序步骤](counting_sort.assets/counting_sort_step1.png)
![计数排序步骤](counting_sort.assets/counting_sort_step1.png){ class="animation-figure" }
=== "<2>"
![counting_sort_step2](counting_sort.assets/counting_sort_step2.png)
![counting_sort_step2](counting_sort.assets/counting_sort_step2.png){ class="animation-figure" }
=== "<3>"
![counting_sort_step3](counting_sort.assets/counting_sort_step3.png)
![counting_sort_step3](counting_sort.assets/counting_sort_step3.png){ class="animation-figure" }
=== "<4>"
![counting_sort_step4](counting_sort.assets/counting_sort_step4.png)
![counting_sort_step4](counting_sort.assets/counting_sort_step4.png){ class="animation-figure" }
=== "<5>"
![counting_sort_step5](counting_sort.assets/counting_sort_step5.png)
![counting_sort_step5](counting_sort.assets/counting_sort_step5.png){ class="animation-figure" }
=== "<6>"
![counting_sort_step6](counting_sort.assets/counting_sort_step6.png)
![counting_sort_step6](counting_sort.assets/counting_sort_step6.png){ class="animation-figure" }
=== "<7>"
![counting_sort_step7](counting_sort.assets/counting_sort_step7.png)
![counting_sort_step7](counting_sort.assets/counting_sort_step7.png){ class="animation-figure" }
=== "<8>"
![counting_sort_step8](counting_sort.assets/counting_sort_step8.png)
![counting_sort_step8](counting_sort.assets/counting_sort_step8.png){ class="animation-figure" }
<p align="center"> 图 11-17 &nbsp; 计数排序步骤 </p>

View File

@@ -29,40 +29,40 @@ comments: true
实际上,元素出堆操作中也包含第 `2.``3.` 步,只是多了一个弹出元素的步骤。
=== "<1>"
![堆排序步骤](heap_sort.assets/heap_sort_step1.png)
![堆排序步骤](heap_sort.assets/heap_sort_step1.png){ class="animation-figure" }
=== "<2>"
![heap_sort_step2](heap_sort.assets/heap_sort_step2.png)
![heap_sort_step2](heap_sort.assets/heap_sort_step2.png){ class="animation-figure" }
=== "<3>"
![heap_sort_step3](heap_sort.assets/heap_sort_step3.png)
![heap_sort_step3](heap_sort.assets/heap_sort_step3.png){ class="animation-figure" }
=== "<4>"
![heap_sort_step4](heap_sort.assets/heap_sort_step4.png)
![heap_sort_step4](heap_sort.assets/heap_sort_step4.png){ class="animation-figure" }
=== "<5>"
![heap_sort_step5](heap_sort.assets/heap_sort_step5.png)
![heap_sort_step5](heap_sort.assets/heap_sort_step5.png){ class="animation-figure" }
=== "<6>"
![heap_sort_step6](heap_sort.assets/heap_sort_step6.png)
![heap_sort_step6](heap_sort.assets/heap_sort_step6.png){ class="animation-figure" }
=== "<7>"
![heap_sort_step7](heap_sort.assets/heap_sort_step7.png)
![heap_sort_step7](heap_sort.assets/heap_sort_step7.png){ class="animation-figure" }
=== "<8>"
![heap_sort_step8](heap_sort.assets/heap_sort_step8.png)
![heap_sort_step8](heap_sort.assets/heap_sort_step8.png){ class="animation-figure" }
=== "<9>"
![heap_sort_step9](heap_sort.assets/heap_sort_step9.png)
![heap_sort_step9](heap_sort.assets/heap_sort_step9.png){ class="animation-figure" }
=== "<10>"
![heap_sort_step10](heap_sort.assets/heap_sort_step10.png)
![heap_sort_step10](heap_sort.assets/heap_sort_step10.png){ class="animation-figure" }
=== "<11>"
![heap_sort_step11](heap_sort.assets/heap_sort_step11.png)
![heap_sort_step11](heap_sort.assets/heap_sort_step11.png){ class="animation-figure" }
=== "<12>"
![heap_sort_step12](heap_sort.assets/heap_sort_step12.png)
![heap_sort_step12](heap_sort.assets/heap_sort_step12.png){ class="animation-figure" }
<p align="center"> 图 11-12 &nbsp; 堆排序步骤 </p>

View File

@@ -7,7 +7,7 @@ icon: material/sort-ascending
<div class="center-table" markdown>
![排序](../assets/covers/chapter_sorting.jpg){ width="600" }
![排序](../assets/covers/chapter_sorting.jpg){ class="cover-image" }
</div>

View File

@@ -10,7 +10,7 @@ comments: true
图 11-6 展示了数组插入元素的操作流程。设基准元素为 `base` ,我们需要将从目标索引到 `base` 之间的所有元素向右移动一位,然后再将 `base` 赋值给目标索引。
![单次插入操作](insertion_sort.assets/insertion_operation.png)
![单次插入操作](insertion_sort.assets/insertion_operation.png){ class="animation-figure" }
<p align="center"> 图 11-6 &nbsp; 单次插入操作 </p>
@@ -23,7 +23,7 @@ comments: true
3. 选取第 3 个元素作为 `base` ,将其插入到正确位置后,**数组的前 3 个元素已排序**。
4. 以此类推,在最后一轮中,选取最后一个元素作为 `base` ,将其插入到正确位置后,**所有元素均已排序**。
![插入排序流程](insertion_sort.assets/insertion_sort_overview.png)
![插入排序流程](insertion_sort.assets/insertion_sort_overview.png){ class="animation-figure" }
<p align="center"> 图 11-7 &nbsp; 插入排序流程 </p>

View File

@@ -9,7 +9,7 @@ comments: true
1. **划分阶段**:通过递归不断地将数组从中点处分开,将长数组的排序问题转换为短数组的排序问题。
2. **合并阶段**:当子数组长度为 1 时终止划分,开始合并,持续地将左右两个较短的有序数组合并为一个较长的有序数组,直至结束。
![归并排序的划分与合并阶段](merge_sort.assets/merge_sort_overview.png)
![归并排序的划分与合并阶段](merge_sort.assets/merge_sort_overview.png){ class="animation-figure" }
<p align="center"> 图 11-10 &nbsp; 归并排序的划分与合并阶段 </p>
@@ -23,34 +23,34 @@ comments: true
“合并阶段”从底至顶地将左子数组和右子数组合并为一个有序数组。需要注意的是,从长度为 1 的子数组开始合并,合并阶段中的每个子数组都是有序的。
=== "<1>"
![归并排序步骤](merge_sort.assets/merge_sort_step1.png)
![归并排序步骤](merge_sort.assets/merge_sort_step1.png){ class="animation-figure" }
=== "<2>"
![merge_sort_step2](merge_sort.assets/merge_sort_step2.png)
![merge_sort_step2](merge_sort.assets/merge_sort_step2.png){ class="animation-figure" }
=== "<3>"
![merge_sort_step3](merge_sort.assets/merge_sort_step3.png)
![merge_sort_step3](merge_sort.assets/merge_sort_step3.png){ class="animation-figure" }
=== "<4>"
![merge_sort_step4](merge_sort.assets/merge_sort_step4.png)
![merge_sort_step4](merge_sort.assets/merge_sort_step4.png){ class="animation-figure" }
=== "<5>"
![merge_sort_step5](merge_sort.assets/merge_sort_step5.png)
![merge_sort_step5](merge_sort.assets/merge_sort_step5.png){ class="animation-figure" }
=== "<6>"
![merge_sort_step6](merge_sort.assets/merge_sort_step6.png)
![merge_sort_step6](merge_sort.assets/merge_sort_step6.png){ class="animation-figure" }
=== "<7>"
![merge_sort_step7](merge_sort.assets/merge_sort_step7.png)
![merge_sort_step7](merge_sort.assets/merge_sort_step7.png){ class="animation-figure" }
=== "<8>"
![merge_sort_step8](merge_sort.assets/merge_sort_step8.png)
![merge_sort_step8](merge_sort.assets/merge_sort_step8.png){ class="animation-figure" }
=== "<9>"
![merge_sort_step9](merge_sort.assets/merge_sort_step9.png)
![merge_sort_step9](merge_sort.assets/merge_sort_step9.png){ class="animation-figure" }
=== "<10>"
![merge_sort_step10](merge_sort.assets/merge_sort_step10.png)
![merge_sort_step10](merge_sort.assets/merge_sort_step10.png){ class="animation-figure" }
<p align="center"> 图 11-11 &nbsp; 归并排序步骤 </p>

View File

@@ -13,31 +13,31 @@ comments: true
3. 循环执行步骤 `2.` ,直到 `i``j` 相遇时停止,最后将基准数交换至两个子数组的分界线。
=== "<1>"
![哨兵划分步骤](quick_sort.assets/pivot_division_step1.png)
![哨兵划分步骤](quick_sort.assets/pivot_division_step1.png){ class="animation-figure" }
=== "<2>"
![pivot_division_step2](quick_sort.assets/pivot_division_step2.png)
![pivot_division_step2](quick_sort.assets/pivot_division_step2.png){ class="animation-figure" }
=== "<3>"
![pivot_division_step3](quick_sort.assets/pivot_division_step3.png)
![pivot_division_step3](quick_sort.assets/pivot_division_step3.png){ class="animation-figure" }
=== "<4>"
![pivot_division_step4](quick_sort.assets/pivot_division_step4.png)
![pivot_division_step4](quick_sort.assets/pivot_division_step4.png){ class="animation-figure" }
=== "<5>"
![pivot_division_step5](quick_sort.assets/pivot_division_step5.png)
![pivot_division_step5](quick_sort.assets/pivot_division_step5.png){ class="animation-figure" }
=== "<6>"
![pivot_division_step6](quick_sort.assets/pivot_division_step6.png)
![pivot_division_step6](quick_sort.assets/pivot_division_step6.png){ class="animation-figure" }
=== "<7>"
![pivot_division_step7](quick_sort.assets/pivot_division_step7.png)
![pivot_division_step7](quick_sort.assets/pivot_division_step7.png){ class="animation-figure" }
=== "<8>"
![pivot_division_step8](quick_sort.assets/pivot_division_step8.png)
![pivot_division_step8](quick_sort.assets/pivot_division_step8.png){ class="animation-figure" }
=== "<9>"
![pivot_division_step9](quick_sort.assets/pivot_division_step9.png)
![pivot_division_step9](quick_sort.assets/pivot_division_step9.png){ class="animation-figure" }
<p align="center"> 图 11-8 &nbsp; 哨兵划分步骤 </p>
@@ -366,7 +366,7 @@ comments: true
2. 然后,对左子数组和右子数组分别递归执行“哨兵划分”。
3. 持续递归,直至子数组长度为 1 时终止,从而完成整个数组的排序。
![快速排序流程](quick_sort.assets/quick_sort_overview.png)
![快速排序流程](quick_sort.assets/quick_sort_overview.png){ class="animation-figure" }
<p align="center"> 图 11-9 &nbsp; 快速排序流程 </p>

View File

@@ -16,7 +16,7 @@ comments: true
2. 对学号的第 $k$ 位执行“计数排序”。完成后,数据会根据第 $k$ 位从小到大排序。
3. 将 $k$ 增加 $1$ ,然后返回步骤 `2.` 继续迭代,直到所有位都排序完成后结束。
![基数排序算法流程](radix_sort.assets/radix_sort_overview.png)
![基数排序算法流程](radix_sort.assets/radix_sort_overview.png){ class="animation-figure" }
<p align="center"> 图 11-18 &nbsp; 基数排序算法流程 </p>

View File

@@ -15,37 +15,37 @@ comments: true
5. 仅剩的一个元素必定是最大元素,无须排序,因此数组排序完成。
=== "<1>"
![选择排序步骤](selection_sort.assets/selection_sort_step1.png)
![选择排序步骤](selection_sort.assets/selection_sort_step1.png){ class="animation-figure" }
=== "<2>"
![selection_sort_step2](selection_sort.assets/selection_sort_step2.png)
![selection_sort_step2](selection_sort.assets/selection_sort_step2.png){ class="animation-figure" }
=== "<3>"
![selection_sort_step3](selection_sort.assets/selection_sort_step3.png)
![selection_sort_step3](selection_sort.assets/selection_sort_step3.png){ class="animation-figure" }
=== "<4>"
![selection_sort_step4](selection_sort.assets/selection_sort_step4.png)
![selection_sort_step4](selection_sort.assets/selection_sort_step4.png){ class="animation-figure" }
=== "<5>"
![selection_sort_step5](selection_sort.assets/selection_sort_step5.png)
![selection_sort_step5](selection_sort.assets/selection_sort_step5.png){ class="animation-figure" }
=== "<6>"
![selection_sort_step6](selection_sort.assets/selection_sort_step6.png)
![selection_sort_step6](selection_sort.assets/selection_sort_step6.png){ class="animation-figure" }
=== "<7>"
![selection_sort_step7](selection_sort.assets/selection_sort_step7.png)
![selection_sort_step7](selection_sort.assets/selection_sort_step7.png){ class="animation-figure" }
=== "<8>"
![selection_sort_step8](selection_sort.assets/selection_sort_step8.png)
![selection_sort_step8](selection_sort.assets/selection_sort_step8.png){ class="animation-figure" }
=== "<9>"
![selection_sort_step9](selection_sort.assets/selection_sort_step9.png)
![selection_sort_step9](selection_sort.assets/selection_sort_step9.png){ class="animation-figure" }
=== "<10>"
![selection_sort_step10](selection_sort.assets/selection_sort_step10.png)
![selection_sort_step10](selection_sort.assets/selection_sort_step10.png){ class="animation-figure" }
=== "<11>"
![selection_sort_step11](selection_sort.assets/selection_sort_step11.png)
![selection_sort_step11](selection_sort.assets/selection_sort_step11.png){ class="animation-figure" }
<p align="center"> 图 11-2 &nbsp; 选择排序步骤 </p>
@@ -290,6 +290,6 @@ comments: true
- **空间复杂度 $O(1)$、原地排序**:指针 $i$ 和 $j$ 使用常数大小的额外空间。
- **非稳定排序**:如图 11-3 所示,元素 `nums[i]` 有可能被交换至与其相等的元素的右边,导致两者相对顺序发生改变。
![选择排序非稳定示例](selection_sort.assets/selection_sort_instability.png)
![选择排序非稳定示例](selection_sort.assets/selection_sort_instability.png){ class="animation-figure" }
<p align="center"> 图 11-3 &nbsp; 选择排序非稳定示例 </p>

View File

@@ -8,7 +8,7 @@ comments: true
如图 11-1 所示,排序算法中的数据类型可以是整数、浮点数、字符或字符串等。排序的判断规则可根据需求设定,如数字大小、字符 ASCII 码顺序或自定义规则。
![数据类型和判断规则示例](sorting_algorithm.assets/sorting_examples.png)
![数据类型和判断规则示例](sorting_algorithm.assets/sorting_examples.png){ class="animation-figure" }
<p align="center"> 图 11-1 &nbsp; 数据类型和判断规则示例 </p>

View File

@@ -16,7 +16,7 @@ comments: true
- 总的来说,我们希望找到一种排序算法,具有高效率、稳定、原地以及正向自适应性等优点。然而,正如其他数据结构和算法一样,没有一种排序算法能够同时满足所有这些条件。在实际应用中,我们需要根据数据的特性来选择合适的排序算法。
- 图 11-19 对比了主流排序算法的效率、稳定性、就地性和自适应性等。
![排序算法对比](summary.assets/sorting_algorithms_comparison.png)
![排序算法对比](summary.assets/sorting_algorithms_comparison.png){ class="animation-figure" }
<p align="center"> 图 11-19 &nbsp; 排序算法对比 </p>