小poop头像
高级排序算法与性能对比——归并、非比较排序及总结封面图

高级排序算法与性能对比——归并、非比较排序及总结

高级排序算法与性能对比——归并、非比较排序及总结

1. 归并排序

基本思想:
归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,采用分治法。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。

核心步骤:分解 -> 合并。

代码实现:

void _MergeSort(int* a, int left, int right, int* tmp) {
    if (left >= right) return;
    int mid = (right + left) / 2;
    // [left, mid] [mid+1, right]
    _MergeSort(a, left, mid, tmp);
    _MergeSort(a, mid + 1, right, tmp);

    int begin1 = left, end1 = mid;
    int begin2 = mid + 1, end2 = right;
    int index = begin1;

    // 合并两个有序数组
    while (begin1 <= end1 && begin2 <= end2) {
        if (a[begin1] < a[begin2]) tmp[index++] = a[begin1++];
        else tmp[index++] = a[begin2++];
    }
    while (begin1 <= end1) tmp[index++] = a[begin1++];
    while (begin2 <= end2) tmp[index++] = a[begin2++];

    for (int i = left; i <= right; i++) a[i] = tmp[i];
}

void MergeSort(int* a, int n) {
    int* tmp = new int[n];
    _MergeSort(a, 0, n - 1, tmp);
    delete[] tmp;
}

特性总结:

  • 时间复杂度:(O(N \log N)),非常稳定。
  • 空间复杂度:(O(N))。
  • 稳定性:稳定。

2. 非比较排序:计数排序

基本思想:
计数排序又称为鸽巢原理,是对哈希直接定址法的变形应用。

  1. 统计相同元素出现次数。
  2. 根据统计的结果将序列回收到原来的序列中。

优化技巧:如果数据范围较大但集中(如100-109),可以按范围开空间,使用 a[i] - min 作为索引。

代码实现:

void CountSort(int* a, int n) {
    int min = a[0], max = a[0];
    for (int i = 1; i < n; i++) {
        if (a[i] > max) max = a[i];
        if (a[i] < min) min = a[i];
    }
    int range = max - min + 1;
    int* count = (int*)malloc(sizeof(int) * range);
    memset(count, 0, sizeof(int) * range);

    // 统计次数
    for (int i = 0; i < n; i++) count[a[i] - min]++;

    // 排序
    int j = 0;
    for (int i = 0; i < range; i++) {
        while (count[i]--) a[j++] = i + min;
    }
    free(count);
}

特性总结:

  • 时间复杂度:(O(N + range))。
  • 空间复杂度:(O(range))。
  • 稳定性:稳定。
  • 适用场景:数据范围集中时效率极高,但适用范围有限。

3. 排序算法复杂度及稳定性分析

3.1 稳定性定义

假定在待排序的记录序列中,存在多个具有相同关键字的记录。若经过排序,这些记录的相对次序保持不变,则称这种排序算法是稳定的;否则称为不稳定。

3.2 综合对比表

排序方法平均情况最好情况最坏情况辅助空间稳定性
冒泡排序(O(n^2))(O(n))(O(n^2))(O(1))稳定
直接选择排序(O(n^2))(O(n^2))(O(n^2))(O(1))不稳定
直接插入排序(O(n^2))(O(n))(O(n^2))(O(1))稳定
希尔排序(O(n \log n) \sim O(n^2))(O(n^{1.3}))(O(n^2))(O(1))不稳定
堆排序(O(n \log n))(O(n \log n))(O(n \log 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^2))(O(\log n) \sim O(n))不稳定

3.3 稳定性验证案例

  • 直接选择排序:5 8 5 2 9(第一个5会被交换到后面,导致不稳定)。
  • 希尔排序:5 8 2 5 9(相同元素可能被分到不同组,导致相对位置改变)。
  • 堆排序:2 2 2 2(建堆和调整过程中可能改变相同元素的相对顺序)。
  • 快速排序:5 3 3 4 3 8 9 10 11(基准值交换可能导致相同元素顺序改变)。

4. 总结

在实际开发中:

  • 若追求平均性能,首选快速排序。
  • 若要求稳定性,首选归并排序。
  • 若数据基本有序,插入排序效率极高。
  • 若数据范围集中,计数排序是最优解。
  • 若考虑空间受限,堆排序是很好的选择。

转载自 CSDN-专业IT技术社区

原文链接:https://blog.csdn.net/lyy070501/article/details/168143197

文章来源转载

评论

评论列表

微信小程序
QQ小程序

关于作者

点赞数:0
关注数:0
粉丝:0
文章:0
关注标签:0
加入于:--