正序数?还是逆序数。洛谷P1428
发布日期:2021-05-16 17:25:08 浏览次数:15 分类:精选文章

本文共 1771 字,大约阅读时间需要 5 分钟。

归并排序的实现和优化

以下是针对归并排序求逆序数的C语言实现代码,代码经过优化,并保留了关键的注释信息。

代码主要包含以下几个部分:

  • 数据结构和全局变量声明
  • 归并操作函数merge()
  • 归并排序主函数mergesort()
  • 主函数main()
  • 代码介绍如下:

    #include 
    #include
    #include
    using namespace std;
    #define maxn 1000005
    struct node {
    int value;
    int mark;
    };
    long long sum;
    int ans[maxn];
    void merge(int l, int r, int m) {
    node temp[maxn];
    int i = l, j = m + 1, k = l;
    while (i <= m && j <= r) {
    if (a[i].value >= a[j].value) {
    temp[k++] = a[i++];
    } else {
    ans[a[j].mark] += m - i + 1;
    temp[k++] = a[j++];
    }
    }
    while (i <= m) {
    temp[k++] = a[i++];
    }
    while (j <= r) {
    temp[k++] = a[j++];
    }
    for (i = l; i <= r; ++i) {
    a[i] = temp[i];
    }
    }
    void mergesort(int l, int r) {
    if (l < r) {
    int m = (l + r) / 2;
    mergesort(l, m);
    mergesort(m + 1, r);
    merge(l, r, m);
    }
    }
    int main() {
    sum = 0;
    int n;
    scanf','%d%', &n;
    a[1].mark = 1;
    for (int i = 2; i <= n; ++i) {
    a[i].mark = i;
    scanf('%d%', &a[i].value);
    }
    mergesort(1, n);
    for (int i = 1; i <= n-1; ++i) {
    sum += ans[i];
    }
    cout << sum;
    return 0;
    }

    代码要点分析:

  • 归并排序适合求逆序数
  • 使用归并排序的思路是将两个有序数组合并成一个有序数组,并统计逆序数
  • 由于Python的递归深度限制,这里采用的是C语言实现
  • merge函数是关键,负责向前置数组的缓冲区中(temp)迁移数据
  • 在合并时,如果当前元素的值大于等于右边的等价元素,则直接加入前置数组
  • 否则,因为是逆序数统计需要明确记录逆序排列的具体数目
  • 合并实现时,使用前置数组temp并正确迁移index
  • 最后累加前置数组中各逆序数以得到结论
  • 该实现是编程实现逆序数的一种经典方法,基本思路没问题,但有待于以下优化建议:

  • 优化1:可以通过减少减速区大小来提高效率。归并与排序的时间复杂度是O(n log n),但reluctant递归深度是考虑的关键点
  • 优化2:注意内存管理和数据类型选择是否合适,避免因为数据大小导致使用问题
  • 优化3:return 0 可以保留或者根据需要保留错误处理信息
  • 优化4:每次都可以考虑加上更多的数组检查,是否有数组越界等问题
  • 优化5:合理控制标记的使用,确保"mark"的值正确唯一对应各个元素
  • 该实现思路清晰,可直接参考和使用。希望以上内容能为您提供帮助!

    上一篇:全排列
    下一篇:逆序数

    发表评论

    最新留言

    第一次来,支持一个
    [***.219.124.196]2025年04月23日 17时21分45秒