欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 科技 > IT业 > 常用的排序算法及对比

常用的排序算法及对比

2025/5/26 4:36:05 来源:https://blog.csdn.net/m0_53605808/article/details/146812300  浏览:    关键词:常用的排序算法及对比

1. 选择排序(Selection Sort)

算法思想与理论推导

  • 基本思想:
    每次从待排序数组中选择最小(或最大)的元素,将它与当前序列的起始位置交换,逐步将整个数组排序。

  • 推导过程:
    设数组长度为 n,第一次遍历需要扫描 n 个元素找到最小值,第二次扫描 (n-1) 个元素……直到最后一个元素。
    总的比较次数约为:

    (n-1) + (n-2) + \cdots + 1 = \frac{n(n-1)}{2} = O(n^2)

算法步骤

  1. 对于下标 i 从 0 到 n-2

    • 在区间 [i, n-1] 内找到最小元素的下标 min_index

    • min_indexi,则交换元素 arr[i] 与 arr[min_index]。

时间复杂度分析

  • 最坏情况: O(n²)

  • 平均情况: O(n²)

  • 空间复杂度: O(1)(原地排序)

  • 稳定性: 不稳定(因为交换可能改变相同元素的相对顺序)


2. 插入排序(Insertion Sort)

算法思想与理论推导

  • 基本思想:
    将数组分为已排序和未排序两部分,每次取未排序部分的第一个元素,在已排序部分中找到合适的位置插入,使已排序部分始终保持有序。

  • 推导过程:
    对于每个元素,最坏情况下需要和前面所有元素比较并移动位置。第 i 个元素可能需要 i 次比较和移动,总的操作次数约为:

    1 + 2 + \cdots + (n-1) = \frac{n(n-1)}{2} = O(n^2)

    当数组已经接近有序时,比较次数大大减少,时间复杂度可以达到 O(n)。

算法步骤

  1. 从数组第二个元素开始(下标 1):

    • 记当前元素为 key,从已排序部分从后向前比较,若遇到比 key 大的元素则后移。

    • 插入 key 到合适的位置。

时间复杂度分析

  • 最坏情况: O(n²)(例如数组逆序排列)

  • 平均情况: O(n²)

  • 最好情况: O(n)(例如数组已经有序)

  • 空间复杂度: O(1)

  • 稳定性: 稳定


3. 冒泡排序(Bubble Sort)

算法思想与理论推导

  • 基本思想:
    通过多次遍历数组,每次比较相邻元素,如果顺序错误则交换,将较大(或较小)的元素逐步“冒泡”到数组的一端。

  • 推导过程:
    每次遍历最多做 n-1 次比较,整个排序需要进行 n-1 次遍历,所以总的比较次数约为:

    (n-1) \times (n-1) = O(n^2)

算法步骤

  1. 重复遍历整个数组,

    • 对于每一对相邻元素,如果前者大于后者则交换。

    • 每遍历完一次后,最大的元素“浮”到数组末尾。

  2. 如果一整趟遍历没有发生交换,则排序结束。

时间复杂度分析

  • 最坏情况: O(n²)

  • 平均情况: O(n²)

  • 最好情况: 若增加标志位检测无交换情况,则最好情况为 O(n)(已经有序)

  • 空间复杂度: O(1)

  • 稳定性: 稳定


4. 归并排序(Merge Sort)

算法思想与理论推导

  • 基本思想:
    利用分治法,将数组递归地分解为两个子序列,分别排序后再将两个有序子序列合并成一个整体有序序列。

  • 推导过程:
    设 T(n) 为排序 n 个元素的时间复杂度,则:

    T(n) = 2T\left(\frac{n}{2}\right) + O(n)

    根据主定理,解得 T(n) = O(n log n)。

算法步骤

  1. 分解阶段:

    • 将数组分为两半。

    • 递归地对两半分别进行归并排序。

  2. 合并阶段:

    • 合并两个有序子数组。

时间复杂度分析

  • 最坏情况: O(n log n)

  • 平均情况: O(n log n)

  • 最好情况: O(n log n)

  • 空间复杂度: O(n)(需要额外的辅助空间用于合并)

  • 稳定性: 稳定


5. 自然合并排序(Natural Merge Sort)

算法思想与理论推导

  • 基本思想:
    利用数据中已存在的自然有序(“天然有序”的子序列或“段”),先将序列分割成若干个自然有序的段,再逐步将这些段两两归并。

  • 推导过程:
    如果输入数据已经部分有序,则自然有序的段较长,合并次数减少,最佳情况时间复杂度可接近 O(n)。
    最坏情况仍然为归并排序的情况,即当数据完全无序时,各自然段长度为 1,总共需要 O(log n) 次归并,每次归并时间 O(n),故为 O(n log n)。

算法步骤

  1. 识别自然段:

    • 扫描数组,识别连续递增(或递减)的一段作为一个“自然段”。

  2. 归并阶段:

    • 将相邻的自然段两两合并,形成新的较长的自然段。

    • 重复归并过程直到整个数组有序。

时间复杂度分析

  • 最坏情况: O(n log n)

  • 平均情况: O(n log n)

  • 最好情况: 如果数组整体有序,识别出一个自然段,时间复杂度 O(n)

  • 空间复杂度: O(n)(归并时需要辅助数组)

  • 稳定性: 稳定


6. 快速排序(Quick Sort)

算法思想与理论推导

  • 基本思想:
    利用分治策略选择一个“基准”(这里取第一个元素),将数组分成两部分:左边所有元素均小于基准,右边所有元素均大于基准,然后对这两部分递归进行排序。

  • 推导过程:
    设 T(n) 为排序 n 个元素的时间复杂度,则:

    T(n) = T(k) + T(n-k-1) + O(n)

    其中 k 表示划分后左侧子数组的大小。

    • 平均情况: 当每次划分较为均匀(大致各半),有 T(n) = 2T(n/2) + O(n),解得 T(n) = O(n log n)

    • 最坏情况: 当划分极不均匀(如数组已排序,且始终选择最小或最大元素作为基准),有 T(n) = T(n-1) + O(n),解得 T(n) = O(n²)。

算法步骤

  1. 选择基准:

    • 选择第一个元素作为基准。

  2. 分区操作:

    • 从数组两端向中间扫描,将比基准小的元素移到左边,比基准大的元素移到右边。

  3. 递归排序:

    • 对左右两个子数组分别进行快速排序。

时间复杂度分析

  • 最坏情况: O(n²)(例如每次划分极不均匀)

  • 平均情况: O(n log n)

  • 最好情况: O(n log n)

  • 空间复杂度: O(log n)(递归调用栈空间,平均情况下)

  • 稳定性: 不稳定


算法对比

算法时间复杂度(最坏/平均/最好)空间复杂度稳定性特点与适用场景
选择排序O(n²) / O(n²) / O(n²)O(1)不稳定实现简单,但比较次数固定,不适合大规模数据排序
插入排序O(n²) / O(n²) / O(n)O(1)稳定对部分有序数据效果好,适用于小规模数据或在线排序
冒泡排序O(n²) / O(n²) / O(n)(优化版)O(1)稳定实现简单,但效率低,更多用于教学演示
归并排序O(n log n) / O(n log n) / O(n log n)O(n)稳定时间复杂度稳定,适用于大规模数据,但需要额外空间
自然合并排序O(n log n) / O(n log n) / O(n)O(n)稳定能利用已有有序序列提升效率,适合部分有序数据
快速排序O(n²) / O(n log n) / O(n log n)O(log n)(平均)不稳定平均性能优异,原地排序,适合大规模数据,但最坏情况需注意

总结

  • 简单排序(选择、插入、冒泡):
    这些算法实现简单,但时间复杂度均为 O(n²)(在最坏或平均情况下),适合数据量较小的情况。插入排序在数据部分有序时表现较好,而冒泡排序常用作教学示例。

  • 分治排序(归并、快速、自然合并):
    归并排序和快速排序均有 O(n log n) 的平均时间复杂度,其中归并排序稳定但需要额外空间,而快速排序在原地排序方面有优势。自然合并排序则利用了数据中已有的有序性,在实际应用中对于部分有序数据可获得较好性能。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词