mirror of
https://github.com/krahets/hello-algo.git
synced 2025-07-24 10:14:44 +08:00
build
This commit is contained in:
@ -4,7 +4,7 @@ comments: true
|
||||
|
||||
# 11.3 冒泡排序
|
||||
|
||||
「冒泡排序 bubble sort」通过连续地比较与交换相邻元素实现排序。这个过程就像气泡从底部升到顶部一样,因此得名冒泡排序。
|
||||
<u>冒泡排序(bubble sort)</u>通过连续地比较与交换相邻元素实现排序。这个过程就像气泡从底部升到顶部一样,因此得名冒泡排序。
|
||||
|
||||
如图 11-4 所示,冒泡过程可以利用元素交换操作来模拟:从数组最左端开始向右遍历,依次比较相邻元素大小,如果“左元素 > 右元素”就交换二者。遍历完成后,最大的元素会被移动到数组的最右端。
|
||||
|
||||
|
@ -6,7 +6,7 @@ comments: true
|
||||
|
||||
前述几种排序算法都属于“基于比较的排序算法”,它们通过比较元素间的大小来实现排序。此类排序算法的时间复杂度无法超越 $O(n \log n)$ 。接下来,我们将探讨几种“非比较排序算法”,它们的时间复杂度可以达到线性阶。
|
||||
|
||||
「桶排序 bucket sort」是分治策略的一个典型应用。它通过设置一些具有大小顺序的桶,每个桶对应一个数据范围,将数据平均分配到各个桶中;然后,在每个桶内部分别执行排序;最终按照桶的顺序将所有数据合并。
|
||||
<u>桶排序(bucket sort)</u>是分治策略的一个典型应用。它通过设置一些具有大小顺序的桶,每个桶对应一个数据范围,将数据平均分配到各个桶中;然后,在每个桶内部分别执行排序;最终按照桶的顺序将所有数据合并。
|
||||
|
||||
## 11.8.1 算法流程
|
||||
|
||||
|
@ -4,7 +4,7 @@ comments: true
|
||||
|
||||
# 11.9 计数排序
|
||||
|
||||
「计数排序 counting sort」通过统计元素数量来实现排序,通常应用于整数数组。
|
||||
<u>计数排序(counting sort)</u>通过统计元素数量来实现排序,通常应用于整数数组。
|
||||
|
||||
## 11.9.1 简单实现
|
||||
|
||||
|
@ -8,7 +8,7 @@ comments: true
|
||||
|
||||
阅读本节前,请确保已学完“堆“章节。
|
||||
|
||||
「堆排序 heap sort」是一种基于堆数据结构实现的高效排序算法。我们可以利用已经学过的“建堆操作”和“元素出堆操作”实现堆排序。
|
||||
<u>堆排序(heap sort)</u>是一种基于堆数据结构实现的高效排序算法。我们可以利用已经学过的“建堆操作”和“元素出堆操作”实现堆排序。
|
||||
|
||||
1. 输入数组并建立小顶堆,此时最小元素位于堆顶。
|
||||
2. 不断执行出堆操作,依次记录出堆元素,即可得到从小到大排序的序列。
|
||||
|
@ -4,7 +4,7 @@ comments: true
|
||||
|
||||
# 11.4 插入排序
|
||||
|
||||
「插入排序 insertion sort」是一种简单的排序算法,它的工作原理与手动整理一副牌的过程非常相似。
|
||||
<u>插入排序(insertion sort)</u>是一种简单的排序算法,它的工作原理与手动整理一副牌的过程非常相似。
|
||||
|
||||
具体来说,我们在未排序区间选择一个基准元素,将该元素与其左侧已排序区间的元素逐一比较大小,并将该元素插入到正确的位置。
|
||||
|
||||
|
@ -4,7 +4,7 @@ comments: true
|
||||
|
||||
# 11.6 归并排序
|
||||
|
||||
「归并排序 merge sort」是一种基于分治策略的排序算法,包含图 11-10 所示的“划分”和“合并”阶段。
|
||||
<u>归并排序(merge sort)</u>是一种基于分治策略的排序算法,包含图 11-10 所示的“划分”和“合并”阶段。
|
||||
|
||||
1. **划分阶段**:通过递归不断地将数组从中点处分开,将长数组的排序问题转换为短数组的排序问题。
|
||||
2. **合并阶段**:当子数组长度为 1 时终止划分,开始合并,持续地将左右两个较短的有序数组合并为一个较长的有序数组,直至结束。
|
||||
|
@ -4,7 +4,7 @@ comments: true
|
||||
|
||||
# 11.5 快速排序
|
||||
|
||||
「快速排序 quick sort」是一种基于分治策略的排序算法,运行高效,应用广泛。
|
||||
<u>快速排序(quick sort)</u>是一种基于分治策略的排序算法,运行高效,应用广泛。
|
||||
|
||||
快速排序的核心操作是“哨兵划分”,其目标是:选择数组中的某个元素作为“基准数”,将所有小于基准数的元素移到其左侧,而大于基准数的元素移到其右侧。具体来说,哨兵划分的流程如图 11-8 所示。
|
||||
|
||||
|
@ -6,7 +6,7 @@ comments: true
|
||||
|
||||
上一节介绍了计数排序,它适用于数据量 $n$ 较大但数据范围 $m$ 较小的情况。假设我们需要对 $n = 10^6$ 个学号进行排序,而学号是一个 $8$ 位数字,这意味着数据范围 $m = 10^8$ 非常大,使用计数排序需要分配大量内存空间,而基数排序可以避免这种情况。
|
||||
|
||||
「基数排序 radix sort」的核心思想与计数排序一致,也通过统计个数来实现排序。在此基础上,基数排序利用数字各位之间的递进关系,依次对每一位进行排序,从而得到最终的排序结果。
|
||||
<u>基数排序(radix sort)</u>的核心思想与计数排序一致,也通过统计个数来实现排序。在此基础上,基数排序利用数字各位之间的递进关系,依次对每一位进行排序,从而得到最终的排序结果。
|
||||
|
||||
## 11.10.1 算法流程
|
||||
|
||||
|
@ -4,7 +4,7 @@ comments: true
|
||||
|
||||
# 11.2 选择排序
|
||||
|
||||
「选择排序 selection sort」的工作原理非常简单:开启一个循环,每轮从未排序区间选择最小的元素,将其放到已排序区间的末尾。
|
||||
<u>选择排序(selection sort)</u>的工作原理非常简单:开启一个循环,每轮从未排序区间选择最小的元素,将其放到已排序区间的末尾。
|
||||
|
||||
设数组的长度为 $n$ ,选择排序的算法流程如图 11-2 所示。
|
||||
|
||||
|
@ -4,7 +4,7 @@ comments: true
|
||||
|
||||
# 11.1 排序算法
|
||||
|
||||
「排序算法 sorting algorithm」用于对一组数据按照特定顺序进行排列。排序算法有着广泛的应用,因为有序数据通常能够被更高效地查找、分析和处理。
|
||||
<u>排序算法(sorting algorithm)</u>用于对一组数据按照特定顺序进行排列。排序算法有着广泛的应用,因为有序数据通常能够被更高效地查找、分析和处理。
|
||||
|
||||
如图 11-1 所示,排序算法中的数据类型可以是整数、浮点数、字符或字符串等。排序的判断规则可根据需求设定,如数字大小、字符 ASCII 码顺序或自定义规则。
|
||||
|
||||
@ -16,11 +16,11 @@ comments: true
|
||||
|
||||
**运行效率**:我们期望排序算法的时间复杂度尽量低,且总体操作数量较少(时间复杂度中的常数项变小)。对于大数据量的情况,运行效率显得尤为重要。
|
||||
|
||||
**就地性**:顾名思义,「原地排序」通过在原数组上直接操作实现排序,无须借助额外的辅助数组,从而节省内存。通常情况下,原地排序的数据搬运操作较少,运行速度也更快。
|
||||
**就地性**:顾名思义,<u>原地排序</u>通过在原数组上直接操作实现排序,无须借助额外的辅助数组,从而节省内存。通常情况下,原地排序的数据搬运操作较少,运行速度也更快。
|
||||
|
||||
**稳定性**:「稳定排序」在完成排序后,相等元素在数组中的相对顺序不发生改变。
|
||||
**稳定性**:<u>稳定排序</u>在完成排序后,相等元素在数组中的相对顺序不发生改变。
|
||||
|
||||
稳定排序是多级排序场景的必要条件。假设我们有一个存储学生信息的表格,第 1 列和第 2 列分别是姓名和年龄。在这种情况下,「非稳定排序」可能导致输入数据的有序性丧失:
|
||||
稳定排序是多级排序场景的必要条件。假设我们有一个存储学生信息的表格,第 1 列和第 2 列分别是姓名和年龄。在这种情况下,<u>非稳定排序</u>可能导致输入数据的有序性丧失:
|
||||
|
||||
```shell
|
||||
# 输入数据是按照姓名排序好的
|
||||
@ -41,11 +41,11 @@ comments: true
|
||||
('E', 23)
|
||||
```
|
||||
|
||||
**自适应性**:「自适应排序」的时间复杂度会受输入数据的影响,即最佳时间复杂度、最差时间复杂度、平均时间复杂度并不完全相等。
|
||||
**自适应性**:<u>自适应排序</u>的时间复杂度会受输入数据的影响,即最佳时间复杂度、最差时间复杂度、平均时间复杂度并不完全相等。
|
||||
|
||||
自适应性需要根据具体情况来评估。如果最差时间复杂度差于平均时间复杂度,说明排序算法在某些数据下性能可能劣化,因此被视为负面属性;而如果最佳时间复杂度优于平均时间复杂度,则被视为正面属性。
|
||||
|
||||
**是否基于比较**:「基于比较的排序」依赖比较运算符($<$、$=$、$>$)来判断元素的相对顺序,从而排序整个数组,理论最优时间复杂度为 $O(n \log n)$ 。而「非比较排序」不使用比较运算符,时间复杂度可达 $O(n)$ ,但其通用性相对较差。
|
||||
**是否基于比较**:<u>基于比较的排序</u>依赖比较运算符($<$、$=$、$>$)来判断元素的相对顺序,从而排序整个数组,理论最优时间复杂度为 $O(n \log n)$ 。而<u>非比较排序</u>不使用比较运算符,时间复杂度可达 $O(n)$ ,但其通用性相对较差。
|
||||
|
||||
## 11.1.2 理想排序算法
|
||||
|
||||
|
Reference in New Issue
Block a user